static struct sim_inferior_data * get_sim_inferior_data (struct inferior *inf, int sim_instance_needed) { SIM_DESC sim_desc = NULL; struct sim_inferior_data *sim_data = (struct sim_inferior_data *) inferior_data (inf, sim_inferior_data_key); /* Try to allocate a new sim instance, if needed. We do this ahead of a potential allocation of a sim_inferior_data struct in order to avoid needlessly allocating that struct in the event that the sim instance allocation fails. */ if (sim_instance_needed == SIM_INSTANCE_NEEDED && (sim_data == NULL || sim_data->gdbsim_desc == NULL)) { struct inferior *idup; sim_desc = sim_open (SIM_OPEN_DEBUG, &gdb_callback, exec_bfd, sim_argv); if (sim_desc == NULL) error (_("Unable to create simulator instance for inferior %d."), inf->num); idup = iterate_over_inferiors (check_for_duplicate_sim_descriptor, sim_desc); if (idup != NULL) { /* We don't close the descriptor due to the fact that it's shared with some other inferior. If we were to close it, that might needlessly muck up the other inferior. Of course, it's possible that the damage has already been done... Note that it *will* ultimately be closed during cleanup of the other inferior. */ sim_desc = NULL; error ( _("Inferior %d and inferior %d would have identical simulator state.\n" "(This simulator does not support the running of more than one inferior.)"), inf->num, idup->num); } } if (sim_data == NULL) { sim_data = XCNEW(struct sim_inferior_data); set_inferior_data (inf, sim_inferior_data_key, sim_data); /* Allocate a ptid for this inferior. */ sim_data->remote_sim_ptid = ptid_build (next_pid, 0, next_pid); next_pid++; /* Initialize the other instance variables. */ sim_data->program_loaded = 0; sim_data->gdbsim_desc = sim_desc; sim_data->resume_siggnal = GDB_SIGNAL_0; sim_data->resume_step = 0; }
/* Implementation of gdb.inferiors () -> (gdb.Inferior, ...). Returns a tuple of all inferiors. */ PyObject * gdbpy_inferiors (PyObject *unused, PyObject *unused2) { int i = 0; PyObject *list, *inferior; struct inferior *inf; list = PyList_New (0); if (!list) return NULL; iterate_over_inferiors (build_inferior_list, list); return PyList_AsTuple (list); }
/* Implementation of gdb.inferiors () -> (gdb.Inferior, ...). Returns a tuple of all inferiors. */ PyObject * gdbpy_inferiors (PyObject *unused, PyObject *unused2) { PyObject *list, *tuple; list = PyList_New (0); if (!list) return NULL; if (iterate_over_inferiors (build_inferior_list, list)) { Py_DECREF (list); return NULL; } tuple = PyList_AsTuple (list); Py_DECREF (list); return tuple; }
static void * mi_interpreter_init (int top_level) { struct mi_interp *mi = XMALLOC (struct mi_interp); /* HACK: We need to force stdout/stderr to point at the console. This avoids any potential side effects caused by legacy code that is still using the TUI / fputs_unfiltered_hook. So we set up output channels for this now, and swap them in when we are run. */ raw_stdout = stdio_fileopen (stdout); /* Create MI channels */ mi->out = mi_console_file_new (raw_stdout, "~", '"'); mi->err = mi_console_file_new (raw_stdout, "&", '"'); mi->log = mi->err; mi->targ = mi_console_file_new (raw_stdout, "@", '"'); mi->event_channel = mi_console_file_new (raw_stdout, "=", 0); if (top_level) { observer_attach_new_thread (mi_new_thread); observer_attach_thread_exit (mi_thread_exit); observer_attach_inferior_added (mi_inferior_added); observer_attach_inferior_appeared (mi_inferior_appeared); observer_attach_inferior_exit (mi_inferior_exit); observer_attach_inferior_removed (mi_inferior_removed); observer_attach_normal_stop (mi_on_normal_stop); observer_attach_target_resumed (mi_on_resume); observer_attach_solib_loaded (mi_solib_loaded); observer_attach_solib_unloaded (mi_solib_unloaded); observer_attach_about_to_proceed (mi_about_to_proceed); /* The initial inferior is created before this function is called, so we need to report it explicitly. Use iteration in case future version of GDB creates more than one inferior up-front. */ iterate_over_inferiors (report_initial_inferior, mi); } return mi; }
static void mi_on_resume (ptid_t ptid) { struct thread_info *tp = NULL; if (ptid_equal (ptid, minus_one_ptid) || ptid_is_pid (ptid)) tp = inferior_thread (); else tp = find_thread_ptid (ptid); /* Suppress output while calling an inferior function. */ if (tp->control.in_infcall) return; /* To cater for older frontends, emit ^running, but do it only once per each command. We do it here, since at this point we know that the target was successfully resumed, and in non-async mode, we won't return back to MI interpreter code until the target is done running, so delaying the output of "^running" until then will make it impossible for frontend to know what's going on. In future (MI3), we'll be outputting "^done" here. */ if (!running_result_record_printed && mi_proceeded) { fprintf_unfiltered (raw_stdout, "%s^running\n", current_token ? current_token : ""); } if (ptid_get_pid (ptid) == -1) fprintf_unfiltered (raw_stdout, "*running,thread-id=\"all\"\n"); else if (ptid_is_pid (ptid)) { int count = 0; /* Backwards compatibility. If there's only one inferior, output "all", otherwise, output each resumed thread individually. */ iterate_over_inferiors (mi_inferior_count, &count); if (count == 1) fprintf_unfiltered (raw_stdout, "*running,thread-id=\"all\"\n"); else iterate_over_threads (mi_output_running_pid, &ptid); } else { struct thread_info *ti = find_thread_ptid (ptid); gdb_assert (ti); fprintf_unfiltered (raw_stdout, "*running,thread-id=\"%d\"\n", ti->num); } if (!running_result_record_printed && mi_proceeded) { running_result_record_printed = 1; /* This is what gdb used to do historically -- printing prompt even if it cannot actually accept any input. This will be surely removed for MI3, and may be removed even earlier. SYNC_EXECUTION is checked here because we only need to emit a prompt if a synchronous command was issued when the target is async. */ if (!target_is_async_p () || sync_execution) fputs_unfiltered ("(gdb) \n", raw_stdout); } gdb_flush (raw_stdout); }
static void * mi_interpreter_init (struct interp *interp, int top_level) { struct mi_interp *mi = XNEW (struct mi_interp); const char *name; int mi_version; /* Assign the output channel created at startup to its own global, so that we can create a console channel that encapsulates and prefixes all gdb_output-type bits coming from the rest of the debugger. */ raw_stdout = gdb_stdout; /* Create MI console channels, each with a different prefix so they can be distinguished. */ mi->out = mi_console_file_new (raw_stdout, "~", '"'); mi->err = mi_console_file_new (raw_stdout, "&", '"'); mi->log = mi->err; mi->targ = mi_console_file_new (raw_stdout, "@", '"'); mi->event_channel = mi_console_file_new (raw_stdout, "=", 0); name = interp_name (interp); /* INTERP_MI selects the most recent released version. "mi2" was released as part of GDB 6.0. */ if (strcmp (name, INTERP_MI) == 0) mi_version = 2; else if (strcmp (name, INTERP_MI1) == 0) mi_version = 1; else if (strcmp (name, INTERP_MI2) == 0) mi_version = 2; else if (strcmp (name, INTERP_MI3) == 0) mi_version = 3; else gdb_assert_not_reached ("unhandled MI version"); mi->mi_uiout = mi_out_new (mi_version); mi->cli_uiout = cli_out_new (mi->out); /* There are installed even if MI is not the top level interpreter. The callbacks themselves decide whether to be skipped. */ observer_attach_signal_received (mi_on_signal_received); observer_attach_end_stepping_range (mi_on_end_stepping_range); observer_attach_signal_exited (mi_on_signal_exited); observer_attach_exited (mi_on_exited); observer_attach_no_history (mi_on_no_history); if (top_level) { observer_attach_new_thread (mi_new_thread); observer_attach_thread_exit (mi_thread_exit); observer_attach_inferior_added (mi_inferior_added); observer_attach_inferior_appeared (mi_inferior_appeared); observer_attach_inferior_exit (mi_inferior_exit); observer_attach_inferior_removed (mi_inferior_removed); observer_attach_record_changed (mi_record_changed); observer_attach_normal_stop (mi_on_normal_stop); observer_attach_target_resumed (mi_on_resume); observer_attach_solib_loaded (mi_solib_loaded); observer_attach_solib_unloaded (mi_solib_unloaded); observer_attach_about_to_proceed (mi_about_to_proceed); observer_attach_traceframe_changed (mi_traceframe_changed); observer_attach_tsv_created (mi_tsv_created); observer_attach_tsv_deleted (mi_tsv_deleted); observer_attach_tsv_modified (mi_tsv_modified); observer_attach_breakpoint_created (mi_breakpoint_created); observer_attach_breakpoint_deleted (mi_breakpoint_deleted); observer_attach_breakpoint_modified (mi_breakpoint_modified); observer_attach_command_param_changed (mi_command_param_changed); observer_attach_memory_changed (mi_memory_changed); observer_attach_sync_execution_done (mi_on_sync_execution_done); /* The initial inferior is created before this function is called, so we need to report it explicitly. Use iteration in case future version of GDB creates more than one inferior up-front. */ iterate_over_inferiors (report_initial_inferior, mi); } return mi; }