X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fmi%2Fmi-main.c;h=da8c81f9e2265a4c1edc56c32d14e8bad5199d60;hb=268a13a5a3f7c6b9b6ffc5ac2d1b24eb41f3fbdc;hp=83b1fcf53223b33592f1fd3d5bce296ac8394895;hpb=245ad7d373aef22013b347504d30d2306da1bdbf;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c index 83b1fcf532..da8c81f9e2 100644 --- a/gdb/mi/mi-main.c +++ b/gdb/mi/mi-main.c @@ -1,6 +1,6 @@ /* MI Command Set. - Copyright (C) 2000-2017 Free Software Foundation, Inc. + Copyright (C) 2000-2019 Free Software Foundation, Inc. Contributed by Cygnus Solutions (a Red Hat company). @@ -38,32 +38,31 @@ #include "gdbcore.h" /* For write_memory(). */ #include "value.h" #include "regcache.h" -#include "gdb.h" #include "frame.h" #include "mi-main.h" #include "mi-common.h" #include "language.h" #include "valprint.h" -#include "inferior.h" #include "osdata.h" -#include "splay-tree.h" +#include "gdbsupport/gdb_splay_tree.h" #include "tracepoint.h" #include "ctf.h" #include "ada-lang.h" #include "linespec.h" #include "extension.h" #include "gdbcmd.h" -#include "observer.h" -#include "common/gdb_optional.h" -#include "common/byte-vector.h" +#include "observable.h" +#include "gdbsupport/gdb_optional.h" +#include "gdbsupport/byte-vector.h" #include -#include "run-time-clock.h" +#include "gdbsupport/run-time-clock.h" #include #include "progspace-and-thread.h" -#include "common/rsp-low.h" +#include "gdbsupport/rsp-low.h" #include #include +#include enum { @@ -96,8 +95,8 @@ static void mi_execute_cli_command (const char *cmd, int args_p, const char *args); static void mi_execute_async_cli_command (const char *cli_command, char **argv, int argc); -static int register_changed_p (int regnum, struct regcache *, - struct regcache *); +static bool register_changed_p (int regnum, readonly_detached_regcache *, + readonly_detached_regcache *); static void output_register (struct frame_info *, int regnum, int format, int skip_unavailable); @@ -109,7 +108,7 @@ static int mi_async = 0; static int mi_async_1 = 0; static void -set_mi_async_command (char *args, int from_tty, +set_mi_async_command (const char *args, int from_tty, struct cmd_list_element *c) { if (have_live_inferiors ()) @@ -243,13 +242,13 @@ mi_cmd_exec_jump (const char *args, char **argv, int argc) static void proceed_thread (struct thread_info *thread, int pid) { - if (!is_stopped (thread->ptid)) + if (thread->state != THREAD_STOPPED) return; - if (pid != 0 && ptid_get_pid (thread->ptid) != pid) + if (pid != 0 && thread->ptid.pid () != pid) return; - switch_to_thread (thread->ptid); + switch_to_thread (thread); clear_proceed_status (0); proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT); } @@ -266,7 +265,7 @@ proceed_thread_callback (struct thread_info *thread, void *arg) static void exec_continue (char **argv, int argc) { - prepare_execution_command (¤t_target, mi_async_p ()); + prepare_execution_command (current_top_target (), mi_async_p ()); if (non_stop) { @@ -345,10 +344,10 @@ interrupt_thread_callback (struct thread_info *thread, void *arg) { int pid = *(int *)arg; - if (!is_running (thread->ptid)) + if (thread->state != THREAD_RUNNING) return 0; - if (ptid_get_pid (thread->ptid) != pid) + if (thread->ptid.pid () != pid) return 0; target_stop (thread->ptid); @@ -405,25 +404,20 @@ run_one_inferior (struct inferior *inf, void *arg) int start_p = *(int *) arg; const char *run_cmd = start_p ? "start" : "run"; struct target_ops *run_target = find_run_target (); - int async_p = mi_async && run_target->to_can_async_p (run_target); + int async_p = mi_async && run_target->can_async_p (); if (inf->pid != 0) { - if (inf->pid != ptid_get_pid (inferior_ptid)) - { - struct thread_info *tp; - - tp = any_thread_of_process (inf->pid); - if (!tp) - error (_("Inferior has no threads.")); + thread_info *tp = any_thread_of_inferior (inf); + if (tp == NULL) + error (_("Inferior has no threads.")); - switch_to_thread (tp->ptid); - } + switch_to_thread (tp); } else { set_current_inferior (inf); - switch_to_thread (null_ptid); + switch_to_no_thread (); set_current_program_space (inf->pspace); } mi_execute_cli_command (run_cmd, async_p, @@ -479,7 +473,7 @@ mi_cmd_exec_run (const char *command, char **argv, int argc) { const char *run_cmd = start_p ? "start" : "run"; struct target_ops *run_target = find_run_target (); - int async_p = mi_async && run_target->to_can_async_p (run_target); + int async_p = mi_async && run_target->can_async_p (); mi_execute_cli_command (run_cmd, async_p, async_p ? "&" : NULL); @@ -492,7 +486,7 @@ find_thread_of_process (struct thread_info *ti, void *p) { int pid = *(int *)p; - if (ptid_get_pid (ti->ptid) == pid && !is_exited (ti->ptid)) + if (ti->ptid.pid () == pid && ti->state != THREAD_EXITED) return 1; return 0; @@ -540,7 +534,7 @@ mi_cmd_target_detach (const char *command, char **argv, int argc) if (!tp) error (_("Thread group is empty")); - switch_to_thread (tp->ptid); + switch_to_thread (tp); } detach_command (NULL, 0); @@ -555,49 +549,56 @@ mi_cmd_target_flash_erase (const char *command, char **argv, int argc) void mi_cmd_thread_select (const char *command, char **argv, int argc) { - enum gdb_rc rc; - char *mi_error_message; - ptid_t previous_ptid = inferior_ptid; - if (argc != 1) error (_("-thread-select: USAGE: threadnum.")); - rc = gdb_thread_select (current_uiout, argv[0], &mi_error_message); + int num = value_as_long (parse_and_eval (argv[0])); + thread_info *thr = find_thread_global_id (num); + if (thr == NULL) + error (_("Thread ID %d not known."), num); - /* If thread switch did not succeed don't notify or print. */ - if (rc == GDB_RC_FAIL) - { - make_cleanup (xfree, mi_error_message); - error ("%s", mi_error_message); - } + ptid_t previous_ptid = inferior_ptid; + + thread_select (argv[0], thr); print_selected_thread_frame (current_uiout, USER_SELECTED_THREAD | USER_SELECTED_FRAME); /* Notify if the thread has effectively changed. */ - if (!ptid_equal (inferior_ptid, previous_ptid)) + if (inferior_ptid != previous_ptid) { - observer_notify_user_selected_context_changed (USER_SELECTED_THREAD - | USER_SELECTED_FRAME); + gdb::observers::user_selected_context_changed.notify + (USER_SELECTED_THREAD | USER_SELECTED_FRAME); } } void mi_cmd_thread_list_ids (const char *command, char **argv, int argc) { - enum gdb_rc rc; - char *mi_error_message; - if (argc != 0) error (_("-thread-list-ids: No arguments required.")); - rc = gdb_list_thread_ids (current_uiout, &mi_error_message); + int num = 0; + int current_thread = -1; - if (rc == GDB_RC_FAIL) - { - make_cleanup (xfree, mi_error_message); - error ("%s", mi_error_message); - } + update_thread_list (); + + { + ui_out_emit_tuple tuple_emitter (current_uiout, "thread-ids"); + + for (thread_info *tp : all_non_exited_threads ()) + { + if (tp->ptid == inferior_ptid) + current_thread = tp->global_num; + + num++; + current_uiout->field_int ("thread-id", tp->global_num); + } + } + + if (current_thread != -1) + current_uiout->field_int ("current-thread-id", current_thread); + current_uiout->field_int ("number-of-threads", num); } void @@ -620,7 +621,7 @@ collect_cores (struct thread_info *ti, void *xdata) { struct collect_cores_data *data = (struct collect_cores_data *) xdata; - if (ptid_get_pid (ti->ptid) == data->pid) + if (ti->ptid.pid () == data->pid) { int core = target_core_of_thread (ti->ptid); @@ -694,155 +695,88 @@ static void output_cores (struct ui_out *uiout, const char *field_name, const char *xcores) { ui_out_emit_list list_emitter (uiout, field_name); - gdb::unique_xmalloc_ptr cores (xstrdup (xcores)); + auto cores = make_unique_xstrdup (xcores); char *p = cores.get (); for (p = strtok (p, ","); p; p = strtok (NULL, ",")) uiout->field_string (NULL, p); } -static void -do_nothing (splay_tree_key k) -{ -} - -static void -free_vector_of_osdata_items (splay_tree_value xvalue) -{ - VEC (osdata_item_s) *value = (VEC (osdata_item_s) *) xvalue; - - /* We don't free the items itself, it will be done separately. */ - VEC_free (osdata_item_s, value); -} - -static int -splay_tree_int_comparator (splay_tree_key xa, splay_tree_key xb) -{ - int a = xa; - int b = xb; - - return a - b; -} - -static void -free_splay_tree (void *xt) -{ - splay_tree t = (splay_tree) xt; - splay_tree_delete (t); -} - static void list_available_thread_groups (const std::set &ids, int recurse) { - struct osdata *data; - struct osdata_item *item; - int ix_items; struct ui_out *uiout = current_uiout; - struct cleanup *cleanup; - /* This keeps a map from integer (pid) to VEC (struct osdata_item *)* - The vector contains information about all threads for the given pid. - This is assigned an initial value to avoid "may be used uninitialized" - warning from gcc. */ - splay_tree tree = NULL; + /* This keeps a map from integer (pid) to vector of struct osdata_item. + The vector contains information about all threads for the given pid. */ + std::map> tree; /* get_osdata will throw if it cannot return data. */ - data = get_osdata ("processes"); - cleanup = make_cleanup_osdata_free (data); + std::unique_ptr data = get_osdata ("processes"); if (recurse) { - struct osdata *threads = get_osdata ("threads"); - - make_cleanup_osdata_free (threads); - tree = splay_tree_new (splay_tree_int_comparator, - do_nothing, - free_vector_of_osdata_items); - make_cleanup (free_splay_tree, tree); + std::unique_ptr threads = get_osdata ("threads"); - for (ix_items = 0; - VEC_iterate (osdata_item_s, threads->items, - ix_items, item); - ix_items++) + for (const osdata_item &item : threads->items) { - const char *pid = get_osdata_column (item, "pid"); - int pid_i = strtoul (pid, NULL, 0); - VEC (osdata_item_s) *vec = 0; + const std::string *pid = get_osdata_column (item, "pid"); + int pid_i = strtoul (pid->c_str (), NULL, 0); - splay_tree_node n = splay_tree_lookup (tree, pid_i); - if (!n) - { - VEC_safe_push (osdata_item_s, vec, item); - splay_tree_insert (tree, pid_i, (splay_tree_value)vec); - } - else - { - vec = (VEC (osdata_item_s) *) n->value; - VEC_safe_push (osdata_item_s, vec, item); - n->value = (splay_tree_value) vec; - } + tree[pid_i].push_back (item); } } ui_out_emit_list list_emitter (uiout, "groups"); - for (ix_items = 0; - VEC_iterate (osdata_item_s, data->items, - ix_items, item); - ix_items++) + for (const osdata_item &item : data->items) { - const char *pid = get_osdata_column (item, "pid"); - const char *cmd = get_osdata_column (item, "command"); - const char *user = get_osdata_column (item, "user"); - const char *cores = get_osdata_column (item, "cores"); + const std::string *pid = get_osdata_column (item, "pid"); + const std::string *cmd = get_osdata_column (item, "command"); + const std::string *user = get_osdata_column (item, "user"); + const std::string *cores = get_osdata_column (item, "cores"); - int pid_i = strtoul (pid, NULL, 0); + int pid_i = strtoul (pid->c_str (), NULL, 0); /* At present, the target will return all available processes and if information about specific ones was required, we filter undesired processes here. */ - if (!ids.empty () && ids.find (pid_i) != ids.end ()) + if (!ids.empty () && ids.find (pid_i) == ids.end ()) continue; ui_out_emit_tuple tuple_emitter (uiout, NULL); - uiout->field_fmt ("id", "%s", pid); + uiout->field_fmt ("id", "%s", pid->c_str ()); uiout->field_string ("type", "process"); if (cmd) - uiout->field_string ("description", cmd); + uiout->field_string ("description", cmd->c_str ()); if (user) - uiout->field_string ("user", user); + uiout->field_string ("user", user->c_str ()); if (cores) - output_cores (uiout, "cores", cores); + output_cores (uiout, "cores", cores->c_str ()); if (recurse) { - splay_tree_node n = splay_tree_lookup (tree, pid_i); - if (n) + auto n = tree.find (pid_i); + if (n != tree.end ()) { - VEC (osdata_item_s) *children = (VEC (osdata_item_s) *) n->value; - struct osdata_item *child; - int ix_child; + std::vector &children = n->second; ui_out_emit_list thread_list_emitter (uiout, "threads"); - for (ix_child = 0; - VEC_iterate (osdata_item_s, children, ix_child, child); - ++ix_child) + for (const osdata_item &child : children) { - ui_out_emit_tuple tuple_emitter (uiout, NULL); - const char *tid = get_osdata_column (child, "tid"); - const char *tcore = get_osdata_column (child, "core"); + ui_out_emit_tuple inner_tuple_emitter (uiout, NULL); + const std::string *tid = get_osdata_column (child, "tid"); + const std::string *tcore = get_osdata_column (child, "core"); - uiout->field_string ("id", tid); + uiout->field_string ("id", tid->c_str ()); if (tcore) - uiout->field_string ("core", tcore); + uiout->field_string ("core", tcore->c_str ()); } } } } - - do_cleanups (cleanup); } void @@ -954,7 +888,7 @@ mi_cmd_data_list_register_names (const char *command, char **argv, int argc) debugged. */ gdbarch = get_current_arch (); - numregs = gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch); + numregs = gdbarch_num_cooked_regs (gdbarch); ui_out_emit_list list_emitter (uiout, "register-names"); @@ -990,11 +924,11 @@ mi_cmd_data_list_register_names (const char *command, char **argv, int argc) void mi_cmd_data_list_changed_registers (const char *command, char **argv, int argc) { - static std::unique_ptr this_regs; + static std::unique_ptr this_regs; struct ui_out *uiout = current_uiout; - std::unique_ptr prev_regs; + std::unique_ptr prev_regs; struct gdbarch *gdbarch; - int regnum, numregs, changed; + int regnum, numregs; int i; /* The last time we visited this function, the current frame's @@ -1012,8 +946,8 @@ mi_cmd_data_list_changed_registers (const char *command, char **argv, int argc) will change depending upon the particular processor being debugged. */ - gdbarch = get_regcache_arch (this_regs.get ()); - numregs = gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch); + gdbarch = this_regs->arch (); + numregs = gdbarch_num_cooked_regs (gdbarch); ui_out_emit_list list_emitter (uiout, "changed-registers"); @@ -1027,12 +961,9 @@ mi_cmd_data_list_changed_registers (const char *command, char **argv, int argc) if (gdbarch_register_name (gdbarch, regnum) == NULL || *(gdbarch_register_name (gdbarch, regnum)) == '\0') continue; - changed = register_changed_p (regnum, prev_regs.get (), - this_regs.get ()); - if (changed < 0) - error (_("-data-list-changed-registers: " - "Unable to read register contents.")); - else if (changed) + + if (register_changed_p (regnum, prev_regs.get (), + this_regs.get ())) uiout->field_int (NULL, regnum); } } @@ -1047,12 +978,8 @@ mi_cmd_data_list_changed_registers (const char *command, char **argv, int argc) && gdbarch_register_name (gdbarch, regnum) != NULL && *gdbarch_register_name (gdbarch, regnum) != '\000') { - changed = register_changed_p (regnum, prev_regs.get (), - this_regs.get ()); - if (changed < 0) - error (_("-data-list-changed-registers: " - "Unable to read register contents.")); - else if (changed) + if (register_changed_p (regnum, prev_regs.get (), + this_regs.get ())) uiout->field_int (NULL, regnum); } else @@ -1060,18 +987,17 @@ mi_cmd_data_list_changed_registers (const char *command, char **argv, int argc) } } -static int -register_changed_p (int regnum, struct regcache *prev_regs, - struct regcache *this_regs) +static bool +register_changed_p (int regnum, readonly_detached_regcache *prev_regs, + readonly_detached_regcache *this_regs) { - struct gdbarch *gdbarch = get_regcache_arch (this_regs); + struct gdbarch *gdbarch = this_regs->arch (); struct value *prev_value, *this_value; - int ret; /* First time through or after gdbarch change consider all registers as changed. */ - if (!prev_regs || get_regcache_arch (prev_regs) != gdbarch) - return 1; + if (!prev_regs || prev_regs->arch () != gdbarch) + return true; /* Get register contents and compare. */ prev_value = prev_regs->cooked_read_value (regnum); @@ -1079,13 +1005,11 @@ register_changed_p (int regnum, struct regcache *prev_regs, gdb_assert (prev_value != NULL); gdb_assert (this_value != NULL); - ret = value_contents_eq (prev_value, 0, this_value, 0, - register_size (gdbarch, regnum)) == 0; + auto ret = !value_contents_eq (prev_value, 0, this_value, 0, + register_size (gdbarch, regnum)); release_value (prev_value); release_value (this_value); - value_free (prev_value); - value_free (this_value); return ret; } @@ -1150,7 +1074,7 @@ mi_cmd_data_list_register_values (const char *command, char **argv, int argc) frame = get_selected_frame (NULL); gdbarch = get_frame_arch (frame); - numregs = gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch); + numregs = gdbarch_num_cooked_regs (gdbarch); ui_out_emit_list list_emitter (uiout, "register-values"); @@ -1237,8 +1161,8 @@ mi_cmd_data_write_register_values (const char *command, char **argv, int argc) debugged. */ regcache = get_current_regcache (); - gdbarch = get_regcache_arch (regcache); - numregs = gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch); + gdbarch = regcache->arch (); + numregs = gdbarch_num_cooked_regs (gdbarch); if (argc == 0) error (_("-data-write-register-values: Usage: -data-write-register-" @@ -1422,11 +1346,8 @@ mi_cmd_data_read_memory (const char *command, char **argv, int argc) gdb::byte_vector mbuf (total_bytes); - /* Dispatch memory reads to the topmost target, not the flattened - current_target. */ - nr_bytes = target_read (current_target.beneath, - TARGET_OBJECT_MEMORY, NULL, mbuf.data (), - addr, total_bytes); + nr_bytes = target_read (current_top_target (), TARGET_OBJECT_MEMORY, NULL, + mbuf.data (), addr, total_bytes); if (nr_bytes <= 0) error (_("Unable to read memory.")); @@ -1453,7 +1374,7 @@ mi_cmd_data_read_memory (const char *command, char **argv, int argc) { int col; int col_byte; - struct value_print_options opts; + struct value_print_options print_opts; ui_out_emit_tuple tuple_emitter (uiout, NULL); uiout->field_core_addr ("addr", gdbarch, addr + row_byte); @@ -1461,7 +1382,7 @@ mi_cmd_data_read_memory (const char *command, char **argv, int argc) row_byte); */ { ui_out_emit_list list_data_emitter (uiout, "data"); - get_formatted_print_options (&opts, word_format); + get_formatted_print_options (&print_opts, word_format); for (col = 0, col_byte = row_byte; col < nr_cols; col++, col_byte += word_size) @@ -1473,8 +1394,8 @@ mi_cmd_data_read_memory (const char *command, char **argv, int argc) else { stream.clear (); - print_scalar_formatted (&mbuf[col_byte], word_type, &opts, - word_asize, &stream); + print_scalar_formatted (&mbuf[col_byte], word_type, + &print_opts, word_asize, &stream); uiout->field_stream (NULL, stream); } } @@ -1545,7 +1466,7 @@ mi_cmd_data_read_memory_bytes (const char *command, char **argv, int argc) length = atol (argv[1]); std::vector result - = read_memory_robust (current_target.beneath, addr, length); + = read_memory_robust (current_top_target (), addr, length); if (result.size () == 0) error (_("Unable to read memory.")); @@ -1760,6 +1681,7 @@ mi_cmd_list_features (const char *command, char **argv, int argc) uiout->field_string (NULL, "info-gdb-mi-command"); uiout->field_string (NULL, "undefined-command-error-code"); uiout->field_string (NULL, "exec-run-start-option"); + uiout->field_string (NULL, "data-disassemble-a-option"); if (ext_lang_initialized_p (get_ext_lang_defn (EXT_LANG_PYTHON))) uiout->field_string (NULL, "python"); @@ -1843,8 +1765,11 @@ mi_cmd_remove_inferior (const char *command, char **argv, int argc) set_current_inferior (new_inferior); if (new_inferior->pid != 0) - tp = any_thread_of_process (new_inferior->pid); - switch_to_thread (tp ? tp->ptid : null_ptid); + tp = any_thread_of_inferior (new_inferior); + if (tp != NULL) + switch_to_thread (tp); + else + switch_to_no_thread (); set_current_program_space (new_inferior->pspace); } @@ -1950,7 +1875,7 @@ captured_mi_execute_command (struct ui_out *uiout, struct mi_parse *context) /* Print a gdb exception to the MI output stream. */ static void -mi_print_exception (const char *token, struct gdb_exception exception) +mi_print_exception (const char *token, const struct gdb_exception &exception) { struct mi_interp *mi = (struct mi_interp *) current_interpreter (); @@ -1959,7 +1884,7 @@ mi_print_exception (const char *token, struct gdb_exception exception) if (exception.message == NULL) fputs_unfiltered ("unknown error", mi->raw_stdout); else - fputstr_unfiltered (exception.message, '"', mi->raw_stdout); + fputstr_unfiltered (exception.what (), '"', mi->raw_stdout); fputs_unfiltered ("\"", mi->raw_stdout); switch (exception.error) @@ -2013,16 +1938,15 @@ mi_execute_command (const char *cmd, int from_tty) target_log_command (cmd); - TRY + try { command = mi_parse (cmd, &token); } - CATCH (exception, RETURN_MASK_ALL) + catch (const gdb_exception &exception) { mi_print_exception (token, exception); xfree (token); } - END_CATCH if (command != NULL) { @@ -2041,11 +1965,11 @@ mi_execute_command (const char *cmd, int from_tty) timestamp (command->cmd_start); } - TRY + try { captured_mi_execute_command (current_uiout, command.get ()); } - CATCH (result, RETURN_MASK_ALL) + catch (const gdb_exception &result) { /* Like in start_event_loop, enable input and force display of the prompt. Otherwise, any command that calls @@ -2059,30 +1983,28 @@ mi_execute_command (const char *cmd, int from_tty) mi_print_exception (command->token, result); mi_out_rewind (current_uiout); } - END_CATCH bpstat_do_actions (); if (/* The notifications are only output when the top-level interpreter (specified on the command line) is MI. */ - interp_ui_out (top_level_interpreter ())->is_mi_like_p () + top_level_interpreter ()->interp_ui_out ()->is_mi_like_p () /* Don't try report anything if there are no threads -- the program is dead. */ - && thread_count () != 0 + && any_thread_p () /* If the command already reports the thread change, no need to do it again. */ && !command_notifies_uscc_observer (command.get ())) { - struct mi_interp *mi = (struct mi_interp *) top_level_interpreter (); int report_change = 0; if (command->thread == -1) { - report_change = (!ptid_equal (previous_ptid, null_ptid) - && !ptid_equal (inferior_ptid, previous_ptid) - && !ptid_equal (inferior_ptid, null_ptid)); + report_change = (previous_ptid != null_ptid + && inferior_ptid != previous_ptid + && inferior_ptid != null_ptid); } - else if (!ptid_equal (inferior_ptid, null_ptid)) + else if (inferior_ptid != null_ptid) { struct thread_info *ti = inferior_thread (); @@ -2091,8 +2013,8 @@ mi_execute_command (const char *cmd, int from_tty) if (report_change) { - observer_notify_user_selected_context_changed - (USER_SELECTED_THREAD | USER_SELECTED_FRAME); + gdb::observers::user_selected_context_changed.notify + (USER_SELECTED_THREAD | USER_SELECTED_FRAME); } } } @@ -2101,9 +2023,7 @@ mi_execute_command (const char *cmd, int from_tty) static void mi_cmd_execute (struct mi_parse *parse) { - struct cleanup *cleanup; - - cleanup = prepare_execute_command (); + scoped_value_mark cleanup = prepare_execute_command (); if (parse->all && parse->thread_group != -1) error (_("Cannot specify --thread-group together with --all")); @@ -2132,22 +2052,25 @@ mi_cmd_execute (struct mi_parse *parse) provide --thread if it wishes to operate on a specific thread. */ if (inf->pid != 0) - tp = any_live_thread_of_process (inf->pid); - switch_to_thread (tp ? tp->ptid : null_ptid); + tp = any_live_thread_of_inferior (inf); + if (tp != NULL) + switch_to_thread (tp); + else + switch_to_no_thread (); set_current_program_space (inf->pspace); } if (parse->thread != -1) { - struct thread_info *tp = find_thread_global_id (parse->thread); + thread_info *tp = find_thread_global_id (parse->thread); - if (!tp) + if (tp == NULL) error (_("Invalid thread id: %d"), parse->thread); - if (is_exited (tp->ptid)) + if (tp->state == THREAD_EXITED) error (_("Thread id: %d has terminated"), parse->thread); - switch_to_thread (tp->ptid); + switch_to_thread (tp); } if (parse->frame != -1) @@ -2195,7 +2118,6 @@ mi_cmd_execute (struct mi_parse *parse) error_stream (stb); } - do_cleanups (cleanup); } /* FIXME: This is just a hack so we can get some extra commands going. @@ -2215,7 +2137,7 @@ mi_execute_cli_command (const char *cmd, int args_p, const char *args) /* FIXME: gdb_???? */ fprintf_unfiltered (gdb_stdout, "cli=%s run=%s\n", cmd, run.c_str ()); - execute_command (&run[0], 0 /* from_tty */ ); + execute_command (run.c_str (), 0 /* from_tty */ ); } } @@ -2229,7 +2151,7 @@ mi_execute_async_cli_command (const char *cli_command, char **argv, int argc) if (mi_async_p ()) run += "&"; - execute_command (&run[0], 0 /* from_tty */ ); + execute_command (run.c_str (), 0 /* from_tty */ ); } void @@ -2249,16 +2171,8 @@ mi_load_progress (const char *section_name, which means uiout may not be correct. Fix it for the duration of this function. */ - std::unique_ptr uiout; - - if (current_interp_named_p (INTERP_MI) - || current_interp_named_p (INTERP_MI2)) - uiout.reset (mi_out_new (2)); - else if (current_interp_named_p (INTERP_MI1)) - uiout.reset (mi_out_new (1)); - else if (current_interp_named_p (INTERP_MI3)) - uiout.reset (mi_out_new (3)); - else + std::unique_ptr uiout (mi_out_new (current_interpreter ()->name ())); + if (uiout == nullptr) return; scoped_restore save_uiout @@ -2643,6 +2557,7 @@ mi_cmd_trace_frame_collected (const char *command, char **argv, int argc) break; case REGISTERS_FORMAT: registers_format = oarg[0]; + break; case MEMORY_CONTENTS: memory_contents = 1; break; @@ -2675,8 +2590,6 @@ mi_cmd_trace_frame_collected (const char *command, char **argv, int argc) /* Explicitly wholly collected variables. */ { - int i; - ui_out_emit_list list_emitter (uiout, "explicit-variables"); const std::vector &wholly_collected = clist->wholly_collected (); @@ -2689,9 +2602,6 @@ mi_cmd_trace_frame_collected (const char *command, char **argv, int argc) /* Computed expressions. */ { - char *p; - int i; - ui_out_emit_list list_emitter (uiout, "computed-expressions"); const std::vector &computed = clist->computed (); @@ -2716,7 +2626,7 @@ mi_cmd_trace_frame_collected (const char *command, char **argv, int argc) frame = get_selected_frame (NULL); gdbarch = get_frame_arch (frame); - numregs = gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch); + numregs = gdbarch_num_cooked_regs (gdbarch); for (regnum = 0; regnum < numregs; regnum++) { @@ -2730,12 +2640,9 @@ mi_cmd_trace_frame_collected (const char *command, char **argv, int argc) /* Trace state variables. */ { - int tvar; - int i; - ui_out_emit_list list_emitter (uiout, "tvars"); - for (i = 0; VEC_iterate (int, tinfo->tvars, i, tvar); i++) + for (int tvar : tinfo->tvars) { struct trace_state_variable *tsv; @@ -2745,7 +2652,7 @@ mi_cmd_trace_frame_collected (const char *command, char **argv, int argc) if (tsv != NULL) { - uiout->field_fmt ("name", "$%s", tsv->name); + uiout->field_fmt ("name", "$%s", tsv->name.c_str ()); tsv->value_known = target_get_trace_state_variable_value (tsv->number, &tsv->value); @@ -2761,43 +2668,91 @@ mi_cmd_trace_frame_collected (const char *command, char **argv, int argc) /* Memory. */ { - struct cleanup *cleanups; - VEC(mem_range_s) *available_memory = NULL; - struct mem_range *r; - int i; + std::vector available_memory; traceframe_available_memory (&available_memory, 0, ULONGEST_MAX); - cleanups = make_cleanup (VEC_cleanup(mem_range_s), &available_memory); ui_out_emit_list list_emitter (uiout, "memory"); - for (i = 0; VEC_iterate (mem_range_s, available_memory, i, r); i++) + for (const mem_range &r : available_memory) { struct gdbarch *gdbarch = target_gdbarch (); ui_out_emit_tuple tuple_emitter (uiout, NULL); - uiout->field_core_addr ("address", gdbarch, r->start); - uiout->field_int ("length", r->length); + uiout->field_core_addr ("address", gdbarch, r.start); + uiout->field_int ("length", r.length); - gdb::byte_vector data (r->length); + gdb::byte_vector data (r.length); if (memory_contents) { - if (target_read_memory (r->start, data.data (), r->length) == 0) + if (target_read_memory (r.start, data.data (), r.length) == 0) { - std::string data_str = bin2hex (data.data (), r->length); + std::string data_str = bin2hex (data.data (), r.length); uiout->field_string ("contents", data_str.c_str ()); } else uiout->field_skip ("contents"); } } + } +} + +/* See mi/mi-main.h. */ - do_cleanups (cleanups); +void +mi_cmd_fix_multi_location_breakpoint_output (const char *command, char **argv, + int argc) +{ + fix_multi_location_breakpoint_output_globally = true; +} + +/* Implement the "-complete" command. */ + +void +mi_cmd_complete (const char *command, char **argv, int argc) +{ + if (argc != 1) + error (_("Usage: -complete COMMAND")); + + if (max_completions == 0) + error (_("max-completions is zero, completion is disabled.")); + + int quote_char = '\0'; + const char *word; + + completion_result result = complete (argv[0], &word, "e_char); + + std::string arg_prefix (argv[0], word - argv[0]); + + struct ui_out *uiout = current_uiout; + + if (result.number_matches > 0) + uiout->field_fmt ("completion", "%s%s", + arg_prefix.c_str (),result.match_list[0]); + + { + ui_out_emit_list completions_emitter (uiout, "matches"); + + if (result.number_matches == 1) + uiout->field_fmt (NULL, "%s%s", + arg_prefix.c_str (), result.match_list[0]); + else + { + result.sort_match_list (); + for (size_t i = 0; i < result.number_matches; i++) + { + uiout->field_fmt (NULL, "%s%s", + arg_prefix.c_str (), result.match_list[i + 1]); + } + } } + uiout->field_string ("max_completions_reached", + result.number_matches == max_completions ? "1" : "0"); } + void _initialize_mi_main (void) {