OLD | NEW |
1 /* MI Interpreter Definitions and Commands for GDB, the GNU debugger. | 1 /* MI Interpreter Definitions and Commands for GDB, the GNU debugger. |
2 | 2 |
3 Copyright (C) 2002-2005, 2007-2012 Free Software Foundation, Inc. | 3 Copyright (C) 2002-2005, 2007-2012 Free Software Foundation, Inc. |
4 | 4 |
5 This file is part of GDB. | 5 This file is part of GDB. |
6 | 6 |
7 This program is free software; you can redistribute it and/or modify | 7 This program is free software; you can redistribute it and/or modify |
8 it under the terms of the GNU General Public License as published by | 8 it under the terms of the GNU General Public License as published by |
9 the Free Software Foundation; either version 3 of the License, or | 9 the Free Software Foundation; either version 3 of the License, or |
10 (at your option) any later version. | 10 (at your option) any later version. |
(...skipping 18 matching lines...) Expand all Loading... |
29 #include "mi-main.h" | 29 #include "mi-main.h" |
30 #include "mi-cmds.h" | 30 #include "mi-cmds.h" |
31 #include "mi-out.h" | 31 #include "mi-out.h" |
32 #include "mi-console.h" | 32 #include "mi-console.h" |
33 #include "mi-common.h" | 33 #include "mi-common.h" |
34 #include "observer.h" | 34 #include "observer.h" |
35 #include "gdbthread.h" | 35 #include "gdbthread.h" |
36 #include "solist.h" | 36 #include "solist.h" |
37 #include "gdb.h" | 37 #include "gdb.h" |
38 | 38 |
39 /* These are the interpreter setup, etc. functions for the MI interpreter */ | 39 /* These are the interpreter setup, etc. functions for the MI |
| 40 interpreter. */ |
| 41 |
40 static void mi_execute_command_wrapper (char *cmd); | 42 static void mi_execute_command_wrapper (char *cmd); |
| 43 static void mi_execute_command_input_handler (char *cmd); |
41 static void mi_command_loop (int mi_version); | 44 static void mi_command_loop (int mi_version); |
42 | 45 |
43 /* These are hooks that we put in place while doing interpreter_exec | 46 /* These are hooks that we put in place while doing interpreter_exec |
44 so we can report interesting things that happened "behind the mi's | 47 so we can report interesting things that happened "behind the MI's |
45 back" in this command */ | 48 back" in this command. */ |
| 49 |
46 static int mi_interp_query_hook (const char *ctlstr, va_list ap) | 50 static int mi_interp_query_hook (const char *ctlstr, va_list ap) |
47 ATTRIBUTE_PRINTF (1, 0); | 51 ATTRIBUTE_PRINTF (1, 0); |
48 | 52 |
49 static void mi3_command_loop (void); | 53 static void mi3_command_loop (void); |
50 static void mi2_command_loop (void); | 54 static void mi2_command_loop (void); |
51 static void mi1_command_loop (void); | 55 static void mi1_command_loop (void); |
52 | 56 |
53 static void mi_insert_notify_hooks (void); | 57 static void mi_insert_notify_hooks (void); |
54 static void mi_remove_notify_hooks (void); | 58 static void mi_remove_notify_hooks (void); |
55 static void mi_on_normal_stop (struct bpstats *bs, int print_frame); | 59 static void mi_on_normal_stop (struct bpstats *bs, int print_frame); |
56 | 60 |
57 static void mi_new_thread (struct thread_info *t); | 61 static void mi_new_thread (struct thread_info *t); |
(...skipping 12 matching lines...) Expand all Loading... |
70 | 74 |
71 static int report_initial_inferior (struct inferior *inf, void *closure); | 75 static int report_initial_inferior (struct inferior *inf, void *closure); |
72 | 76 |
73 static void * | 77 static void * |
74 mi_interpreter_init (struct interp *interp, int top_level) | 78 mi_interpreter_init (struct interp *interp, int top_level) |
75 { | 79 { |
76 struct mi_interp *mi = XMALLOC (struct mi_interp); | 80 struct mi_interp *mi = XMALLOC (struct mi_interp); |
77 const char *name; | 81 const char *name; |
78 int mi_version; | 82 int mi_version; |
79 | 83 |
80 /* HACK: We need to force stdout/stderr to point at the console. This avoids | 84 /* Assign the output channel created at startup to its own global, |
81 any potential side effects caused by legacy code that is still | 85 so that we can create a console channel that encapsulates and |
82 using the TUI / fputs_unfiltered_hook. So we set up output channels for | 86 prefixes all gdb_output-type bits coming from the rest of the |
83 this now, and swap them in when we are run. */ | 87 debugger. */ |
84 | 88 |
85 raw_stdout = stdio_fileopen (stdout); | 89 raw_stdout = gdb_stdout; |
86 | 90 |
87 /* Create MI channels */ | 91 /* Create MI console channels, each with a different prefix so they |
| 92 can be distinguished. */ |
88 mi->out = mi_console_file_new (raw_stdout, "~", '"'); | 93 mi->out = mi_console_file_new (raw_stdout, "~", '"'); |
89 mi->err = mi_console_file_new (raw_stdout, "&", '"'); | 94 mi->err = mi_console_file_new (raw_stdout, "&", '"'); |
90 mi->log = mi->err; | 95 mi->log = mi->err; |
91 mi->targ = mi_console_file_new (raw_stdout, "@", '"'); | 96 mi->targ = mi_console_file_new (raw_stdout, "@", '"'); |
92 mi->event_channel = mi_console_file_new (raw_stdout, "=", 0); | 97 mi->event_channel = mi_console_file_new (raw_stdout, "=", 0); |
93 | 98 |
94 name = interp_name (interp); | 99 name = interp_name (interp); |
95 /* INTERP_MI selects the most recent released version. "mi2" was | 100 /* INTERP_MI selects the most recent released version. "mi2" was |
96 released as part of GDB 6.0. */ | 101 released as part of GDB 6.0. */ |
97 if (strcmp (name, INTERP_MI) == 0) | 102 if (strcmp (name, INTERP_MI) == 0) |
(...skipping 19 matching lines...) Expand all Loading... |
117 observer_attach_inferior_removed (mi_inferior_removed); | 122 observer_attach_inferior_removed (mi_inferior_removed); |
118 observer_attach_normal_stop (mi_on_normal_stop); | 123 observer_attach_normal_stop (mi_on_normal_stop); |
119 observer_attach_target_resumed (mi_on_resume); | 124 observer_attach_target_resumed (mi_on_resume); |
120 observer_attach_solib_loaded (mi_solib_loaded); | 125 observer_attach_solib_loaded (mi_solib_loaded); |
121 observer_attach_solib_unloaded (mi_solib_unloaded); | 126 observer_attach_solib_unloaded (mi_solib_unloaded); |
122 observer_attach_about_to_proceed (mi_about_to_proceed); | 127 observer_attach_about_to_proceed (mi_about_to_proceed); |
123 observer_attach_breakpoint_created (mi_breakpoint_created); | 128 observer_attach_breakpoint_created (mi_breakpoint_created); |
124 observer_attach_breakpoint_deleted (mi_breakpoint_deleted); | 129 observer_attach_breakpoint_deleted (mi_breakpoint_deleted); |
125 observer_attach_breakpoint_modified (mi_breakpoint_modified); | 130 observer_attach_breakpoint_modified (mi_breakpoint_modified); |
126 | 131 |
127 /* The initial inferior is created before this function is called, so we | 132 /* The initial inferior is created before this function is |
128 » need to report it explicitly. Use iteration in case future version | 133 » called, so we need to report it explicitly. Use iteration in |
129 » of GDB creates more than one inferior up-front. */ | 134 » case future version of GDB creates more than one inferior |
| 135 » up-front. */ |
130 iterate_over_inferiors (report_initial_inferior, mi); | 136 iterate_over_inferiors (report_initial_inferior, mi); |
131 } | 137 } |
132 | 138 |
133 return mi; | 139 return mi; |
134 } | 140 } |
135 | 141 |
136 static int | 142 static int |
137 mi_interpreter_resume (void *data) | 143 mi_interpreter_resume (void *data) |
138 { | 144 { |
139 struct mi_interp *mi = data; | 145 struct mi_interp *mi = data; |
140 | 146 |
141 /* As per hack note in mi_interpreter_init, swap in the output channels... */ | 147 /* As per hack note in mi_interpreter_init, swap in the output |
| 148 channels... */ |
142 gdb_setup_readline (); | 149 gdb_setup_readline (); |
143 | 150 |
144 /* These overwrite some of the initialization done in | 151 /* These overwrite some of the initialization done in |
145 _intialize_event_loop. */ | 152 _intialize_event_loop. */ |
146 call_readline = gdb_readline2; | 153 call_readline = gdb_readline2; |
147 input_handler = mi_execute_command_wrapper; | 154 input_handler = mi_execute_command_input_handler; |
148 add_file_handler (input_fd, stdin_event_handler, 0); | 155 add_file_handler (input_fd, stdin_event_handler, 0); |
149 async_command_editing_p = 0; | 156 async_command_editing_p = 0; |
150 /* FIXME: This is a total hack for now. PB's use of the MI | 157 /* FIXME: This is a total hack for now. PB's use of the MI |
151 implicitly relies on a bug in the async support which allows | 158 implicitly relies on a bug in the async support which allows |
152 asynchronous commands to leak through the commmand loop. The bug | 159 asynchronous commands to leak through the commmand loop. The bug |
153 involves (but is not limited to) the fact that sync_execution was | 160 involves (but is not limited to) the fact that sync_execution was |
154 erroneously initialized to 0. Duplicate by initializing it thus | 161 erroneously initialized to 0. Duplicate by initializing it thus |
155 here... */ | 162 here... */ |
156 sync_execution = 0; | 163 sync_execution = 0; |
157 | 164 |
158 gdb_stdout = mi->out; | 165 gdb_stdout = mi->out; |
159 /* Route error and log output through the MI */ | 166 /* Route error and log output through the MI. */ |
160 gdb_stderr = mi->err; | 167 gdb_stderr = mi->err; |
161 gdb_stdlog = mi->log; | 168 gdb_stdlog = mi->log; |
162 /* Route target output through the MI. */ | 169 /* Route target output through the MI. */ |
163 gdb_stdtarg = mi->targ; | 170 gdb_stdtarg = mi->targ; |
164 /* Route target error through the MI as well. */ | 171 /* Route target error through the MI as well. */ |
165 gdb_stdtargerr = mi->targ; | 172 gdb_stdtargerr = mi->targ; |
166 | 173 |
167 /* Replace all the hooks that we know about. There really needs to | 174 /* Replace all the hooks that we know about. There really needs to |
168 be a better way of doing this... */ | 175 be a better way of doing this... */ |
169 clear_interpreter_hooks (); | 176 clear_interpreter_hooks (); |
170 | 177 |
171 deprecated_show_load_progress = mi_load_progress; | 178 deprecated_show_load_progress = mi_load_progress; |
172 | 179 |
173 /* If we're _the_ interpreter, take control. */ | 180 /* If we're _the_ interpreter, take control. */ |
174 if (current_interp_named_p (INTERP_MI1)) | 181 if (current_interp_named_p (INTERP_MI1)) |
175 deprecated_command_loop_hook = mi1_command_loop; | 182 deprecated_command_loop_hook = mi1_command_loop; |
176 else if (current_interp_named_p (INTERP_MI2)) | 183 else if (current_interp_named_p (INTERP_MI2)) |
177 deprecated_command_loop_hook = mi2_command_loop; | 184 deprecated_command_loop_hook = mi2_command_loop; |
178 else if (current_interp_named_p (INTERP_MI3)) | 185 else if (current_interp_named_p (INTERP_MI3)) |
179 deprecated_command_loop_hook = mi3_command_loop; | 186 deprecated_command_loop_hook = mi3_command_loop; |
180 else | 187 else |
181 deprecated_command_loop_hook = mi2_command_loop; | 188 deprecated_command_loop_hook = mi2_command_loop; |
182 | 189 |
183 return 1; | 190 return 1; |
184 } | 191 } |
185 | 192 |
186 static int | 193 static int |
187 mi_interpreter_suspend (void *data) | 194 mi_interpreter_suspend (void *data) |
188 { | 195 { |
189 gdb_disable_readline (); | 196 gdb_disable_readline (); |
190 return 1; | 197 return 1; |
191 } | 198 } |
192 | 199 |
193 static struct gdb_exception | 200 static struct gdb_exception |
194 mi_interpreter_exec (void *data, const char *command) | 201 mi_interpreter_exec (void *data, const char *command) |
195 { | 202 { |
196 char *tmp = alloca (strlen (command) + 1); | 203 char *tmp = alloca (strlen (command) + 1); |
197 | 204 |
198 strcpy (tmp, command); | 205 strcpy (tmp, command); |
199 mi_execute_command_wrapper (tmp); | 206 mi_execute_command_wrapper (tmp); |
200 return exception_none; | 207 return exception_none; |
201 } | 208 } |
202 | 209 |
203 /* Never display the default gdb prompt in mi case. */ | 210 /* Never display the default GDB prompt in MI case. */ |
| 211 |
204 static int | 212 static int |
205 mi_interpreter_prompt_p (void *data) | 213 mi_interpreter_prompt_p (void *data) |
206 { | 214 { |
207 return 0; | 215 return 0; |
208 } | 216 } |
209 | 217 |
210 void | 218 void |
211 mi_cmd_interpreter_exec (char *command, char **argv, int argc) | 219 mi_cmd_interpreter_exec (char *command, char **argv, int argc) |
212 { | 220 { |
213 struct interp *interp_to_use; | 221 struct interp *interp_to_use; |
214 int i; | 222 int i; |
215 char *mi_error_message = NULL; | 223 char *mi_error_message = NULL; |
216 struct cleanup *old_chain; | 224 struct cleanup *old_chain; |
217 | 225 |
218 if (argc < 2) | 226 if (argc < 2) |
219 error (_("-interpreter-exec: " | 227 error (_("-interpreter-exec: " |
220 "Usage: -interpreter-exec interp command")); | 228 "Usage: -interpreter-exec interp command")); |
221 | 229 |
222 interp_to_use = interp_lookup (argv[0]); | 230 interp_to_use = interp_lookup (argv[0]); |
223 if (interp_to_use == NULL) | 231 if (interp_to_use == NULL) |
224 error (_("-interpreter-exec: could not find interpreter \"%s\""), | 232 error (_("-interpreter-exec: could not find interpreter \"%s\""), |
225 argv[0]); | 233 argv[0]); |
226 | 234 |
227 if (!interp_exec_p (interp_to_use)) | 235 if (!interp_exec_p (interp_to_use)) |
228 error (_("-interpreter-exec: interpreter \"%s\" " | 236 error (_("-interpreter-exec: interpreter \"%s\" " |
229 "does not support command execution"), | 237 "does not support command execution"), |
230 argv[0]); | 238 argv[0]); |
231 | 239 |
232 /* Insert the MI out hooks, making sure to also call the interpreter's hooks | 240 /* Insert the MI out hooks, making sure to also call the |
233 if it has any. */ | 241 interpreter's hooks if it has any. */ |
234 /* KRS: We shouldn't need this... Events should be installed and they should | 242 /* KRS: We shouldn't need this... Events should be installed and |
235 just ALWAYS fire something out down the MI channel... */ | 243 they should just ALWAYS fire something out down the MI |
| 244 channel. */ |
236 mi_insert_notify_hooks (); | 245 mi_insert_notify_hooks (); |
237 | 246 |
238 /* Now run the code... */ | 247 /* Now run the code. */ |
239 | 248 |
240 old_chain = make_cleanup (null_cleanup, 0); | 249 old_chain = make_cleanup (null_cleanup, 0); |
241 for (i = 1; i < argc; i++) | 250 for (i = 1; i < argc; i++) |
242 { | 251 { |
243 struct gdb_exception e = interp_exec (interp_to_use, argv[i]); | 252 struct gdb_exception e = interp_exec (interp_to_use, argv[i]); |
244 | 253 |
245 if (e.reason < 0) | 254 if (e.reason < 0) |
246 { | 255 { |
247 mi_error_message = xstrdup (e.message); | 256 mi_error_message = xstrdup (e.message); |
248 make_cleanup (xfree, mi_error_message); | 257 make_cleanup (xfree, mi_error_message); |
249 break; | 258 break; |
250 } | 259 } |
251 } | 260 } |
252 | 261 |
253 mi_remove_notify_hooks (); | 262 mi_remove_notify_hooks (); |
254 | 263 |
255 if (mi_error_message != NULL) | 264 if (mi_error_message != NULL) |
256 error ("%s", mi_error_message); | 265 error ("%s", mi_error_message); |
257 do_cleanups (old_chain); | 266 do_cleanups (old_chain); |
258 } | 267 } |
259 | 268 |
260 /* | 269 /* This inserts a number of hooks that are meant to produce |
261 * mi_insert_notify_hooks - This inserts a number of hooks that are | 270 async-notify ("=") MI messages while running commands in another |
262 * meant to produce async-notify ("=") MI messages while running | 271 interpreter using mi_interpreter_exec. The canonical use for this |
263 * commands in another interpreter using mi_interpreter_exec. The | 272 is to allow access to the gdb CLI interpreter from within the MI, |
264 * canonical use for this is to allow access to the gdb CLI | 273 while still producing MI style output when actions in the CLI |
265 * interpreter from within the MI, while still producing MI style | 274 command change GDB's state. */ |
266 * output when actions in the CLI command change gdb's state. | |
267 */ | |
268 | 275 |
269 static void | 276 static void |
270 mi_insert_notify_hooks (void) | 277 mi_insert_notify_hooks (void) |
271 { | 278 { |
272 deprecated_query_hook = mi_interp_query_hook; | 279 deprecated_query_hook = mi_interp_query_hook; |
273 } | 280 } |
274 | 281 |
275 static void | 282 static void |
276 mi_remove_notify_hooks (void) | 283 mi_remove_notify_hooks (void) |
277 { | 284 { |
278 deprecated_query_hook = NULL; | 285 deprecated_query_hook = NULL; |
279 } | 286 } |
280 | 287 |
281 static int | 288 static int |
282 mi_interp_query_hook (const char *ctlstr, va_list ap) | 289 mi_interp_query_hook (const char *ctlstr, va_list ap) |
283 { | 290 { |
284 return 1; | 291 return 1; |
285 } | 292 } |
286 | 293 |
287 static void | 294 static void |
288 mi_execute_command_wrapper (char *cmd) | 295 mi_execute_command_wrapper (char *cmd) |
289 { | 296 { |
290 mi_execute_command (cmd, stdin == instream); | 297 mi_execute_command (cmd, stdin == instream); |
291 } | 298 } |
292 | 299 |
| 300 /* mi_execute_command_wrapper wrapper suitable for INPUT_HANDLER. */ |
| 301 |
| 302 static void |
| 303 mi_execute_command_input_handler (char *cmd) |
| 304 { |
| 305 mi_execute_command_wrapper (cmd); |
| 306 |
| 307 fputs_unfiltered ("(gdb) \n", raw_stdout); |
| 308 gdb_flush (raw_stdout); |
| 309 } |
| 310 |
293 static void | 311 static void |
294 mi1_command_loop (void) | 312 mi1_command_loop (void) |
295 { | 313 { |
296 mi_command_loop (1); | 314 mi_command_loop (1); |
297 } | 315 } |
298 | 316 |
299 static void | 317 static void |
300 mi2_command_loop (void) | 318 mi2_command_loop (void) |
301 { | 319 { |
302 mi_command_loop (2); | 320 mi_command_loop (2); |
303 } | 321 } |
304 | 322 |
305 static void | 323 static void |
306 mi3_command_loop (void) | 324 mi3_command_loop (void) |
307 { | 325 { |
308 mi_command_loop (3); | 326 mi_command_loop (3); |
309 } | 327 } |
310 | 328 |
311 static void | 329 static void |
312 mi_command_loop (int mi_version) | 330 mi_command_loop (int mi_version) |
313 { | 331 { |
314 /* Turn off 8 bit strings in quoted output. Any character with the | 332 /* Turn off 8 bit strings in quoted output. Any character with the |
315 high bit set is printed using C's octal format. */ | 333 high bit set is printed using C's octal format. */ |
316 sevenbit_strings = 1; | 334 sevenbit_strings = 1; |
317 /* Tell the world that we're alive */ | 335 |
| 336 /* Tell the world that we're alive. */ |
318 fputs_unfiltered ("(gdb) \n", raw_stdout); | 337 fputs_unfiltered ("(gdb) \n", raw_stdout); |
319 gdb_flush (raw_stdout); | 338 gdb_flush (raw_stdout); |
| 339 |
320 start_event_loop (); | 340 start_event_loop (); |
321 } | 341 } |
322 | 342 |
323 static void | 343 static void |
324 mi_new_thread (struct thread_info *t) | 344 mi_new_thread (struct thread_info *t) |
325 { | 345 { |
326 struct mi_interp *mi = top_level_interpreter_data (); | 346 struct mi_interp *mi = top_level_interpreter_data (); |
327 struct inferior *inf = find_inferior_pid (ptid_get_pid (t->ptid)); | 347 struct inferior *inf = find_inferior_pid (ptid_get_pid (t->ptid)); |
328 | 348 |
329 gdb_assert (inf); | 349 gdb_assert (inf); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
413 using cli interpreter, be sure to use MI uiout for output, | 433 using cli interpreter, be sure to use MI uiout for output, |
414 not the current one. */ | 434 not the current one. */ |
415 struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ()); | 435 struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ()); |
416 | 436 |
417 if (print_frame) | 437 if (print_frame) |
418 { | 438 { |
419 int core; | 439 int core; |
420 | 440 |
421 if (current_uiout != mi_uiout) | 441 if (current_uiout != mi_uiout) |
422 { | 442 { |
423 » /* The normal_stop function has printed frame information into | 443 » /* The normal_stop function has printed frame information |
424 » CLI uiout, or some other non-MI uiout. There's no way we | 444 » into CLI uiout, or some other non-MI uiout. There's no |
425 » can extract proper fields from random uiout object, so we print | 445 » way we can extract proper fields from random uiout |
426 » the frame again. In practice, this can only happen when running | 446 » object, so we print the frame again. In practice, this |
427 » a CLI command in MI. */ | 447 » can only happen when running a CLI command in MI. */ |
428 struct ui_out *saved_uiout = current_uiout; | 448 struct ui_out *saved_uiout = current_uiout; |
429 struct target_waitstatus last; | 449 struct target_waitstatus last; |
430 ptid_t last_ptid; | 450 ptid_t last_ptid; |
431 | 451 |
432 current_uiout = mi_uiout; | 452 current_uiout = mi_uiout; |
433 | 453 |
434 get_last_target_status (&last_ptid, &last); | 454 get_last_target_status (&last_ptid, &last); |
435 bpstat_print (bs, last.kind); | 455 bpstat_print (bs, last.kind); |
436 | 456 |
437 print_stack_frame (get_selected_frame (NULL), 0, SRC_AND_LOC); | 457 print_stack_frame (get_selected_frame (NULL), 0, SRC_AND_LOC); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
476 | 496 |
477 if (tp->control.in_infcall) | 497 if (tp->control.in_infcall) |
478 return; | 498 return; |
479 } | 499 } |
480 | 500 |
481 mi_proceeded = 1; | 501 mi_proceeded = 1; |
482 } | 502 } |
483 | 503 |
484 /* When non-zero, no MI notifications will be emitted in | 504 /* When non-zero, no MI notifications will be emitted in |
485 response to breakpoint change observers. */ | 505 response to breakpoint change observers. */ |
| 506 |
486 int mi_suppress_breakpoint_notifications = 0; | 507 int mi_suppress_breakpoint_notifications = 0; |
487 | 508 |
488 /* Emit notification about a created breakpoint. */ | 509 /* Emit notification about a created breakpoint. */ |
| 510 |
489 static void | 511 static void |
490 mi_breakpoint_created (struct breakpoint *b) | 512 mi_breakpoint_created (struct breakpoint *b) |
491 { | 513 { |
492 struct mi_interp *mi = top_level_interpreter_data (); | 514 struct mi_interp *mi = top_level_interpreter_data (); |
493 struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ()); | 515 struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ()); |
494 struct gdb_exception e; | 516 volatile struct gdb_exception e; |
495 | 517 |
496 if (mi_suppress_breakpoint_notifications) | 518 if (mi_suppress_breakpoint_notifications) |
497 return; | 519 return; |
498 | 520 |
499 if (b->number <= 0) | 521 if (b->number <= 0) |
500 return; | 522 return; |
501 | 523 |
502 target_terminal_ours (); | 524 target_terminal_ours (); |
503 fprintf_unfiltered (mi->event_channel, | 525 fprintf_unfiltered (mi->event_channel, |
504 "breakpoint-created"); | 526 "breakpoint-created"); |
505 /* We want the output from gdb_breakpoint_query to go to | 527 /* We want the output from gdb_breakpoint_query to go to |
506 mi->event_channel. One approach would be to just | 528 mi->event_channel. One approach would be to just call |
507 call gdb_breakpoint_query, and then use mi_out_put to | 529 gdb_breakpoint_query, and then use mi_out_put to send the current |
508 send the current content of mi_outout into mi->event_channel. | 530 content of mi_outout into mi->event_channel. However, that will |
509 However, that will break if anything is output to mi_uiout | 531 break if anything is output to mi_uiout prior to calling the |
510 prior the calling the breakpoint_created notifications. | 532 breakpoint_created notifications. So, we use |
511 So, we use ui_out_redirect. */ | 533 ui_out_redirect. */ |
512 ui_out_redirect (mi_uiout, mi->event_channel); | 534 ui_out_redirect (mi_uiout, mi->event_channel); |
513 TRY_CATCH (e, RETURN_MASK_ERROR) | 535 TRY_CATCH (e, RETURN_MASK_ERROR) |
514 gdb_breakpoint_query (mi_uiout, b->number, NULL); | 536 gdb_breakpoint_query (mi_uiout, b->number, NULL); |
515 ui_out_redirect (mi_uiout, NULL); | 537 ui_out_redirect (mi_uiout, NULL); |
516 | 538 |
517 gdb_flush (mi->event_channel); | 539 gdb_flush (mi->event_channel); |
518 } | 540 } |
519 | 541 |
520 /* Emit notification about deleted breakpoint. */ | 542 /* Emit notification about deleted breakpoint. */ |
| 543 |
521 static void | 544 static void |
522 mi_breakpoint_deleted (struct breakpoint *b) | 545 mi_breakpoint_deleted (struct breakpoint *b) |
523 { | 546 { |
524 struct mi_interp *mi = top_level_interpreter_data (); | 547 struct mi_interp *mi = top_level_interpreter_data (); |
525 | 548 |
526 if (mi_suppress_breakpoint_notifications) | 549 if (mi_suppress_breakpoint_notifications) |
527 return; | 550 return; |
528 | 551 |
529 if (b->number <= 0) | 552 if (b->number <= 0) |
530 return; | 553 return; |
531 | 554 |
532 target_terminal_ours (); | 555 target_terminal_ours (); |
533 | 556 |
534 fprintf_unfiltered (mi->event_channel, "breakpoint-deleted,id=\"%d\"", | 557 fprintf_unfiltered (mi->event_channel, "breakpoint-deleted,id=\"%d\"", |
535 b->number); | 558 b->number); |
536 | 559 |
537 gdb_flush (mi->event_channel); | 560 gdb_flush (mi->event_channel); |
538 } | 561 } |
539 | 562 |
540 /* Emit notification about modified breakpoint. */ | 563 /* Emit notification about modified breakpoint. */ |
| 564 |
541 static void | 565 static void |
542 mi_breakpoint_modified (struct breakpoint *b) | 566 mi_breakpoint_modified (struct breakpoint *b) |
543 { | 567 { |
544 struct mi_interp *mi = top_level_interpreter_data (); | 568 struct mi_interp *mi = top_level_interpreter_data (); |
545 struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ()); | 569 struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ()); |
546 struct gdb_exception e; | 570 volatile struct gdb_exception e; |
547 | 571 |
548 if (mi_suppress_breakpoint_notifications) | 572 if (mi_suppress_breakpoint_notifications) |
549 return; | 573 return; |
550 | 574 |
551 if (b->number <= 0) | 575 if (b->number <= 0) |
552 return; | 576 return; |
553 | 577 |
554 target_terminal_ours (); | 578 target_terminal_ours (); |
555 fprintf_unfiltered (mi->event_channel, | 579 fprintf_unfiltered (mi->event_channel, |
556 "breakpoint-modified"); | 580 "breakpoint-modified"); |
557 /* We want the output from gdb_breakpoint_query to go to | 581 /* We want the output from gdb_breakpoint_query to go to |
558 mi->event_channel. One approach would be to just | 582 mi->event_channel. One approach would be to just call |
559 call gdb_breakpoint_query, and then use mi_out_put to | 583 gdb_breakpoint_query, and then use mi_out_put to send the current |
560 send the current content of mi_outout into mi->event_channel. | 584 content of mi_outout into mi->event_channel. However, that will |
561 However, that will break if anything is output to mi_uiout | 585 break if anything is output to mi_uiout prior to calling the |
562 prior the calling the breakpoint_created notifications. | 586 breakpoint_created notifications. So, we use |
563 So, we use ui_out_redirect. */ | 587 ui_out_redirect. */ |
564 ui_out_redirect (mi_uiout, mi->event_channel); | 588 ui_out_redirect (mi_uiout, mi->event_channel); |
565 TRY_CATCH (e, RETURN_MASK_ERROR) | 589 TRY_CATCH (e, RETURN_MASK_ERROR) |
566 gdb_breakpoint_query (mi_uiout, b->number, NULL); | 590 gdb_breakpoint_query (mi_uiout, b->number, NULL); |
567 ui_out_redirect (mi_uiout, NULL); | 591 ui_out_redirect (mi_uiout, NULL); |
568 | 592 |
569 gdb_flush (mi->event_channel); | 593 gdb_flush (mi->event_channel); |
570 } | 594 } |
571 | 595 |
572 | |
573 static int | 596 static int |
574 mi_output_running_pid (struct thread_info *info, void *arg) | 597 mi_output_running_pid (struct thread_info *info, void *arg) |
575 { | 598 { |
576 ptid_t *ptid = arg; | 599 ptid_t *ptid = arg; |
577 | 600 |
578 if (ptid_get_pid (*ptid) == ptid_get_pid (info->ptid)) | 601 if (ptid_get_pid (*ptid) == ptid_get_pid (info->ptid)) |
579 fprintf_unfiltered (raw_stdout, | 602 fprintf_unfiltered (raw_stdout, |
580 "*running,thread-id=\"%d\"\n", | 603 "*running,thread-id=\"%d\"\n", |
581 info->num); | 604 info->num); |
582 | 605 |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
725 } | 748 } |
726 | 749 |
727 static struct ui_out * | 750 static struct ui_out * |
728 mi_ui_out (struct interp *interp) | 751 mi_ui_out (struct interp *interp) |
729 { | 752 { |
730 struct mi_interp *mi = interp_data (interp); | 753 struct mi_interp *mi = interp_data (interp); |
731 | 754 |
732 return mi->uiout; | 755 return mi->uiout; |
733 } | 756 } |
734 | 757 |
| 758 /* Save the original value of raw_stdout here when logging, so we can |
| 759 restore correctly when done. */ |
| 760 |
| 761 static struct ui_file *saved_raw_stdout; |
| 762 |
| 763 /* Do MI-specific logging actions; save raw_stdout, and change all |
| 764 the consoles to use the supplied ui-file(s). */ |
| 765 |
| 766 static int |
| 767 mi_set_logging (struct interp *interp, int start_log, |
| 768 struct ui_file *out, struct ui_file *logfile) |
| 769 { |
| 770 struct mi_interp *mi = interp_data (interp); |
| 771 |
| 772 if (!mi) |
| 773 return 0; |
| 774 |
| 775 if (start_log) |
| 776 { |
| 777 /* The tee created already is based on gdb_stdout, which for MI |
| 778 is a console and so we end up in an infinite loop of console |
| 779 writing to ui_file writing to console etc. So discard the |
| 780 existing tee (it hasn't been used yet, and MI won't ever use |
| 781 it), and create one based on raw_stdout instead. */ |
| 782 if (logfile) |
| 783 { |
| 784 ui_file_delete (out); |
| 785 out = tee_file_new (raw_stdout, 0, logfile, 0); |
| 786 } |
| 787 |
| 788 saved_raw_stdout = raw_stdout; |
| 789 raw_stdout = out; |
| 790 } |
| 791 else |
| 792 { |
| 793 raw_stdout = saved_raw_stdout; |
| 794 saved_raw_stdout = NULL; |
| 795 } |
| 796 |
| 797 mi_console_set_raw (mi->out, raw_stdout); |
| 798 mi_console_set_raw (mi->err, raw_stdout); |
| 799 mi_console_set_raw (mi->log, raw_stdout); |
| 800 mi_console_set_raw (mi->targ, raw_stdout); |
| 801 mi_console_set_raw (mi->event_channel, raw_stdout); |
| 802 |
| 803 return 1; |
| 804 } |
| 805 |
735 extern initialize_file_ftype _initialize_mi_interp; /* -Wmissing-prototypes */ | 806 extern initialize_file_ftype _initialize_mi_interp; /* -Wmissing-prototypes */ |
736 | 807 |
737 void | 808 void |
738 _initialize_mi_interp (void) | 809 _initialize_mi_interp (void) |
739 { | 810 { |
740 static const struct interp_procs procs = | 811 static const struct interp_procs procs = |
741 { | 812 { |
742 mi_interpreter_init,» /* init_proc */ | 813 mi_interpreter_init,» /* init_proc */ |
743 mi_interpreter_resume,» /* resume_proc */ | 814 mi_interpreter_resume,» /* resume_proc */ |
744 mi_interpreter_suspend,» /* suspend_proc */ | 815 mi_interpreter_suspend,» /* suspend_proc */ |
745 mi_interpreter_exec,» /* exec_proc */ | 816 mi_interpreter_exec,» /* exec_proc */ |
746 mi_interpreter_prompt_p,» /* prompt_proc_p */ | 817 mi_interpreter_prompt_p,» /* prompt_proc_p */ |
747 mi_ui_out » » » /* ui_out_proc */ | 818 mi_ui_out, » » /* ui_out_proc */ |
748 }; | 819 mi_set_logging» » /* set_logging_proc */ |
| 820 }; |
749 | 821 |
750 /* The various interpreter levels. */ | 822 /* The various interpreter levels. */ |
751 interp_add (interp_new (INTERP_MI1, &procs)); | 823 interp_add (interp_new (INTERP_MI1, &procs)); |
752 interp_add (interp_new (INTERP_MI2, &procs)); | 824 interp_add (interp_new (INTERP_MI2, &procs)); |
753 interp_add (interp_new (INTERP_MI3, &procs)); | 825 interp_add (interp_new (INTERP_MI3, &procs)); |
754 interp_add (interp_new (INTERP_MI, &procs)); | 826 interp_add (interp_new (INTERP_MI, &procs)); |
755 } | 827 } |
OLD | NEW |