aboutsummaryrefslogtreecommitdiff
path: root/src/monkey/prg_control.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/monkey/prg_control.c')
-rw-r--r--src/monkey/prg_control.c454
1 files changed, 454 insertions, 0 deletions
diff --git a/src/monkey/prg_control.c b/src/monkey/prg_control.c
new file mode 100644
index 000000000..671725f94
--- /dev/null
+++ b/src/monkey/prg_control.c
@@ -0,0 +1,454 @@
1/**[txh]********************************************************************
2
3 Copyright (c) 2004 by Salvador E. Tropea.
4 Covered by the GPL license.
5
6 Module: Program control.
7 Comments:
8 GDB/MI commands for the "Program Control" section.@p
9
10@<pre>
11gdb command: Implemented?
12
13-exec-abort N.A. (*) (kill, but with non-interactive options)
14-exec-arguments Yes
15-exec-continue Yes ASYNC
16-exec-finish Yes ASYNC
17-exec-interrupt Yes ASYNC
18-exec-next Yes ASYNC
19-exec-next-instruction Yes ASYNC
20-exec-return Yes
21-exec-run Yes ASYNC
22-exec-show-arguments N.A. (show args) see gmi_stack_info_frame
23-exec-step Yes ASYNC
24-exec-step-instruction Yes ASYNC
25-exec-until Yes ASYNC
26-file-exec-and-symbols Yes
27-file-exec-file No
28-file-list-exec-sections N.A. (info file)
29-file-list-exec-source-files N.A.
30-file-list-shared-libraries N.A.
31-file-list-symbol-files N.A.
32-file-symbol-file Yes
33@</pre>
34
35(*) gmi_exec_kill implements it, but you should ensure that
36gmi_gdb_set("confirm","off") was called.@p
37
38GDB Bug workaround for -file-exec-and-symbols and -file-symbol-file: This
39is complex, but a real bug. When you set a breakpoint you never know the
40name of the file as it appears in the debug info. So you can be specifying
41an absolute file name or a relative file name. The reference point could be
42different than the one used in the debug info. To solve all the combinations
43gdb does a search trying various combinations. GDB isn't very smart so you
44must at least specify the working directory and the directory where the
45binary is located to get a good chance (+ user options to solve the rest).
46Once you did it gdb can find the file by doing transformations to the
47"canonical" filename. This search works OK for already loaded symtabs
48(symbol tables), but it have a bug when the search is done for psymtabs
49(partial symtabs). The bug is in the use of source_full_path_of (source.c).
50This function calls openp indicating try_cwd_first. It makes the search file
51if the psymtab file name have at least one dirseparator. It means that
52psymtabs for files compiled with relative paths will fail. The search for
53symtabs uses symtab_to_filename, it calls open_source_file which finally
54calls openp without try_cwd_first.@*
55To workaround this bug we must ensure gdb loads *all* the symtabs to memory.
56And here comes another problem -file-exec-and-symbols doesn't support it
57according to docs. In real life that's a wrapper for "file", but as nobody
58can say it won't change we must use the CLI command.
59
60***************************************************************************/
61
62#include <signal.h>
63#include "mi_gdb.h"
64
65/* Low level versions. */
66
67void mi_file_exec_and_symbols(mi_h *h, const char *file)
68{
69 if (mi_get_workaround(MI_PSYM_SEARCH))
70 mi_send(h,"file %s -readnow\n",file);
71 else
72 mi_send(h,"-file-exec-and-symbols %s\n",file);
73}
74
75void mi_exec_arguments(mi_h *h, const char *args)
76{
77 mi_send(h,"-exec-arguments %s\n",args);
78}
79
80void mi_exec_run(mi_h *h)
81{
82 mi_send(h,"-exec-run\n");
83}
84
85void mi_exec_continue(mi_h *h)
86{
87 mi_send(h,"-exec-continue\n");
88}
89
90void mi_target_terminal(mi_h *h, const char *tty_name)
91{
92 mi_send(h,"tty %s\n",tty_name);
93}
94
95void mi_file_symbol_file(mi_h *h, const char *file)
96{
97 if (mi_get_workaround(MI_PSYM_SEARCH))
98 mi_send(h,"symbol-file %s -readnow\n",file);
99 else
100 mi_send(h,"-file-symbol-file %s\n",file);
101}
102
103void mi_exec_finish(mi_h *h)
104{
105 mi_send(h,"-exec-finish\n");
106}
107
108void mi_exec_interrupt(mi_h *h)
109{
110 mi_send(h,"-exec-interrupt\n");
111}
112
113void mi_exec_next(mi_h *h, int count)
114{
115 if (count>1)
116 mi_send(h,"-exec-next %d\n",count);
117 else
118 mi_send(h,"-exec-next\n");
119}
120
121void mi_exec_next_instruction(mi_h *h)
122{
123 mi_send(h,"-exec-next-instruction\n");
124}
125
126void mi_exec_step(mi_h *h, int count)
127{
128 if (count>1)
129 mi_send(h,"-exec-step %d\n",count);
130 else
131 mi_send(h,"-exec-step\n");
132}
133
134void mi_exec_step_instruction(mi_h *h)
135{
136 mi_send(h,"-exec-step-instruction\n");
137}
138
139void mi_exec_until(mi_h *h, const char *file, int line)
140{
141 if (!file)
142 mi_send(h,"-exec-until\n");
143 else
144 mi_send(h,"-exec-until %s:%d\n",file,line);
145}
146
147void mi_exec_until_addr(mi_h *h, void *addr)
148{
149 mi_send(h,"-exec-until *%p\n",addr);
150}
151
152void mi_exec_return(mi_h *h)
153{
154 mi_send(h,"-exec-return\n");
155}
156
157void mi_exec_kill(mi_h *h)
158{
159 mi_send(h,"kill\n");
160}
161
162/* High level versions. */
163
164/**[txh]********************************************************************
165
166 Description:
167 Specify the executable and arguments for local debug.
168
169 Command: -file-exec-and-symbols + -exec-arguments
170 Return: !=0 OK
171
172***************************************************************************/
173
174int gmi_set_exec(mi_h *h, const char *file, const char *args)
175{
176 mi_file_exec_and_symbols(h,file);
177 if (!mi_res_simple_done(h))
178 return 0;
179 if (!args)
180 return 1;
181 mi_exec_arguments(h,args);
182 return mi_res_simple_done(h);
183}
184
185/**[txh]********************************************************************
186
187 Description:
188 Start running the executable. Remote sessions starts running.
189
190 Command: -exec-run
191 Return: !=0 OK
192
193***************************************************************************/
194
195int gmi_exec_run(mi_h *h)
196{
197 mi_exec_run(h);
198 return mi_res_simple_running(h);
199}
200
201/**[txh]********************************************************************
202
203 Description:
204 Continue the execution after a "stop".
205
206 Command: -exec-continue
207 Return: !=0 OK
208
209***************************************************************************/
210
211int gmi_exec_continue(mi_h *h)
212{
213 mi_exec_continue(h);
214 return mi_res_simple_running(h);
215}
216
217/**[txh]********************************************************************
218
219 Description:
220 Indicate which terminal will use the target program. For local sessions.
221
222 Command: tty
223 Return: !=0 OK
224 Example:
225
226***************************************************************************/
227
228int gmi_target_terminal(mi_h *h, const char *tty_name)
229{
230 mi_target_terminal(h,tty_name);
231 return mi_res_simple_done(h);
232}
233
234/**[txh]********************************************************************
235
236 Description:
237 Specify what's the local copy that have debug info. For remote sessions.
238
239 Command: -file-symbol-file
240 Return: !=0 OK
241
242***************************************************************************/
243
244int gmi_file_symbol_file(mi_h *h, const char *file)
245{
246 mi_file_symbol_file(h,file);
247 return mi_res_simple_done(h);
248}
249
250/**[txh]********************************************************************
251
252 Description:
253 Continue until function return, the return value is included in the async
254response.
255
256 Command: -exec-finish
257 Return: !=0 OK.
258
259***************************************************************************/
260
261int gmi_exec_finish(mi_h *h)
262{
263 mi_exec_finish(h);
264 return mi_res_simple_running(h);
265}
266
267/**[txh]********************************************************************
268
269 Description:
270 Stop the program using SIGINT. The corresponding command should be
271-exec-interrupt but not even gdb 6.1.1 can do it because the "async" mode
272isn't really working.
273
274 Command: -exec-interrupt [replacement]
275 Return: Always 1
276 Example:
277
278***************************************************************************/
279
280int gmi_exec_interrupt(mi_h *h)
281{
282 // **** IMPORTANT!!! **** Not even gdb 6.1.1 can do it because the "async"
283 // mode isn't really working.
284 //mi_exec_interrupt(h);
285 //return mi_res_simple_running(h);
286
287 kill(h->pid,SIGINT);
288 return 1; // How can I know?
289}
290
291/**[txh]********************************************************************
292
293 Description:
294 Next line of code.
295
296 Command: -exec-next
297 Return: !=0 OK
298
299***************************************************************************/
300
301int gmi_exec_next(mi_h *h)
302{
303 mi_exec_next(h,1);
304 return mi_res_simple_running(h);
305}
306
307/**[txh]********************************************************************
308
309 Description:
310 Skip count lines of code.
311
312 Command: -exec-next count
313 Return: !=0 OK
314
315***************************************************************************/
316
317int gmi_exec_next_cnt(mi_h *h, int count)
318{
319 mi_exec_next(h,count);
320 return mi_res_simple_running(h);
321}
322
323/**[txh]********************************************************************
324
325 Description:
326 Next line of assembler code.
327
328 Command: -exec-next-instruction
329 Return: !=0 OK
330
331***************************************************************************/
332
333int gmi_exec_next_instruction(mi_h *h)
334{
335 mi_exec_next_instruction(h);
336 return mi_res_simple_running(h);
337}
338
339/**[txh]********************************************************************
340
341 Description:
342 Next line of code. Get inside functions.
343
344 Command: -exec-step
345 Return: !=0 OK
346
347***************************************************************************/
348
349int gmi_exec_step(mi_h *h)
350{
351 mi_exec_step(h,1);
352 return mi_res_simple_running(h);
353}
354
355/**[txh]********************************************************************
356
357 Description:
358 Next count lines of code. Get inside functions.
359
360 Command: -exec-step count
361 Return: !=0 OK
362
363***************************************************************************/
364
365int gmi_exec_step_cnt(mi_h *h, int count)
366{
367 mi_exec_step(h,count);
368 return mi_res_simple_running(h);
369}
370
371/**[txh]********************************************************************
372
373 Description:
374 Next line of assembler code. Get inside calls.
375
376 Command: -exec-step-instruction
377 Return: !=0 OK
378
379***************************************************************************/
380
381int gmi_exec_step_instruction(mi_h *h)
382{
383 mi_exec_step_instruction(h);
384 return mi_res_simple_running(h);
385}
386
387/**[txh]********************************************************************
388
389 Description:
390 Execute until location is reached. If file is NULL then is until next
391line.
392
393 Command: -exec-until
394 Return: !=0 OK
395
396***************************************************************************/
397
398int gmi_exec_until(mi_h *h, const char *file, int line)
399{
400 mi_exec_until(h,file,line);
401 return mi_res_simple_running(h);
402}
403
404/**[txh]********************************************************************
405
406 Description:
407 Execute until location is reached.
408
409 Command: -exec-until (using *address)
410 Return: !=0 OK
411
412***************************************************************************/
413
414int gmi_exec_until_addr(mi_h *h, void *addr)
415{
416 mi_exec_until_addr(h,addr);
417 return mi_res_simple_running(h);
418}
419
420/**[txh]********************************************************************
421
422 Description:
423 Return to previous frame inmediatly.
424
425 Command: -exec-return
426 Return: A pointer to a new mi_frames structure indicating the current
427location. NULL on error.
428
429***************************************************************************/
430
431mi_frames *gmi_exec_return(mi_h *h)
432{
433 mi_exec_return(h);
434 return mi_res_frame(h);
435}
436
437/**[txh]********************************************************************
438
439 Description:
440 Just kill the program. That's what -exec-abort should do, but it isn't
441implemented by gdb. This implementation only works if the interactive mode
442is disabled (gmi_gdb_set("confirm","off")).
443
444 Command: -exec-abort [using kill]
445 Return: !=0 OK
446
447***************************************************************************/
448
449int gmi_exec_kill(mi_h *h)
450{
451 mi_exec_kill(h);
452 return mi_res_simple_done(h);
453}
454