GDB (API)
|
00001 /* MI Interpreter Definitions and Commands for GDB, the GNU debugger. 00002 00003 Copyright (C) 2002-2013 Free Software Foundation, Inc. 00004 00005 This file is part of GDB. 00006 00007 This program is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 3 of the License, or 00010 (at your option) any later version. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00019 00020 #include "defs.h" 00021 #include "gdb_string.h" 00022 #include "interps.h" 00023 #include "event-top.h" 00024 #include "event-loop.h" 00025 #include "inferior.h" 00026 #include "ui-out.h" 00027 #include "top.h" 00028 #include "exceptions.h" 00029 #include "mi-main.h" 00030 #include "mi-cmds.h" 00031 #include "mi-out.h" 00032 #include "mi-console.h" 00033 #include "mi-common.h" 00034 #include "observer.h" 00035 #include "gdbthread.h" 00036 #include "solist.h" 00037 #include "gdb.h" 00038 #include "objfiles.h" 00039 #include "tracepoint.h" 00040 00041 /* These are the interpreter setup, etc. functions for the MI 00042 interpreter. */ 00043 00044 static void mi_execute_command_wrapper (const char *cmd); 00045 static void mi_execute_command_input_handler (char *cmd); 00046 static void mi_command_loop (void *data); 00047 00048 /* These are hooks that we put in place while doing interpreter_exec 00049 so we can report interesting things that happened "behind the MI's 00050 back" in this command. */ 00051 00052 static int mi_interp_query_hook (const char *ctlstr, va_list ap) 00053 ATTRIBUTE_PRINTF (1, 0); 00054 00055 static void mi_insert_notify_hooks (void); 00056 static void mi_remove_notify_hooks (void); 00057 static void mi_on_normal_stop (struct bpstats *bs, int print_frame); 00058 00059 static void mi_new_thread (struct thread_info *t); 00060 static void mi_thread_exit (struct thread_info *t, int silent); 00061 static void mi_record_changed (struct inferior*, int); 00062 static void mi_inferior_added (struct inferior *inf); 00063 static void mi_inferior_appeared (struct inferior *inf); 00064 static void mi_inferior_exit (struct inferior *inf); 00065 static void mi_inferior_removed (struct inferior *inf); 00066 static void mi_on_resume (ptid_t ptid); 00067 static void mi_solib_loaded (struct so_list *solib); 00068 static void mi_solib_unloaded (struct so_list *solib); 00069 static void mi_about_to_proceed (void); 00070 static void mi_traceframe_changed (int tfnum, int tpnum); 00071 static void mi_tsv_created (const struct trace_state_variable *tsv); 00072 static void mi_tsv_deleted (const struct trace_state_variable *tsv); 00073 static void mi_tsv_modified (const struct trace_state_variable *tsv); 00074 static void mi_breakpoint_created (struct breakpoint *b); 00075 static void mi_breakpoint_deleted (struct breakpoint *b); 00076 static void mi_breakpoint_modified (struct breakpoint *b); 00077 static void mi_command_param_changed (const char *param, const char *value); 00078 static void mi_memory_changed (struct inferior *inf, CORE_ADDR memaddr, 00079 ssize_t len, const bfd_byte *myaddr); 00080 00081 static int report_initial_inferior (struct inferior *inf, void *closure); 00082 00083 static void * 00084 mi_interpreter_init (struct interp *interp, int top_level) 00085 { 00086 struct mi_interp *mi = XMALLOC (struct mi_interp); 00087 const char *name; 00088 int mi_version; 00089 00090 /* Assign the output channel created at startup to its own global, 00091 so that we can create a console channel that encapsulates and 00092 prefixes all gdb_output-type bits coming from the rest of the 00093 debugger. */ 00094 00095 raw_stdout = gdb_stdout; 00096 00097 /* Create MI console channels, each with a different prefix so they 00098 can be distinguished. */ 00099 mi->out = mi_console_file_new (raw_stdout, "~", '"'); 00100 mi->err = mi_console_file_new (raw_stdout, "&", '"'); 00101 mi->log = mi->err; 00102 mi->targ = mi_console_file_new (raw_stdout, "@", '"'); 00103 mi->event_channel = mi_console_file_new (raw_stdout, "=", 0); 00104 00105 name = interp_name (interp); 00106 /* INTERP_MI selects the most recent released version. "mi2" was 00107 released as part of GDB 6.0. */ 00108 if (strcmp (name, INTERP_MI) == 0) 00109 mi_version = 2; 00110 else if (strcmp (name, INTERP_MI1) == 0) 00111 mi_version = 1; 00112 else if (strcmp (name, INTERP_MI2) == 0) 00113 mi_version = 2; 00114 else if (strcmp (name, INTERP_MI3) == 0) 00115 mi_version = 3; 00116 else 00117 gdb_assert_not_reached ("unhandled MI version"); 00118 00119 mi->uiout = mi_out_new (mi_version); 00120 00121 if (top_level) 00122 { 00123 observer_attach_new_thread (mi_new_thread); 00124 observer_attach_thread_exit (mi_thread_exit); 00125 observer_attach_inferior_added (mi_inferior_added); 00126 observer_attach_inferior_appeared (mi_inferior_appeared); 00127 observer_attach_inferior_exit (mi_inferior_exit); 00128 observer_attach_inferior_removed (mi_inferior_removed); 00129 observer_attach_record_changed (mi_record_changed); 00130 observer_attach_normal_stop (mi_on_normal_stop); 00131 observer_attach_target_resumed (mi_on_resume); 00132 observer_attach_solib_loaded (mi_solib_loaded); 00133 observer_attach_solib_unloaded (mi_solib_unloaded); 00134 observer_attach_about_to_proceed (mi_about_to_proceed); 00135 observer_attach_traceframe_changed (mi_traceframe_changed); 00136 observer_attach_tsv_created (mi_tsv_created); 00137 observer_attach_tsv_deleted (mi_tsv_deleted); 00138 observer_attach_tsv_modified (mi_tsv_modified); 00139 observer_attach_breakpoint_created (mi_breakpoint_created); 00140 observer_attach_breakpoint_deleted (mi_breakpoint_deleted); 00141 observer_attach_breakpoint_modified (mi_breakpoint_modified); 00142 observer_attach_command_param_changed (mi_command_param_changed); 00143 observer_attach_memory_changed (mi_memory_changed); 00144 00145 /* The initial inferior is created before this function is 00146 called, so we need to report it explicitly. Use iteration in 00147 case future version of GDB creates more than one inferior 00148 up-front. */ 00149 iterate_over_inferiors (report_initial_inferior, mi); 00150 } 00151 00152 return mi; 00153 } 00154 00155 static int 00156 mi_interpreter_resume (void *data) 00157 { 00158 struct mi_interp *mi = data; 00159 00160 /* As per hack note in mi_interpreter_init, swap in the output 00161 channels... */ 00162 gdb_setup_readline (); 00163 00164 /* These overwrite some of the initialization done in 00165 _intialize_event_loop. */ 00166 call_readline = gdb_readline2; 00167 input_handler = mi_execute_command_input_handler; 00168 async_command_editing_p = 0; 00169 /* FIXME: This is a total hack for now. PB's use of the MI 00170 implicitly relies on a bug in the async support which allows 00171 asynchronous commands to leak through the commmand loop. The bug 00172 involves (but is not limited to) the fact that sync_execution was 00173 erroneously initialized to 0. Duplicate by initializing it thus 00174 here... */ 00175 sync_execution = 0; 00176 00177 gdb_stdout = mi->out; 00178 /* Route error and log output through the MI. */ 00179 gdb_stderr = mi->err; 00180 gdb_stdlog = mi->log; 00181 /* Route target output through the MI. */ 00182 gdb_stdtarg = mi->targ; 00183 /* Route target error through the MI as well. */ 00184 gdb_stdtargerr = mi->targ; 00185 00186 /* Replace all the hooks that we know about. There really needs to 00187 be a better way of doing this... */ 00188 clear_interpreter_hooks (); 00189 00190 deprecated_show_load_progress = mi_load_progress; 00191 00192 return 1; 00193 } 00194 00195 static int 00196 mi_interpreter_suspend (void *data) 00197 { 00198 gdb_disable_readline (); 00199 return 1; 00200 } 00201 00202 static struct gdb_exception 00203 mi_interpreter_exec (void *data, const char *command) 00204 { 00205 mi_execute_command_wrapper (command); 00206 return exception_none; 00207 } 00208 00209 /* Never display the default GDB prompt in MI case. */ 00210 00211 static int 00212 mi_interpreter_prompt_p (void *data) 00213 { 00214 return 0; 00215 } 00216 00217 void 00218 mi_cmd_interpreter_exec (char *command, char **argv, int argc) 00219 { 00220 struct interp *interp_to_use; 00221 int i; 00222 char *mi_error_message = NULL; 00223 struct cleanup *old_chain; 00224 00225 if (argc < 2) 00226 error (_("-interpreter-exec: " 00227 "Usage: -interpreter-exec interp command")); 00228 00229 interp_to_use = interp_lookup (argv[0]); 00230 if (interp_to_use == NULL) 00231 error (_("-interpreter-exec: could not find interpreter \"%s\""), 00232 argv[0]); 00233 00234 if (!interp_exec_p (interp_to_use)) 00235 error (_("-interpreter-exec: interpreter \"%s\" " 00236 "does not support command execution"), 00237 argv[0]); 00238 00239 /* Insert the MI out hooks, making sure to also call the 00240 interpreter's hooks if it has any. */ 00241 /* KRS: We shouldn't need this... Events should be installed and 00242 they should just ALWAYS fire something out down the MI 00243 channel. */ 00244 mi_insert_notify_hooks (); 00245 00246 /* Now run the code. */ 00247 00248 old_chain = make_cleanup (null_cleanup, 0); 00249 for (i = 1; i < argc; i++) 00250 { 00251 struct gdb_exception e = interp_exec (interp_to_use, argv[i]); 00252 00253 if (e.reason < 0) 00254 { 00255 mi_error_message = xstrdup (e.message); 00256 make_cleanup (xfree, mi_error_message); 00257 break; 00258 } 00259 } 00260 00261 mi_remove_notify_hooks (); 00262 00263 if (mi_error_message != NULL) 00264 error ("%s", mi_error_message); 00265 do_cleanups (old_chain); 00266 } 00267 00268 /* This inserts a number of hooks that are meant to produce 00269 async-notify ("=") MI messages while running commands in another 00270 interpreter using mi_interpreter_exec. The canonical use for this 00271 is to allow access to the gdb CLI interpreter from within the MI, 00272 while still producing MI style output when actions in the CLI 00273 command change GDB's state. */ 00274 00275 static void 00276 mi_insert_notify_hooks (void) 00277 { 00278 deprecated_query_hook = mi_interp_query_hook; 00279 } 00280 00281 static void 00282 mi_remove_notify_hooks (void) 00283 { 00284 deprecated_query_hook = NULL; 00285 } 00286 00287 static int 00288 mi_interp_query_hook (const char *ctlstr, va_list ap) 00289 { 00290 return 1; 00291 } 00292 00293 static void 00294 mi_execute_command_wrapper (const char *cmd) 00295 { 00296 mi_execute_command (cmd, stdin == instream); 00297 } 00298 00299 /* mi_execute_command_wrapper wrapper suitable for INPUT_HANDLER. */ 00300 00301 static void 00302 mi_execute_command_input_handler (char *cmd) 00303 { 00304 mi_execute_command_wrapper (cmd); 00305 00306 fputs_unfiltered ("(gdb) \n", raw_stdout); 00307 gdb_flush (raw_stdout); 00308 } 00309 00310 static void 00311 mi_command_loop (void *data) 00312 { 00313 /* Turn off 8 bit strings in quoted output. Any character with the 00314 high bit set is printed using C's octal format. */ 00315 sevenbit_strings = 1; 00316 00317 /* Tell the world that we're alive. */ 00318 fputs_unfiltered ("(gdb) \n", raw_stdout); 00319 gdb_flush (raw_stdout); 00320 00321 start_event_loop (); 00322 } 00323 00324 static void 00325 mi_new_thread (struct thread_info *t) 00326 { 00327 struct mi_interp *mi = top_level_interpreter_data (); 00328 struct inferior *inf = find_inferior_pid (ptid_get_pid (t->ptid)); 00329 00330 gdb_assert (inf); 00331 00332 fprintf_unfiltered (mi->event_channel, 00333 "thread-created,id=\"%d\",group-id=\"i%d\"", 00334 t->num, inf->num); 00335 gdb_flush (mi->event_channel); 00336 } 00337 00338 static void 00339 mi_thread_exit (struct thread_info *t, int silent) 00340 { 00341 struct mi_interp *mi; 00342 struct inferior *inf; 00343 00344 if (silent) 00345 return; 00346 00347 inf = find_inferior_pid (ptid_get_pid (t->ptid)); 00348 00349 mi = top_level_interpreter_data (); 00350 target_terminal_ours (); 00351 fprintf_unfiltered (mi->event_channel, 00352 "thread-exited,id=\"%d\",group-id=\"i%d\"", 00353 t->num, inf->num); 00354 gdb_flush (mi->event_channel); 00355 } 00356 00357 /* Emit notification on changing the state of record. */ 00358 00359 static void 00360 mi_record_changed (struct inferior *inferior, int started) 00361 { 00362 struct mi_interp *mi = top_level_interpreter_data (); 00363 00364 fprintf_unfiltered (mi->event_channel, "record-%s,thread-group=\"i%d\"", 00365 started ? "started" : "stopped", inferior->num); 00366 00367 gdb_flush (mi->event_channel); 00368 } 00369 00370 static void 00371 mi_inferior_added (struct inferior *inf) 00372 { 00373 struct mi_interp *mi = top_level_interpreter_data (); 00374 00375 target_terminal_ours (); 00376 fprintf_unfiltered (mi->event_channel, 00377 "thread-group-added,id=\"i%d\"", 00378 inf->num); 00379 gdb_flush (mi->event_channel); 00380 } 00381 00382 static void 00383 mi_inferior_appeared (struct inferior *inf) 00384 { 00385 struct mi_interp *mi = top_level_interpreter_data (); 00386 00387 target_terminal_ours (); 00388 fprintf_unfiltered (mi->event_channel, 00389 "thread-group-started,id=\"i%d\",pid=\"%d\"", 00390 inf->num, inf->pid); 00391 gdb_flush (mi->event_channel); 00392 } 00393 00394 static void 00395 mi_inferior_exit (struct inferior *inf) 00396 { 00397 struct mi_interp *mi = top_level_interpreter_data (); 00398 00399 target_terminal_ours (); 00400 if (inf->has_exit_code) 00401 fprintf_unfiltered (mi->event_channel, 00402 "thread-group-exited,id=\"i%d\",exit-code=\"%s\"", 00403 inf->num, int_string (inf->exit_code, 8, 0, 0, 1)); 00404 else 00405 fprintf_unfiltered (mi->event_channel, 00406 "thread-group-exited,id=\"i%d\"", inf->num); 00407 00408 gdb_flush (mi->event_channel); 00409 } 00410 00411 static void 00412 mi_inferior_removed (struct inferior *inf) 00413 { 00414 struct mi_interp *mi = top_level_interpreter_data (); 00415 00416 target_terminal_ours (); 00417 fprintf_unfiltered (mi->event_channel, 00418 "thread-group-removed,id=\"i%d\"", 00419 inf->num); 00420 gdb_flush (mi->event_channel); 00421 } 00422 00423 static void 00424 mi_on_normal_stop (struct bpstats *bs, int print_frame) 00425 { 00426 /* Since this can be called when CLI command is executing, 00427 using cli interpreter, be sure to use MI uiout for output, 00428 not the current one. */ 00429 struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ()); 00430 00431 if (print_frame) 00432 { 00433 int core; 00434 00435 if (current_uiout != mi_uiout) 00436 { 00437 /* The normal_stop function has printed frame information 00438 into CLI uiout, or some other non-MI uiout. There's no 00439 way we can extract proper fields from random uiout 00440 object, so we print the frame again. In practice, this 00441 can only happen when running a CLI command in MI. */ 00442 struct ui_out *saved_uiout = current_uiout; 00443 struct target_waitstatus last; 00444 ptid_t last_ptid; 00445 00446 current_uiout = mi_uiout; 00447 00448 get_last_target_status (&last_ptid, &last); 00449 bpstat_print (bs, last.kind); 00450 00451 print_stack_frame (get_selected_frame (NULL), 0, SRC_AND_LOC, 1); 00452 current_uiout = saved_uiout; 00453 } 00454 00455 ui_out_field_int (mi_uiout, "thread-id", 00456 pid_to_thread_id (inferior_ptid)); 00457 if (non_stop) 00458 { 00459 struct cleanup *back_to = make_cleanup_ui_out_list_begin_end 00460 (mi_uiout, "stopped-threads"); 00461 00462 ui_out_field_int (mi_uiout, NULL, 00463 pid_to_thread_id (inferior_ptid)); 00464 do_cleanups (back_to); 00465 } 00466 else 00467 ui_out_field_string (mi_uiout, "stopped-threads", "all"); 00468 00469 core = target_core_of_thread (inferior_ptid); 00470 if (core != -1) 00471 ui_out_field_int (mi_uiout, "core", core); 00472 } 00473 00474 fputs_unfiltered ("*stopped", raw_stdout); 00475 mi_out_put (mi_uiout, raw_stdout); 00476 mi_out_rewind (mi_uiout); 00477 mi_print_timing_maybe (); 00478 fputs_unfiltered ("\n", raw_stdout); 00479 gdb_flush (raw_stdout); 00480 } 00481 00482 static void 00483 mi_about_to_proceed (void) 00484 { 00485 /* Suppress output while calling an inferior function. */ 00486 00487 if (!ptid_equal (inferior_ptid, null_ptid)) 00488 { 00489 struct thread_info *tp = inferior_thread (); 00490 00491 if (tp->control.in_infcall) 00492 return; 00493 } 00494 00495 mi_proceeded = 1; 00496 } 00497 00498 /* When the element is non-zero, no MI notifications will be emitted in 00499 response to the corresponding observers. */ 00500 00501 struct mi_suppress_notification mi_suppress_notification = 00502 { 00503 0, 00504 0, 00505 0, 00506 }; 00507 00508 /* Emit notification on changing a traceframe. */ 00509 00510 static void 00511 mi_traceframe_changed (int tfnum, int tpnum) 00512 { 00513 struct mi_interp *mi = top_level_interpreter_data (); 00514 00515 if (mi_suppress_notification.traceframe) 00516 return; 00517 00518 target_terminal_ours (); 00519 00520 if (tfnum >= 0) 00521 fprintf_unfiltered (mi->event_channel, "traceframe-changed," 00522 "num=\"%d\",tracepoint=\"%d\"\n", 00523 tfnum, tpnum); 00524 else 00525 fprintf_unfiltered (mi->event_channel, "traceframe-changed,end"); 00526 00527 gdb_flush (mi->event_channel); 00528 } 00529 00530 /* Emit notification on creating a trace state variable. */ 00531 00532 static void 00533 mi_tsv_created (const struct trace_state_variable *tsv) 00534 { 00535 struct mi_interp *mi = top_level_interpreter_data (); 00536 00537 target_terminal_ours (); 00538 00539 fprintf_unfiltered (mi->event_channel, "tsv-created," 00540 "name=\"%s\",initial=\"%s\"\n", 00541 tsv->name, plongest (tsv->initial_value)); 00542 00543 gdb_flush (mi->event_channel); 00544 } 00545 00546 /* Emit notification on deleting a trace state variable. */ 00547 00548 static void 00549 mi_tsv_deleted (const struct trace_state_variable *tsv) 00550 { 00551 struct mi_interp *mi = top_level_interpreter_data (); 00552 00553 target_terminal_ours (); 00554 00555 if (tsv != NULL) 00556 fprintf_unfiltered (mi->event_channel, "tsv-deleted," 00557 "name=\"%s\"\n", tsv->name); 00558 else 00559 fprintf_unfiltered (mi->event_channel, "tsv-deleted\n"); 00560 00561 gdb_flush (mi->event_channel); 00562 } 00563 00564 /* Emit notification on modifying a trace state variable. */ 00565 00566 static void 00567 mi_tsv_modified (const struct trace_state_variable *tsv) 00568 { 00569 struct mi_interp *mi = top_level_interpreter_data (); 00570 struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ()); 00571 00572 target_terminal_ours (); 00573 00574 fprintf_unfiltered (mi->event_channel, 00575 "tsv-modified"); 00576 00577 ui_out_redirect (mi_uiout, mi->event_channel); 00578 00579 ui_out_field_string (mi_uiout, "name", tsv->name); 00580 ui_out_field_string (mi_uiout, "initial", 00581 plongest (tsv->initial_value)); 00582 if (tsv->value_known) 00583 ui_out_field_string (mi_uiout, "current", plongest (tsv->value)); 00584 00585 ui_out_redirect (mi_uiout, NULL); 00586 00587 gdb_flush (mi->event_channel); 00588 } 00589 00590 /* Emit notification about a created breakpoint. */ 00591 00592 static void 00593 mi_breakpoint_created (struct breakpoint *b) 00594 { 00595 struct mi_interp *mi = top_level_interpreter_data (); 00596 struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ()); 00597 volatile struct gdb_exception e; 00598 00599 if (mi_suppress_notification.breakpoint) 00600 return; 00601 00602 if (b->number <= 0) 00603 return; 00604 00605 target_terminal_ours (); 00606 fprintf_unfiltered (mi->event_channel, 00607 "breakpoint-created"); 00608 /* We want the output from gdb_breakpoint_query to go to 00609 mi->event_channel. One approach would be to just call 00610 gdb_breakpoint_query, and then use mi_out_put to send the current 00611 content of mi_outout into mi->event_channel. However, that will 00612 break if anything is output to mi_uiout prior to calling the 00613 breakpoint_created notifications. So, we use 00614 ui_out_redirect. */ 00615 ui_out_redirect (mi_uiout, mi->event_channel); 00616 TRY_CATCH (e, RETURN_MASK_ERROR) 00617 gdb_breakpoint_query (mi_uiout, b->number, NULL); 00618 ui_out_redirect (mi_uiout, NULL); 00619 00620 gdb_flush (mi->event_channel); 00621 } 00622 00623 /* Emit notification about deleted breakpoint. */ 00624 00625 static void 00626 mi_breakpoint_deleted (struct breakpoint *b) 00627 { 00628 struct mi_interp *mi = top_level_interpreter_data (); 00629 00630 if (mi_suppress_notification.breakpoint) 00631 return; 00632 00633 if (b->number <= 0) 00634 return; 00635 00636 target_terminal_ours (); 00637 00638 fprintf_unfiltered (mi->event_channel, "breakpoint-deleted,id=\"%d\"", 00639 b->number); 00640 00641 gdb_flush (mi->event_channel); 00642 } 00643 00644 /* Emit notification about modified breakpoint. */ 00645 00646 static void 00647 mi_breakpoint_modified (struct breakpoint *b) 00648 { 00649 struct mi_interp *mi = top_level_interpreter_data (); 00650 struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ()); 00651 volatile struct gdb_exception e; 00652 00653 if (mi_suppress_notification.breakpoint) 00654 return; 00655 00656 if (b->number <= 0) 00657 return; 00658 00659 target_terminal_ours (); 00660 fprintf_unfiltered (mi->event_channel, 00661 "breakpoint-modified"); 00662 /* We want the output from gdb_breakpoint_query to go to 00663 mi->event_channel. One approach would be to just call 00664 gdb_breakpoint_query, and then use mi_out_put to send the current 00665 content of mi_outout into mi->event_channel. However, that will 00666 break if anything is output to mi_uiout prior to calling the 00667 breakpoint_created notifications. So, we use 00668 ui_out_redirect. */ 00669 ui_out_redirect (mi_uiout, mi->event_channel); 00670 TRY_CATCH (e, RETURN_MASK_ERROR) 00671 gdb_breakpoint_query (mi_uiout, b->number, NULL); 00672 ui_out_redirect (mi_uiout, NULL); 00673 00674 gdb_flush (mi->event_channel); 00675 } 00676 00677 static int 00678 mi_output_running_pid (struct thread_info *info, void *arg) 00679 { 00680 ptid_t *ptid = arg; 00681 00682 if (ptid_get_pid (*ptid) == ptid_get_pid (info->ptid)) 00683 fprintf_unfiltered (raw_stdout, 00684 "*running,thread-id=\"%d\"\n", 00685 info->num); 00686 00687 return 0; 00688 } 00689 00690 static int 00691 mi_inferior_count (struct inferior *inf, void *arg) 00692 { 00693 if (inf->pid != 0) 00694 { 00695 int *count_p = arg; 00696 (*count_p)++; 00697 } 00698 00699 return 0; 00700 } 00701 00702 static void 00703 mi_on_resume (ptid_t ptid) 00704 { 00705 struct thread_info *tp = NULL; 00706 00707 if (ptid_equal (ptid, minus_one_ptid) || ptid_is_pid (ptid)) 00708 tp = inferior_thread (); 00709 else 00710 tp = find_thread_ptid (ptid); 00711 00712 /* Suppress output while calling an inferior function. */ 00713 if (tp->control.in_infcall) 00714 return; 00715 00716 /* To cater for older frontends, emit ^running, but do it only once 00717 per each command. We do it here, since at this point we know 00718 that the target was successfully resumed, and in non-async mode, 00719 we won't return back to MI interpreter code until the target 00720 is done running, so delaying the output of "^running" until then 00721 will make it impossible for frontend to know what's going on. 00722 00723 In future (MI3), we'll be outputting "^done" here. */ 00724 if (!running_result_record_printed && mi_proceeded) 00725 { 00726 fprintf_unfiltered (raw_stdout, "%s^running\n", 00727 current_token ? current_token : ""); 00728 } 00729 00730 if (ptid_get_pid (ptid) == -1) 00731 fprintf_unfiltered (raw_stdout, "*running,thread-id=\"all\"\n"); 00732 else if (ptid_is_pid (ptid)) 00733 { 00734 int count = 0; 00735 00736 /* Backwards compatibility. If there's only one inferior, 00737 output "all", otherwise, output each resumed thread 00738 individually. */ 00739 iterate_over_inferiors (mi_inferior_count, &count); 00740 00741 if (count == 1) 00742 fprintf_unfiltered (raw_stdout, "*running,thread-id=\"all\"\n"); 00743 else 00744 iterate_over_threads (mi_output_running_pid, &ptid); 00745 } 00746 else 00747 { 00748 struct thread_info *ti = find_thread_ptid (ptid); 00749 00750 gdb_assert (ti); 00751 fprintf_unfiltered (raw_stdout, "*running,thread-id=\"%d\"\n", ti->num); 00752 } 00753 00754 if (!running_result_record_printed && mi_proceeded) 00755 { 00756 running_result_record_printed = 1; 00757 /* This is what gdb used to do historically -- printing prompt even if 00758 it cannot actually accept any input. This will be surely removed 00759 for MI3, and may be removed even earler. */ 00760 /* FIXME: review the use of target_is_async_p here -- is that 00761 what we want? */ 00762 if (!target_is_async_p ()) 00763 fputs_unfiltered ("(gdb) \n", raw_stdout); 00764 } 00765 gdb_flush (raw_stdout); 00766 } 00767 00768 static void 00769 mi_solib_loaded (struct so_list *solib) 00770 { 00771 struct mi_interp *mi = top_level_interpreter_data (); 00772 00773 target_terminal_ours (); 00774 if (gdbarch_has_global_solist (target_gdbarch ())) 00775 fprintf_unfiltered (mi->event_channel, 00776 "library-loaded,id=\"%s\",target-name=\"%s\"," 00777 "host-name=\"%s\",symbols-loaded=\"%d\"", 00778 solib->so_original_name, solib->so_original_name, 00779 solib->so_name, solib->symbols_loaded); 00780 else 00781 fprintf_unfiltered (mi->event_channel, 00782 "library-loaded,id=\"%s\",target-name=\"%s\"," 00783 "host-name=\"%s\",symbols-loaded=\"%d\"," 00784 "thread-group=\"i%d\"", 00785 solib->so_original_name, solib->so_original_name, 00786 solib->so_name, solib->symbols_loaded, 00787 current_inferior ()->num); 00788 00789 gdb_flush (mi->event_channel); 00790 } 00791 00792 static void 00793 mi_solib_unloaded (struct so_list *solib) 00794 { 00795 struct mi_interp *mi = top_level_interpreter_data (); 00796 00797 target_terminal_ours (); 00798 if (gdbarch_has_global_solist (target_gdbarch ())) 00799 fprintf_unfiltered (mi->event_channel, 00800 "library-unloaded,id=\"%s\",target-name=\"%s\"," 00801 "host-name=\"%s\"", 00802 solib->so_original_name, solib->so_original_name, 00803 solib->so_name); 00804 else 00805 fprintf_unfiltered (mi->event_channel, 00806 "library-unloaded,id=\"%s\",target-name=\"%s\"," 00807 "host-name=\"%s\",thread-group=\"i%d\"", 00808 solib->so_original_name, solib->so_original_name, 00809 solib->so_name, current_inferior ()->num); 00810 00811 gdb_flush (mi->event_channel); 00812 } 00813 00814 /* Emit notification about the command parameter change. */ 00815 00816 static void 00817 mi_command_param_changed (const char *param, const char *value) 00818 { 00819 struct mi_interp *mi = top_level_interpreter_data (); 00820 struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ()); 00821 00822 if (mi_suppress_notification.cmd_param_changed) 00823 return; 00824 00825 target_terminal_ours (); 00826 00827 fprintf_unfiltered (mi->event_channel, 00828 "cmd-param-changed"); 00829 00830 ui_out_redirect (mi_uiout, mi->event_channel); 00831 00832 ui_out_field_string (mi_uiout, "param", param); 00833 ui_out_field_string (mi_uiout, "value", value); 00834 00835 ui_out_redirect (mi_uiout, NULL); 00836 00837 gdb_flush (mi->event_channel); 00838 } 00839 00840 /* Emit notification about the target memory change. */ 00841 00842 static void 00843 mi_memory_changed (struct inferior *inferior, CORE_ADDR memaddr, 00844 ssize_t len, const bfd_byte *myaddr) 00845 { 00846 struct mi_interp *mi = top_level_interpreter_data (); 00847 struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ()); 00848 struct obj_section *sec; 00849 00850 if (mi_suppress_notification.memory) 00851 return; 00852 00853 target_terminal_ours (); 00854 00855 fprintf_unfiltered (mi->event_channel, 00856 "memory-changed"); 00857 00858 ui_out_redirect (mi_uiout, mi->event_channel); 00859 00860 ui_out_field_fmt (mi_uiout, "thread-group", "i%d", inferior->num); 00861 ui_out_field_core_addr (mi_uiout, "addr", target_gdbarch (), memaddr); 00862 ui_out_field_fmt (mi_uiout, "len", "0x%zx", len); 00863 00864 /* Append 'type=code' into notification if MEMADDR falls in the range of 00865 sections contain code. */ 00866 sec = find_pc_section (memaddr); 00867 if (sec != NULL && sec->objfile != NULL) 00868 { 00869 flagword flags = bfd_get_section_flags (sec->objfile->obfd, 00870 sec->the_bfd_section); 00871 00872 if (flags & SEC_CODE) 00873 ui_out_field_string (mi_uiout, "type", "code"); 00874 } 00875 00876 ui_out_redirect (mi_uiout, NULL); 00877 00878 gdb_flush (mi->event_channel); 00879 } 00880 00881 static int 00882 report_initial_inferior (struct inferior *inf, void *closure) 00883 { 00884 /* This function is called from mi_intepreter_init, and since 00885 mi_inferior_added assumes that inferior is fully initialized 00886 and top_level_interpreter_data is set, we cannot call 00887 it here. */ 00888 struct mi_interp *mi = closure; 00889 00890 target_terminal_ours (); 00891 fprintf_unfiltered (mi->event_channel, 00892 "thread-group-added,id=\"i%d\"", 00893 inf->num); 00894 gdb_flush (mi->event_channel); 00895 return 0; 00896 } 00897 00898 static struct ui_out * 00899 mi_ui_out (struct interp *interp) 00900 { 00901 struct mi_interp *mi = interp_data (interp); 00902 00903 return mi->uiout; 00904 } 00905 00906 /* Save the original value of raw_stdout here when logging, so we can 00907 restore correctly when done. */ 00908 00909 static struct ui_file *saved_raw_stdout; 00910 00911 /* Do MI-specific logging actions; save raw_stdout, and change all 00912 the consoles to use the supplied ui-file(s). */ 00913 00914 static int 00915 mi_set_logging (struct interp *interp, int start_log, 00916 struct ui_file *out, struct ui_file *logfile) 00917 { 00918 struct mi_interp *mi = interp_data (interp); 00919 00920 if (!mi) 00921 return 0; 00922 00923 if (start_log) 00924 { 00925 /* The tee created already is based on gdb_stdout, which for MI 00926 is a console and so we end up in an infinite loop of console 00927 writing to ui_file writing to console etc. So discard the 00928 existing tee (it hasn't been used yet, and MI won't ever use 00929 it), and create one based on raw_stdout instead. */ 00930 if (logfile) 00931 { 00932 ui_file_delete (out); 00933 out = tee_file_new (raw_stdout, 0, logfile, 0); 00934 } 00935 00936 saved_raw_stdout = raw_stdout; 00937 raw_stdout = out; 00938 } 00939 else 00940 { 00941 raw_stdout = saved_raw_stdout; 00942 saved_raw_stdout = NULL; 00943 } 00944 00945 mi_console_set_raw (mi->out, raw_stdout); 00946 mi_console_set_raw (mi->err, raw_stdout); 00947 mi_console_set_raw (mi->log, raw_stdout); 00948 mi_console_set_raw (mi->targ, raw_stdout); 00949 mi_console_set_raw (mi->event_channel, raw_stdout); 00950 00951 return 1; 00952 } 00953 00954 extern initialize_file_ftype _initialize_mi_interp; /* -Wmissing-prototypes */ 00955 00956 void 00957 _initialize_mi_interp (void) 00958 { 00959 static const struct interp_procs procs = 00960 { 00961 mi_interpreter_init, /* init_proc */ 00962 mi_interpreter_resume, /* resume_proc */ 00963 mi_interpreter_suspend, /* suspend_proc */ 00964 mi_interpreter_exec, /* exec_proc */ 00965 mi_interpreter_prompt_p, /* prompt_proc_p */ 00966 mi_ui_out, /* ui_out_proc */ 00967 mi_set_logging, /* set_logging_proc */ 00968 mi_command_loop /* command_loop_proc */ 00969 }; 00970 00971 /* The various interpreter levels. */ 00972 interp_add (interp_new (INTERP_MI1, &procs)); 00973 interp_add (interp_new (INTERP_MI2, &procs)); 00974 interp_add (interp_new (INTERP_MI3, &procs)); 00975 interp_add (interp_new (INTERP_MI, &procs)); 00976 }