X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fmi%2Fmi-main.c;h=24daf3f883883433856cd0a0ab67e81abad37252;hb=db2d40f7d0b8477ca5ad9e305b8137a085434c97;hp=9c4e44ba6b482b0ec2ba7c803f6904890b243526;hpb=76727919ceb590f03ff0f6db08b7ceab5b7aeaff;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c index 9c4e44ba6b..24daf3f883 100644 --- a/gdb/mi/mi-main.c +++ b/gdb/mi/mi-main.c @@ -1,6 +1,6 @@ /* MI Command Set. - Copyright (C) 2000-2018 Free Software Foundation, Inc. + Copyright (C) 2000-2020 Free Software Foundation, Inc. Contributed by Cygnus Solutions (a Red Hat company). @@ -43,24 +43,22 @@ #include "mi-common.h" #include "language.h" #include "valprint.h" -#include "inferior.h" #include "osdata.h" -#include "common/gdb_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 "observable.h" -#include "common/gdb_optional.h" -#include "common/byte-vector.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 @@ -102,11 +100,11 @@ static void output_register (struct frame_info *, int regnum, int format, int skip_unavailable); /* Controls whether the frontend wants MI in async mode. */ -static int mi_async = 0; +static bool mi_async = false; /* The set command writes to this variable. If the inferior is executing, mi_async is *not* updated. */ -static int mi_async_1 = 0; +static bool mi_async_1 = false; static void set_mi_async_command (const char *args, int from_tty, @@ -243,13 +241,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 +264,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 +343,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,27 +403,18 @@ 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); - set_current_program_space (inf->pspace); - } + switch_to_inferior_no_thread (inf); mi_execute_cli_command (run_cmd, async_p, async_p ? "&" : NULL); return 0; @@ -479,7 +468,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 +481,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 +529,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); @@ -571,7 +560,7 @@ mi_cmd_thread_select (const char *command, char **argv, int argc) 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) { gdb::observers::user_selected_context_changed.notify (USER_SELECTED_THREAD | USER_SELECTED_FRAME); @@ -592,20 +581,19 @@ mi_cmd_thread_list_ids (const char *command, char **argv, int argc) { ui_out_emit_tuple tuple_emitter (current_uiout, "thread-ids"); - struct thread_info *tp; - ALL_NON_EXITED_THREADS (tp) + 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); + current_uiout->field_signed ("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); + current_uiout->field_signed ("current-thread-id", current_thread); + current_uiout->field_signed ("number-of-threads", num); } void @@ -628,7 +616,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); @@ -665,7 +653,7 @@ print_one_inferior (struct inferior *inferior, void *xdata) uiout->field_string ("exit-code", int_string (inferior->exit_code, 8, 0, 0, 1)); if (inferior->pid != 0) - uiout->field_int ("pid", inferior->pid); + uiout->field_signed ("pid", inferior->pid); if (inferior->pspace->pspace_exec_filename != NULL) { @@ -684,7 +672,7 @@ print_one_inferior (struct inferior *inferior, void *xdata) ui_out_emit_list list_emitter (uiout, "cores"); for (int b : data.cores) - uiout->field_int (NULL, b); + uiout->field_signed (NULL, b); } if (top_data->recurse) @@ -702,10 +690,11 @@ 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 (); + char *saveptr; - for (p = strtok (p, ","); p; p = strtok (NULL, ",")) + for (p = strtok_r (p, ",", &saveptr); p; p = strtok_r (NULL, ",", &saveptr)) uiout->field_string (NULL, p); } @@ -753,7 +742,7 @@ list_available_thread_groups (const std::set &ids, int recurse) ui_out_emit_tuple tuple_emitter (uiout, NULL); - uiout->field_fmt ("id", "%s", pid->c_str ()); + uiout->field_string ("id", pid->c_str ()); uiout->field_string ("type", "process"); if (cmd) uiout->field_string ("description", cmd->c_str ()); @@ -773,7 +762,7 @@ list_available_thread_groups (const std::set &ids, int recurse) for (const osdata_item &child : children) { - ui_out_emit_tuple tuple_emitter (uiout, NULL); + 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"); @@ -895,7 +884,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"); @@ -954,7 +943,7 @@ mi_cmd_data_list_changed_registers (const char *command, char **argv, int argc) debugged. */ gdbarch = this_regs->arch (); - numregs = gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch); + numregs = gdbarch_num_cooked_regs (gdbarch); ui_out_emit_list list_emitter (uiout, "changed-registers"); @@ -971,7 +960,7 @@ mi_cmd_data_list_changed_registers (const char *command, char **argv, int argc) if (register_changed_p (regnum, prev_regs.get (), this_regs.get ())) - uiout->field_int (NULL, regnum); + uiout->field_signed (NULL, regnum); } } @@ -987,7 +976,7 @@ mi_cmd_data_list_changed_registers (const char *command, char **argv, int argc) { if (register_changed_p (regnum, prev_regs.get (), this_regs.get ())) - uiout->field_int (NULL, regnum); + uiout->field_signed (NULL, regnum); } else error (_("bad register number")); @@ -1017,8 +1006,6 @@ register_changed_p (int regnum, readonly_detached_regcache *prev_regs, release_value (prev_value); release_value (this_value); - value_free (prev_value); - value_free (this_value); return ret; } @@ -1083,7 +1070,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"); @@ -1133,7 +1120,7 @@ output_register (struct frame_info *frame, int regnum, int format, return; ui_out_emit_tuple tuple_emitter (uiout, NULL); - uiout->field_int ("number", regnum); + uiout->field_signed ("number", regnum); if (format == 'N') format = 0; @@ -1171,7 +1158,7 @@ mi_cmd_data_write_register_values (const char *command, char **argv, int argc) regcache = get_current_regcache (); gdbarch = regcache->arch (); - numregs = gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch); + numregs = gdbarch_num_cooked_regs (gdbarch); if (argc == 0) error (_("-data-write-register-values: Usage: -data-write-register-" @@ -1244,12 +1231,12 @@ mi_cmd_data_evaluate_expression (const char *command, char **argv, int argc) the ``x'' command. WORD-SIZE: size of each ``word''; 1,2,4, or 8 bytes. NR_ROW: Number of rows. - NR_COL: The number of colums (words per row). + NR_COL: The number of columns (words per row). ASCHAR: (OPTIONAL) Append an ascii character dump to each row. Use ASCHAR for unprintable characters. Reads SIZE*NR_ROW*NR_COL bytes starting at ADDR from memory and - displayes them. Returns: + displays them. Returns: {addr="...",rowN={wordN="..." ,... [,ascii="..."]}, ...} @@ -1355,24 +1342,21 @@ 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.")); /* Output the header information. */ uiout->field_core_addr ("addr", gdbarch, addr); - uiout->field_int ("nr-bytes", nr_bytes); - uiout->field_int ("total-bytes", total_bytes); + uiout->field_signed ("nr-bytes", nr_bytes); + uiout->field_signed ("total-bytes", total_bytes); uiout->field_core_addr ("next-row", gdbarch, addr + word_size * nr_cols); uiout->field_core_addr ("prev-row", gdbarch, addr - word_size * nr_cols); uiout->field_core_addr ("next-page", gdbarch, addr + total_bytes); uiout->field_core_addr ("prev-page", gdbarch, addr - total_bytes); - /* Build the result as a two dimentional table. */ + /* Build the result as a two dimensional table. */ { int row; int row_byte; @@ -1386,7 +1370,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); @@ -1394,7 +1378,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) @@ -1406,8 +1390,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); } } @@ -1478,7 +1462,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.")); @@ -1693,6 +1677,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"); @@ -1776,8 +1761,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); } @@ -1883,7 +1871,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 (); @@ -1892,7 +1880,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) @@ -1946,16 +1934,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) { @@ -1974,11 +1961,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 @@ -1992,30 +1979,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 (); @@ -2063,22 +2048,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) @@ -2179,16 +2167,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 @@ -2207,8 +2187,8 @@ mi_load_progress (const char *section_name, { ui_out_emit_tuple tuple_emitter (uiout.get (), NULL); uiout->field_string ("section", section_name); - uiout->field_int ("section-size", total_section); - uiout->field_int ("total-size", grand_total); + uiout->field_signed ("section-size", total_section); + uiout->field_signed ("total-size", grand_total); } mi_out_put (uiout.get (), mi->raw_stdout); fputs_unfiltered ("\n", mi->raw_stdout); @@ -2225,10 +2205,10 @@ mi_load_progress (const char *section_name, { ui_out_emit_tuple tuple_emitter (uiout.get (), NULL); uiout->field_string ("section", section_name); - uiout->field_int ("section-sent", sent_so_far); - uiout->field_int ("section-size", total_section); - uiout->field_int ("total-sent", total_sent); - uiout->field_int ("total-size", grand_total); + uiout->field_signed ("section-sent", sent_so_far); + uiout->field_signed ("section-size", total_section); + uiout->field_signed ("total-sent", total_sent); + uiout->field_signed ("total-size", grand_total); } mi_out_put (uiout.get (), mi->raw_stdout); fputs_unfiltered ("\n", mi->raw_stdout); @@ -2573,6 +2553,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; @@ -2641,7 +2622,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++) { @@ -2667,11 +2648,11 @@ 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); - uiout->field_int ("current", tsv->value); + uiout->field_signed ("current", tsv->value); } else { @@ -2696,7 +2677,7 @@ mi_cmd_trace_frame_collected (const char *command, char **argv, int argc) ui_out_emit_tuple tuple_emitter (uiout, NULL); uiout->field_core_addr ("address", gdbarch, r.start); - uiout->field_int ("length", r.length); + uiout->field_signed ("length", r.length); gdb::byte_vector data (r.length); @@ -2714,6 +2695,60 @@ mi_cmd_trace_frame_collected (const char *command, char **argv, int argc) } } +/* See mi/mi-main.h. */ + +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) {