2008-10-17 21:43:47 +02:00
|
|
|
/* Reverse execution and reverse debugging.
|
|
|
|
|
2017-01-01 07:50:51 +01:00
|
|
|
Copyright (C) 2006-2017 Free Software Foundation, Inc.
|
2008-10-17 21:43:47 +02:00
|
|
|
|
|
|
|
This file is part of GDB.
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
2009-03-18 09:51:11 +01:00
|
|
|
the Free Software Foundation; either version 3 of the License, or
|
2008-10-17 21:43:47 +02:00
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
2009-03-18 09:51:11 +01:00
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
2008-10-17 21:43:47 +02:00
|
|
|
|
|
|
|
#include "defs.h"
|
|
|
|
#include "target.h"
|
|
|
|
#include "top.h"
|
|
|
|
#include "cli/cli-cmds.h"
|
|
|
|
#include "cli/cli-decode.h"
|
2011-02-21 19:13:17 +01:00
|
|
|
#include "cli/cli-utils.h"
|
2008-10-17 21:43:47 +02:00
|
|
|
#include "inferior.h"
|
Add new infrun.h header.
Move infrun.c declarations out of inferior.h to a new infrun.h file.
Tested by building on:
i686-w64-mingw32, enable-targets=all
x86_64-linux, enable-targets=all
i586-pc-msdosdjgpp
And also grepped the whole tree for each symbol moved to find where
infrun.h might be necessary.
gdb/
2014-05-22 Pedro Alves <palves@redhat.com>
* inferior.h (debug_infrun, debug_displaced, stop_on_solib_events)
(sync_execution, sched_multi, step_stop_if_no_debug, non_stop)
(disable_randomization, enum exec_direction_kind)
(execution_direction, stop_registers, start_remote)
(clear_proceed_status, proceed, resume, user_visible_resume_ptid)
(wait_for_inferior, normal_stop, get_last_target_status)
(prepare_for_detach, fetch_inferior_event, init_wait_for_inferior)
(insert_step_resume_breakpoint_at_sal)
(follow_inferior_reset_breakpoints, stepping_past_instruction_at)
(set_step_info, print_stop_event, signal_stop_state)
(signal_print_state, signal_pass_state, signal_stop_update)
(signal_print_update, signal_pass_update)
(update_signals_program_target, clear_exit_convenience_vars)
(displaced_step_dump_bytes, update_observer_mode)
(signal_catch_update, gdb_signal_from_command): Move
declarations ...
* infrun.h: ... to this new file.
* amd64-tdep.c: Include infrun.h.
* annotate.c: Include infrun.h.
* arch-utils.c: Include infrun.h.
* arm-linux-tdep.c: Include infrun.h.
* arm-tdep.c: Include infrun.h.
* break-catch-sig.c: Include infrun.h.
* breakpoint.c: Include infrun.h.
* common/agent.c: Include infrun.h instead of inferior.h.
* corelow.c: Include infrun.h.
* event-top.c: Include infrun.h.
* go32-nat.c: Include infrun.h.
* i386-tdep.c: Include infrun.h.
* inf-loop.c: Include infrun.h.
* infcall.c: Include infrun.h.
* infcmd.c: Include infrun.h.
* infrun.c: Include infrun.h.
* linux-fork.c: Include infrun.h.
* linux-nat.c: Include infrun.h.
* linux-thread-db.c: Include infrun.h.
* monitor.c: Include infrun.h.
* nto-tdep.c: Include infrun.h.
* procfs.c: Include infrun.h.
* record-btrace.c: Include infrun.h.
* record-full.c: Include infrun.h.
* remote-m32r-sdi.c: Include infrun.h.
* remote-mips.c: Include infrun.h.
* remote-notif.c: Include infrun.h.
* remote-sim.c: Include infrun.h.
* remote.c: Include infrun.h.
* reverse.c: Include infrun.h.
* rs6000-tdep.c: Include infrun.h.
* s390-linux-tdep.c: Include infrun.h.
* solib-irix.c: Include infrun.h.
* solib-osf.c: Include infrun.h.
* solib-svr4.c: Include infrun.h.
* target.c: Include infrun.h.
* top.c: Include infrun.h.
* windows-nat.c: Include infrun.h.
* mi/mi-interp.c: Include infrun.h.
* mi/mi-main.c: Include infrun.h.
* python/py-threadevent.c: Include infrun.h.
2014-05-22 13:29:11 +02:00
|
|
|
#include "infrun.h"
|
2009-11-20 18:23:38 +01:00
|
|
|
#include "regcache.h"
|
2008-10-17 21:43:47 +02:00
|
|
|
|
|
|
|
/* User interface:
|
|
|
|
reverse-step, reverse-next etc. */
|
|
|
|
|
|
|
|
/* exec_reverse_once -- accepts an arbitrary gdb command (string),
|
|
|
|
and executes it with exec-direction set to 'reverse'.
|
|
|
|
|
|
|
|
Used to implement reverse-next etc. commands. */
|
|
|
|
|
|
|
|
static void
|
-Wwrite-strings: The Rest
This is the remainder boring constification that all looks more of less
borderline obvious IMO.
gdb/ChangeLog:
2017-04-05 Pedro Alves <palves@redhat.com>
* ada-exp.y (yyerror): Constify.
* ada-lang.c (bound_name, get_selections)
(ada_variant_discrim_type)
(ada_variant_discrim_name, ada_value_struct_elt)
(ada_lookup_struct_elt_type, is_unchecked_variant)
(ada_which_variant_applies, standard_exc, ada_get_next_arg)
(catch_ada_exception_command_split)
(catch_ada_assert_command_split, catch_assert_command)
(ada_op_name): Constify.
* ada-lang.h (ada_yyerror, get_selections)
(ada_variant_discrim_name, ada_value_struct_elt): Constify.
* arc-tdep.c (arc_print_frame_cache): Constify.
* arm-tdep.c (arm_skip_stub): Constify.
* ax-gdb.c (gen_binop, gen_struct_ref_recursive, gen_struct_ref)
(gen_aggregate_elt_ref): Constify.
* bcache.c (print_bcache_statistics): Constify.
* bcache.h (print_bcache_statistics): Constify.
* break-catch-throw.c (catch_exception_command_1):
* breakpoint.c (struct ep_type_description::description):
Constify.
(add_solib_catchpoint): Constify.
(catch_fork_command_1): Add cast.
(add_catch_command): Constify.
* breakpoint.h (add_catch_command, add_solib_catchpoint):
Constify.
* bsd-uthread.c (bsd_uthread_state): Constify.
* buildsym.c (patch_subfile_names): Constify.
* buildsym.h (next_symbol_text_func, patch_subfile_names):
Constify.
* c-exp.y (yyerror): Constify.
(token::oper): Constify.
* c-lang.h (c_yyerror, cp_print_class_member): Constify.
* c-varobj.c (cplus_describe_child): Constify.
* charset.c (find_charset_names): Add cast.
(find_charset_names): Constify array and add const_cast.
* cli/cli-cmds.c (complete_command, cd_command): Constify.
(edit_command): Constify.
* cli/cli-decode.c (lookup_cmd): Constify.
* cli/cli-dump.c (dump_memory_command, dump_value_command):
Constify.
(struct dump_context): Constify.
(add_dump_command, restore_command): Constify.
* cli/cli-script.c (get_command_line): Constify.
* cli/cli-script.h (get_command_line): Constify.
* cli/cli-utils.c (check_for_argument): Constify.
* cli/cli-utils.h (check_for_argument): Constify.
* coff-pe-read.c (struct read_pe_section_data): Constify.
* command.h (lookup_cmd): Constify.
* common/print-utils.c (decimal2str): Constify.
* completer.c (gdb_print_filename): Constify.
* corefile.c (set_gnutarget): Constify.
* cp-name-parser.y (yyerror): Constify.
* cp-valprint.c (cp_print_class_member): Constify.
* cris-tdep.c (cris_register_name, crisv32_register_name):
Constify.
* d-exp.y (yyerror): Constify.
(struct token::oper): Constify.
* d-lang.h (d_yyerror): Constify.
* dbxread.c (struct header_file_location::name): Constify.
(add_old_header_file, add_new_header_file, last_function_name)
(dbx_next_symbol_text, add_bincl_to_list)
(find_corresponding_bincl_psymtab, set_namestring)
(find_stab_function_addr, read_dbx_symtab, start_psymtab)
(dbx_end_psymtab, read_ofile_symtab, process_one_symbol):
* defs.h (command_line_input, print_address_symbolic)
(deprecated_readline_begin_hook): Constify.
* dwarf2read.c (anonymous_struct_prefix, dwarf_bool_name):
Constify.
* event-top.c (handle_line_of_input): Constify and add cast.
* exceptions.c (catch_errors): Constify.
* exceptions.h (catch_errors): Constify.
* expprint.c (print_subexp_standard, op_string, op_name)
(op_name_standard, dump_raw_expression, dump_raw_expression):
* expression.h (op_name, op_string, dump_raw_expression):
Constify.
* f-exp.y (yyerror): Constify.
(struct token::oper): Constify.
(struct f77_boolean_val::name): Constify.
* f-lang.c (f_word_break_characters): Constify.
* f-lang.h (f_yyerror): Constify.
* fork-child.c (fork_inferior): Add cast.
* frv-tdep.c (struct gdbarch_tdep::register_names): Constify.
(new_variant): Constify.
* gdbarch.sh (pstring_ptr, pstring_list): Constify.
* gdbarch.c: Regenerate.
* gdbcore.h (set_gnutarget): Constify.
* go-exp.y (yyerror): Constify.
(token::oper): Constify.
* go-lang.h (go_yyerror): Constify.
* go32-nat.c (go32_sysinfo): Constify.
* guile/scm-breakpoint.c (gdbscm_breakpoint_expression): Constify.
* guile/scm-cmd.c (cmdscm_function): Constify.
* guile/scm-param.c (pascm_param_value): Constify.
* h8300-tdep.c (h8300_register_name, h8300s_register_name)
(h8300sx_register_name): Constify.
* hppa-tdep.c (hppa32_register_name, hppa64_register_name):
Constify.
* ia64-tdep.c (ia64_register_names): Constify.
* infcmd.c (construct_inferior_arguments): Constify.
(path_command, attach_post_wait): Constify.
* language.c (show_range_command, show_case_command)
(unk_lang_error): Constify.
* language.h (language_defn::la_error)
(language_defn::la_name_of_this): Constify.
* linespec.c (decode_line_2): Constify.
* linux-thread-db.c (thread_db_err_str): Constify.
* lm32-tdep.c (lm32_register_name): Constify.
* m2-exp.y (yyerror): Constify.
* m2-lang.h (m2_yyerror): Constify.
* m32r-tdep.c (m32r_register_names): Constify and make static.
* m68hc11-tdep.c (m68hc11_register_names): Constify.
* m88k-tdep.c (m88k_register_name): Constify.
* macroexp.c (appendmem): Constify.
* mdebugread.c (fdr_name, add_data_symbol, parse_type)
(upgrade_type, parse_external, parse_partial_symbols)
(mdebug_next_symbol_text, cross_ref, mylookup_symbol, new_psymtab)
(new_symbol): Constify.
* memattr.c (mem_info_command): Constify.
* mep-tdep.c (register_name_from_keyword): Constify.
* mi/mi-cmd-env.c (mi_cmd_env_path, _initialize_mi_cmd_env):
Constify.
* mi/mi-cmd-stack.c (list_args_or_locals): Constify.
* mi/mi-cmd-var.c (mi_cmd_var_show_attributes): Constify.
* mi/mi-main.c (captured_mi_execute_command): Constify and add
cast.
(mi_execute_async_cli_command): Constify.
* mips-tdep.c (mips_register_name): Constify.
* mn10300-tdep.c (register_name, mn10300_generic_register_name)
(am33_register_name, am33_2_register_name)
* moxie-tdep.c (moxie_register_names): Constify.
* nat/linux-osdata.c (osdata_type): Constify fields.
* nto-tdep.c (nto_parse_redirection): Constify.
* objc-lang.c (lookup_struct_typedef, lookup_objc_class)
(lookup_child_selector): Constify.
(objc_methcall::name): Constify.
* objc-lang.h (lookup_objc_class, lookup_child_selector)
(lookup_struct_typedef): Constify.
* objfiles.c (pc_in_section): Constify.
* objfiles.h (pc_in_section): Constify.
* p-exp.y (struct token::oper): Constify.
(yyerror): Constify.
* p-lang.h (pascal_yyerror): Constify.
* parser-defs.h (op_name_standard): Constify.
(op_print::string): Constify.
(exp_descriptor::op_name): Constify.
* printcmd.c (print_address_symbolic): Constify.
* psymtab.c (print_partial_symbols): Constify.
* python/py-breakpoint.c (stop_func): Constify.
(bppy_get_expression): Constify.
* python/py-cmd.c (cmdpy_completer::name): Constify.
(cmdpy_function): Constify.
* python/py-event.c (evpy_add_attribute)
(gdbpy_initialize_event_generic): Constify.
* python/py-event.h (evpy_add_attribute)
(gdbpy_initialize_event_generic): Constify.
* python/py-evts.c (add_new_registry): Constify.
* python/py-finishbreakpoint.c (outofscope_func): Constify.
* python/py-framefilter.c (get_py_iter_from_func): Constify.
* python/py-inferior.c (get_buffer): Add cast.
* python/py-param.c (parm_constant::name): Constify.
* python/py-unwind.c (fprint_frame_id): Constify.
* python/python.c (gdbpy_parameter_value): Constify.
* remote-fileio.c (remote_fio_func_map): Make 'name' const.
* remote.c (memory_packet_config::name): Constify.
(show_packet_config_cmd, remote_write_bytes)
(remote_buffer_add_string):
* reverse.c (exec_reverse_once): Constify.
* rs6000-tdep.c (variant::name, variant::description): Constify.
* rust-exp.y (rustyyerror): Constify.
* rust-lang.c (rust_op_name): Constify.
* rust-lang.h (rustyyerror): Constify.
* serial.h (serial_ops::name): Constify.
* sh-tdep.c (sh_sh_register_name, sh_sh3_register_name)
(sh_sh3e_register_name, sh_sh2e_register_name)
(sh_sh2a_register_name, sh_sh2a_nofpu_register_name)
(sh_sh_dsp_register_name, sh_sh3_dsp_register_name)
(sh_sh4_register_name, sh_sh4_nofpu_register_name)
(sh_sh4al_dsp_register_name): Constify.
* sh64-tdep.c (sh64_register_name): Constify.
* solib-darwin.c (lookup_symbol_from_bfd): Constify.
* spu-tdep.c (spu_register_name, info_spu_dma_cmdlist): Constify.
* stabsread.c (patch_block_stabs, read_type_number)
(ref_map::stabs, ref_add, process_reference)
(symbol_reference_defined, define_symbol, define_symbol)
(error_type, read_type, read_member_functions, read_cpp_abbrev)
(read_one_struct_field, read_struct_fields, read_baseclasses)
(read_tilde_fields, read_struct_type, read_array_type)
(read_enum_type, read_sun_builtin_type, read_sun_floating_type)
(read_huge_number, read_range_type, read_args, common_block_start)
(find_name_end): Constify.
* stabsread.h (common_block_start, define_symbol)
(process_one_symbol, symbol_reference_defined, ref_add):
* symfile.c (get_section_index, add_symbol_file_command):
* symfile.h (get_section_index): Constify.
* target-descriptions.c (tdesc_type::name): Constify.
(tdesc_free_type): Add cast.
* target.c (find_default_run_target):
(add_deprecated_target_alias, find_default_run_target)
(target_announce_detach): Constify.
(do_option): Constify.
* target.h (add_deprecated_target_alias): Constify.
* thread.c (print_thread_info_1): Constify.
* top.c (deprecated_readline_begin_hook, command_line_input):
Constify.
(init_main): Add casts.
* top.h (handle_line_of_input): Constify.
* tracefile-tfile.c (tfile_write_uploaded_tsv): Constify.
* tracepoint.c (tvariables_info_1, trace_status_mi): Constify.
(tfind_command): Rename to ...
(tfind_command_1): ... this and constify.
(tfind_command): New function.
(tfind_end_command, tfind_start_command): Adjust.
(encode_source_string): Constify.
* tracepoint.h (encode_source_string): Constify.
* tui/tui-data.c (tui_partial_win_by_name): Constify.
* tui/tui-data.h (tui_partial_win_by_name): Constify.
* tui/tui-source.c (tui_set_source_content_nil): Constify.
* tui/tui-source.h (tui_set_source_content_nil): Constify.
* tui/tui-win.c (parse_scrolling_args): Constify.
* tui/tui-windata.c (tui_erase_data_content): Constify.
* tui/tui-windata.h (tui_erase_data_content): Constify.
* tui/tui-winsource.c (tui_erase_source_content): Constify.
* tui/tui.c (tui_enable): Add cast.
* utils.c (defaulted_query): Constify.
(init_page_info): Add cast.
(puts_debug, subset_compare): Constify.
* utils.h (subset_compare): Constify.
* varobj.c (varobj_format_string): Constify.
* varobj.h (varobj_format_string): Constify.
* vax-tdep.c (vax_register_name): Constify.
* windows-nat.c (windows_detach): Constify.
* xcoffread.c (process_linenos, xcoff_next_symbol_text): Constify.
* xml-support.c (gdb_xml_end_element): Constify.
* xml-tdesc.c (tdesc_start_reg): Constify.
* xstormy16-tdep.c (xstormy16_register_name): Constify.
* xtensa-tdep.c (xtensa_find_register_by_name): Constify.
* xtensa-tdep.h (xtensa_register_t::name): Constify.
gdb/gdbserver/ChangeLog:
2017-04-05 Pedro Alves <palves@redhat.com>
* gdbreplay.c (sync_error): Constify.
* linux-x86-low.c (push_opcode): Constify.
2017-04-05 20:21:37 +02:00
|
|
|
exec_reverse_once (const char *cmd, char *args, int from_tty)
|
2008-10-17 21:43:47 +02:00
|
|
|
{
|
|
|
|
enum exec_direction_kind dir = execution_direction;
|
|
|
|
|
|
|
|
if (dir == EXEC_REVERSE)
|
|
|
|
error (_("Already in reverse mode. Use '%s' or 'set exec-dir forward'."),
|
|
|
|
cmd);
|
|
|
|
|
|
|
|
if (!target_can_execute_reverse)
|
|
|
|
error (_("Target %s does not support this command."), target_shortname);
|
|
|
|
|
2017-04-27 06:53:40 +02:00
|
|
|
std::string reverse_command = string_printf ("%s %s", cmd, args ? args : "");
|
|
|
|
scoped_restore restore_exec_dir
|
|
|
|
= make_scoped_restore (&execution_direction, EXEC_REVERSE);
|
|
|
|
execute_command (&reverse_command[0], from_tty);
|
2008-10-17 21:43:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
reverse_step (char *args, int from_tty)
|
|
|
|
{
|
|
|
|
exec_reverse_once ("step", args, from_tty);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
reverse_stepi (char *args, int from_tty)
|
|
|
|
{
|
|
|
|
exec_reverse_once ("stepi", args, from_tty);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
reverse_next (char *args, int from_tty)
|
|
|
|
{
|
|
|
|
exec_reverse_once ("next", args, from_tty);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
reverse_nexti (char *args, int from_tty)
|
|
|
|
{
|
|
|
|
exec_reverse_once ("nexti", args, from_tty);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
reverse_continue (char *args, int from_tty)
|
|
|
|
{
|
|
|
|
exec_reverse_once ("continue", args, from_tty);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
reverse_finish (char *args, int from_tty)
|
|
|
|
{
|
|
|
|
exec_reverse_once ("finish", args, from_tty);
|
|
|
|
}
|
|
|
|
|
2009-11-20 18:23:38 +01:00
|
|
|
/* Data structures for a bookmark list. */
|
|
|
|
|
|
|
|
struct bookmark {
|
|
|
|
struct bookmark *next;
|
|
|
|
int number;
|
|
|
|
CORE_ADDR pc;
|
|
|
|
struct symtab_and_line sal;
|
|
|
|
gdb_byte *opaque_data;
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct bookmark *bookmark_chain;
|
|
|
|
static int bookmark_count;
|
|
|
|
|
|
|
|
#define ALL_BOOKMARKS(B) for ((B) = bookmark_chain; (B); (B) = (B)->next)
|
|
|
|
|
|
|
|
#define ALL_BOOKMARKS_SAFE(B,TMP) \
|
|
|
|
for ((B) = bookmark_chain; \
|
|
|
|
(B) ? ((TMP) = (B)->next, 1) : 0; \
|
|
|
|
(B) = (TMP))
|
|
|
|
|
|
|
|
/* save_bookmark_command -- implement "bookmark" command.
|
|
|
|
Call target method to get a bookmark identifier.
|
|
|
|
Insert bookmark identifier into list.
|
|
|
|
|
|
|
|
Identifier will be a malloc string (gdb_byte *).
|
|
|
|
Up to us to free it as required. */
|
|
|
|
|
|
|
|
static void
|
|
|
|
save_bookmark_command (char *args, int from_tty)
|
|
|
|
{
|
|
|
|
/* Get target's idea of a bookmark. */
|
|
|
|
gdb_byte *bookmark_id = target_get_bookmark (args, from_tty);
|
|
|
|
struct gdbarch *gdbarch = get_regcache_arch (get_current_regcache ());
|
|
|
|
|
|
|
|
/* CR should not cause another identical bookmark. */
|
|
|
|
dont_repeat ();
|
|
|
|
|
|
|
|
if (bookmark_id == NULL)
|
|
|
|
error (_("target_get_bookmark failed."));
|
|
|
|
|
|
|
|
/* Set up a bookmark struct. */
|
2017-09-04 18:10:13 +02:00
|
|
|
bookmark *b = new bookmark ();
|
2009-11-20 18:23:38 +01:00
|
|
|
b->number = ++bookmark_count;
|
|
|
|
b->pc = regcache_read_pc (get_current_regcache ());
|
|
|
|
b->sal = find_pc_line (b->pc, 0);
|
|
|
|
b->sal.pspace = get_frame_program_space (get_current_frame ());
|
|
|
|
b->opaque_data = bookmark_id;
|
|
|
|
b->next = NULL;
|
|
|
|
|
|
|
|
/* Add this bookmark to the end of the chain, so that a list
|
|
|
|
of bookmarks will come out in order of increasing numbers. */
|
|
|
|
|
2017-09-04 18:10:13 +02:00
|
|
|
bookmark *b1 = bookmark_chain;
|
2009-11-20 18:23:38 +01:00
|
|
|
if (b1 == 0)
|
|
|
|
bookmark_chain = b;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
while (b1->next)
|
|
|
|
b1 = b1->next;
|
|
|
|
b1->next = b;
|
|
|
|
}
|
|
|
|
printf_filtered (_("Saved bookmark %d at %s\n"), b->number,
|
|
|
|
paddress (gdbarch, b->sal.pc));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Implement "delete bookmark" command. */
|
|
|
|
|
|
|
|
static int
|
2011-02-19 20:10:48 +01:00
|
|
|
delete_one_bookmark (int num)
|
2009-11-20 18:23:38 +01:00
|
|
|
{
|
2011-02-19 20:10:48 +01:00
|
|
|
struct bookmark *b1, *b;
|
|
|
|
|
|
|
|
/* Find bookmark with corresponding number. */
|
|
|
|
ALL_BOOKMARKS (b)
|
|
|
|
if (b->number == num)
|
|
|
|
break;
|
2009-11-20 18:23:38 +01:00
|
|
|
|
|
|
|
/* Special case, first item in list. */
|
|
|
|
if (b == bookmark_chain)
|
|
|
|
bookmark_chain = b->next;
|
|
|
|
|
2011-07-05 06:35:00 +02:00
|
|
|
/* Find bookmark preceding "marked" one, so we can unlink. */
|
2009-11-20 18:23:38 +01:00
|
|
|
if (b)
|
|
|
|
{
|
|
|
|
ALL_BOOKMARKS (b1)
|
|
|
|
if (b1->next == b)
|
|
|
|
{
|
|
|
|
/* Found designated bookmark. Unlink and delete. */
|
|
|
|
b1->next = b->next;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
xfree (b->opaque_data);
|
2017-09-04 18:10:13 +02:00
|
|
|
delete b;
|
2009-11-20 18:23:38 +01:00
|
|
|
return 1; /* success */
|
|
|
|
}
|
|
|
|
return 0; /* failure */
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
delete_all_bookmarks (void)
|
|
|
|
{
|
|
|
|
struct bookmark *b, *b1;
|
|
|
|
|
|
|
|
ALL_BOOKMARKS_SAFE (b, b1)
|
|
|
|
{
|
|
|
|
xfree (b->opaque_data);
|
|
|
|
xfree (b);
|
|
|
|
}
|
|
|
|
bookmark_chain = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2017-09-13 05:09:47 +02:00
|
|
|
delete_bookmark_command (const char *args, int from_tty)
|
2009-11-20 18:23:38 +01:00
|
|
|
{
|
|
|
|
if (bookmark_chain == NULL)
|
|
|
|
{
|
|
|
|
warning (_("No bookmarks."));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (args == NULL || args[0] == '\0')
|
|
|
|
{
|
|
|
|
if (from_tty && !query (_("Delete all bookmarks? ")))
|
|
|
|
return;
|
|
|
|
delete_all_bookmarks ();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
Convert tid_range_parser and get_number_or_range to classes
This converts tid_range_parser and get_number_or_range to be classes.
The various tid_range_parser_* and get_number_or_range_* functions
become methods on the respective classes. Then it updates the users
to follow.
The rationale for the change is that this provides better
encapsulation. For example, this forced me to think of a better
interface between tid_range_parser and get_number_or_range, since the
former peeked into the latter's internals a bit too much. That ended
up resulting mostly in these two not-just-straight-1-1 changes:
void
-tid_range_parser_skip (struct tid_range_parser *parser)
+tid_range_parser::skip_range ()
{
...
- tid_range_parser_init (parser, parser->range_parser.end_ptr,
- parser->default_inferior);
+ m_range_parser.skip_range ();
+ init (m_range_parser.string (), m_default_inferior);
}
and:
/* If we successfully parsed a thread number or finished parsing a
thread range, switch back to assuming the next TID is
inferior-qualified. */
- if (parser->range_parser.end_ptr == NULL
- || parser->range_parser.string == parser->range_parser.end_ptr)
+ if (!m_range_parser.in_range ())
{
For the same reason (encapsulation), this moves the enum
tid_range_state definition to within the tid_parser class's scope,
since that is private implementation detail.
While at it, switch to use "bool" for booleans.
gdb/ChangeLog:
2016-10-13 Pedro Alves <palves@redhat.com>
Tom Tromey <tom@tromey.com>
* tid-parse.h (tid_range_parser): New class.
(enum tid_range_state): Move into tid_range_parser's scope.
Remove TID_RANGE_ prefix from all values.
(tid_range_parser_get_tid, tid_range_parser_get_tid_range)
(tid_range_parser_star_range, tid_range_parser_finished)
(tid_range_parser_skip, tid_range_parser_qualified): Don't
declare.
(tid_is_in_list): Update comment.
* tid-parse.c (tid_range_parser::tid_range_parser): New.
(init, finished, get_string, skip, tid_is_qualified)
(get_tid_or_range, get_tid_range, get_tid, star_range): Rename;
turn into methods.
(tid_is_in_list): Adjust.
* cli/cli-utils.h (number_or_range_parser): New class.
(init_number_or_range, get_number_or_range)
(number_range_setup_range): Don't declare.
* cli/cli-utils.c
(number_or_range_parser::number_or_range_parser): New.
(init_number_or_range, get_number_or_range)
(number_range_setup_range): Rename; turn into methods.
(number_is_in_list): Adjust.
* breakpoint.c (map_breakpoint_numbers): Adjust. Use bool.
(trace_pass_command, get_tracepoint_by_number): Adjust.
* breakpoint.h (get_tracepoint_by_number): Adjust.
* inferior.c (detach_inferior_command, kill_inferior_command)
(remove_inferior_command): Adjust.
* linespec.c (decode_line_2): Adjust.
* memattr.c (mem_enable_command, mem_disable_command)
(mem_delete_command): Adjust.
* printcmd.c (map_display_numbers): Adjust.
* reverse.c (delete_bookmark_command, bookmarks_info): Adjust.
* thread.c (thread_apply_command): Adjust.
2016-10-13 02:54:07 +02:00
|
|
|
number_or_range_parser parser (args);
|
|
|
|
while (!parser.finished ())
|
2011-02-19 20:10:48 +01:00
|
|
|
{
|
Convert tid_range_parser and get_number_or_range to classes
This converts tid_range_parser and get_number_or_range to be classes.
The various tid_range_parser_* and get_number_or_range_* functions
become methods on the respective classes. Then it updates the users
to follow.
The rationale for the change is that this provides better
encapsulation. For example, this forced me to think of a better
interface between tid_range_parser and get_number_or_range, since the
former peeked into the latter's internals a bit too much. That ended
up resulting mostly in these two not-just-straight-1-1 changes:
void
-tid_range_parser_skip (struct tid_range_parser *parser)
+tid_range_parser::skip_range ()
{
...
- tid_range_parser_init (parser, parser->range_parser.end_ptr,
- parser->default_inferior);
+ m_range_parser.skip_range ();
+ init (m_range_parser.string (), m_default_inferior);
}
and:
/* If we successfully parsed a thread number or finished parsing a
thread range, switch back to assuming the next TID is
inferior-qualified. */
- if (parser->range_parser.end_ptr == NULL
- || parser->range_parser.string == parser->range_parser.end_ptr)
+ if (!m_range_parser.in_range ())
{
For the same reason (encapsulation), this moves the enum
tid_range_state definition to within the tid_parser class's scope,
since that is private implementation detail.
While at it, switch to use "bool" for booleans.
gdb/ChangeLog:
2016-10-13 Pedro Alves <palves@redhat.com>
Tom Tromey <tom@tromey.com>
* tid-parse.h (tid_range_parser): New class.
(enum tid_range_state): Move into tid_range_parser's scope.
Remove TID_RANGE_ prefix from all values.
(tid_range_parser_get_tid, tid_range_parser_get_tid_range)
(tid_range_parser_star_range, tid_range_parser_finished)
(tid_range_parser_skip, tid_range_parser_qualified): Don't
declare.
(tid_is_in_list): Update comment.
* tid-parse.c (tid_range_parser::tid_range_parser): New.
(init, finished, get_string, skip, tid_is_qualified)
(get_tid_or_range, get_tid_range, get_tid, star_range): Rename;
turn into methods.
(tid_is_in_list): Adjust.
* cli/cli-utils.h (number_or_range_parser): New class.
(init_number_or_range, get_number_or_range)
(number_range_setup_range): Don't declare.
* cli/cli-utils.c
(number_or_range_parser::number_or_range_parser): New.
(init_number_or_range, get_number_or_range)
(number_range_setup_range): Rename; turn into methods.
(number_is_in_list): Adjust.
* breakpoint.c (map_breakpoint_numbers): Adjust. Use bool.
(trace_pass_command, get_tracepoint_by_number): Adjust.
* breakpoint.h (get_tracepoint_by_number): Adjust.
* inferior.c (detach_inferior_command, kill_inferior_command)
(remove_inferior_command): Adjust.
* linespec.c (decode_line_2): Adjust.
* memattr.c (mem_enable_command, mem_disable_command)
(mem_delete_command): Adjust.
* printcmd.c (map_display_numbers): Adjust.
* reverse.c (delete_bookmark_command, bookmarks_info): Adjust.
* thread.c (thread_apply_command): Adjust.
2016-10-13 02:54:07 +02:00
|
|
|
int num = parser.get_number ();
|
2011-02-19 20:10:48 +01:00
|
|
|
if (!delete_one_bookmark (num))
|
|
|
|
/* Not found. */
|
|
|
|
warning (_("No bookmark #%d."), num);
|
|
|
|
}
|
2009-11-20 18:23:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Implement "goto-bookmark" command. */
|
|
|
|
|
|
|
|
static void
|
|
|
|
goto_bookmark_command (char *args, int from_tty)
|
|
|
|
{
|
|
|
|
struct bookmark *b;
|
|
|
|
unsigned long num;
|
2014-02-22 07:42:12 +01:00
|
|
|
char *p = args;
|
2009-11-20 18:23:38 +01:00
|
|
|
|
|
|
|
if (args == NULL || args[0] == '\0')
|
|
|
|
error (_("Command requires an argument."));
|
|
|
|
|
2015-03-06 10:42:06 +01:00
|
|
|
if (startswith (args, "start")
|
|
|
|
|| startswith (args, "begin")
|
|
|
|
|| startswith (args, "end"))
|
2009-11-20 18:23:38 +01:00
|
|
|
{
|
|
|
|
/* Special case. Give target opportunity to handle. */
|
2013-04-19 17:32:56 +02:00
|
|
|
target_goto_bookmark ((gdb_byte *) args, from_tty);
|
2009-11-20 18:23:38 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (args[0] == '\'' || args[0] == '\"')
|
|
|
|
{
|
|
|
|
/* Special case -- quoted string. Pass on to target. */
|
|
|
|
if (args[strlen (args) - 1] != args[0])
|
|
|
|
error (_("Unbalanced quotes: %s"), args);
|
2013-04-19 17:32:56 +02:00
|
|
|
target_goto_bookmark ((gdb_byte *) args, from_tty);
|
2009-11-20 18:23:38 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* General case. Bookmark identified by bookmark number. */
|
2011-02-19 20:10:48 +01:00
|
|
|
num = get_number (&args);
|
2014-02-22 07:42:12 +01:00
|
|
|
|
|
|
|
if (num == 0)
|
|
|
|
error (_("goto-bookmark: invalid bookmark number '%s'."), p);
|
|
|
|
|
2009-11-20 18:23:38 +01:00
|
|
|
ALL_BOOKMARKS (b)
|
|
|
|
if (b->number == num)
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (b)
|
|
|
|
{
|
|
|
|
/* Found. Send to target method. */
|
|
|
|
target_goto_bookmark (b->opaque_data, from_tty);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
/* Not found. */
|
2014-02-22 07:42:12 +01:00
|
|
|
error (_("goto-bookmark: no bookmark found for '%s'."), p);
|
2009-11-20 18:23:38 +01:00
|
|
|
}
|
|
|
|
|
2011-02-19 20:10:48 +01:00
|
|
|
static int
|
|
|
|
bookmark_1 (int bnum)
|
|
|
|
{
|
|
|
|
struct gdbarch *gdbarch = get_regcache_arch (get_current_regcache ());
|
|
|
|
struct bookmark *b;
|
|
|
|
int matched = 0;
|
|
|
|
|
|
|
|
ALL_BOOKMARKS (b)
|
|
|
|
{
|
|
|
|
if (bnum == -1 || bnum == b->number)
|
|
|
|
{
|
|
|
|
printf_filtered (" %d %s '%s'\n",
|
|
|
|
b->number,
|
|
|
|
paddress (gdbarch, b->pc),
|
|
|
|
b->opaque_data);
|
|
|
|
matched++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bnum > 0 && matched == 0)
|
|
|
|
printf_filtered ("No bookmark #%d\n", bnum);
|
|
|
|
|
|
|
|
return matched;
|
|
|
|
}
|
|
|
|
|
2009-11-20 18:23:38 +01:00
|
|
|
/* Implement "info bookmarks" command. */
|
|
|
|
|
|
|
|
static void
|
2017-08-22 22:09:55 +02:00
|
|
|
info_bookmarks_command (char *args, int from_tty)
|
2009-11-20 18:23:38 +01:00
|
|
|
{
|
|
|
|
if (!bookmark_chain)
|
2011-02-19 20:10:48 +01:00
|
|
|
printf_filtered (_("No bookmarks.\n"));
|
|
|
|
else if (args == NULL || *args == '\0')
|
|
|
|
bookmark_1 (-1);
|
|
|
|
else
|
2011-03-10 19:33:59 +01:00
|
|
|
{
|
Convert tid_range_parser and get_number_or_range to classes
This converts tid_range_parser and get_number_or_range to be classes.
The various tid_range_parser_* and get_number_or_range_* functions
become methods on the respective classes. Then it updates the users
to follow.
The rationale for the change is that this provides better
encapsulation. For example, this forced me to think of a better
interface between tid_range_parser and get_number_or_range, since the
former peeked into the latter's internals a bit too much. That ended
up resulting mostly in these two not-just-straight-1-1 changes:
void
-tid_range_parser_skip (struct tid_range_parser *parser)
+tid_range_parser::skip_range ()
{
...
- tid_range_parser_init (parser, parser->range_parser.end_ptr,
- parser->default_inferior);
+ m_range_parser.skip_range ();
+ init (m_range_parser.string (), m_default_inferior);
}
and:
/* If we successfully parsed a thread number or finished parsing a
thread range, switch back to assuming the next TID is
inferior-qualified. */
- if (parser->range_parser.end_ptr == NULL
- || parser->range_parser.string == parser->range_parser.end_ptr)
+ if (!m_range_parser.in_range ())
{
For the same reason (encapsulation), this moves the enum
tid_range_state definition to within the tid_parser class's scope,
since that is private implementation detail.
While at it, switch to use "bool" for booleans.
gdb/ChangeLog:
2016-10-13 Pedro Alves <palves@redhat.com>
Tom Tromey <tom@tromey.com>
* tid-parse.h (tid_range_parser): New class.
(enum tid_range_state): Move into tid_range_parser's scope.
Remove TID_RANGE_ prefix from all values.
(tid_range_parser_get_tid, tid_range_parser_get_tid_range)
(tid_range_parser_star_range, tid_range_parser_finished)
(tid_range_parser_skip, tid_range_parser_qualified): Don't
declare.
(tid_is_in_list): Update comment.
* tid-parse.c (tid_range_parser::tid_range_parser): New.
(init, finished, get_string, skip, tid_is_qualified)
(get_tid_or_range, get_tid_range, get_tid, star_range): Rename;
turn into methods.
(tid_is_in_list): Adjust.
* cli/cli-utils.h (number_or_range_parser): New class.
(init_number_or_range, get_number_or_range)
(number_range_setup_range): Don't declare.
* cli/cli-utils.c
(number_or_range_parser::number_or_range_parser): New.
(init_number_or_range, get_number_or_range)
(number_range_setup_range): Rename; turn into methods.
(number_is_in_list): Adjust.
* breakpoint.c (map_breakpoint_numbers): Adjust. Use bool.
(trace_pass_command, get_tracepoint_by_number): Adjust.
* breakpoint.h (get_tracepoint_by_number): Adjust.
* inferior.c (detach_inferior_command, kill_inferior_command)
(remove_inferior_command): Adjust.
* linespec.c (decode_line_2): Adjust.
* memattr.c (mem_enable_command, mem_disable_command)
(mem_delete_command): Adjust.
* printcmd.c (map_display_numbers): Adjust.
* reverse.c (delete_bookmark_command, bookmarks_info): Adjust.
* thread.c (thread_apply_command): Adjust.
2016-10-13 02:54:07 +02:00
|
|
|
number_or_range_parser parser (args);
|
|
|
|
while (!parser.finished ())
|
2011-03-10 19:33:59 +01:00
|
|
|
{
|
Convert tid_range_parser and get_number_or_range to classes
This converts tid_range_parser and get_number_or_range to be classes.
The various tid_range_parser_* and get_number_or_range_* functions
become methods on the respective classes. Then it updates the users
to follow.
The rationale for the change is that this provides better
encapsulation. For example, this forced me to think of a better
interface between tid_range_parser and get_number_or_range, since the
former peeked into the latter's internals a bit too much. That ended
up resulting mostly in these two not-just-straight-1-1 changes:
void
-tid_range_parser_skip (struct tid_range_parser *parser)
+tid_range_parser::skip_range ()
{
...
- tid_range_parser_init (parser, parser->range_parser.end_ptr,
- parser->default_inferior);
+ m_range_parser.skip_range ();
+ init (m_range_parser.string (), m_default_inferior);
}
and:
/* If we successfully parsed a thread number or finished parsing a
thread range, switch back to assuming the next TID is
inferior-qualified. */
- if (parser->range_parser.end_ptr == NULL
- || parser->range_parser.string == parser->range_parser.end_ptr)
+ if (!m_range_parser.in_range ())
{
For the same reason (encapsulation), this moves the enum
tid_range_state definition to within the tid_parser class's scope,
since that is private implementation detail.
While at it, switch to use "bool" for booleans.
gdb/ChangeLog:
2016-10-13 Pedro Alves <palves@redhat.com>
Tom Tromey <tom@tromey.com>
* tid-parse.h (tid_range_parser): New class.
(enum tid_range_state): Move into tid_range_parser's scope.
Remove TID_RANGE_ prefix from all values.
(tid_range_parser_get_tid, tid_range_parser_get_tid_range)
(tid_range_parser_star_range, tid_range_parser_finished)
(tid_range_parser_skip, tid_range_parser_qualified): Don't
declare.
(tid_is_in_list): Update comment.
* tid-parse.c (tid_range_parser::tid_range_parser): New.
(init, finished, get_string, skip, tid_is_qualified)
(get_tid_or_range, get_tid_range, get_tid, star_range): Rename;
turn into methods.
(tid_is_in_list): Adjust.
* cli/cli-utils.h (number_or_range_parser): New class.
(init_number_or_range, get_number_or_range)
(number_range_setup_range): Don't declare.
* cli/cli-utils.c
(number_or_range_parser::number_or_range_parser): New.
(init_number_or_range, get_number_or_range)
(number_range_setup_range): Rename; turn into methods.
(number_is_in_list): Adjust.
* breakpoint.c (map_breakpoint_numbers): Adjust. Use bool.
(trace_pass_command, get_tracepoint_by_number): Adjust.
* breakpoint.h (get_tracepoint_by_number): Adjust.
* inferior.c (detach_inferior_command, kill_inferior_command)
(remove_inferior_command): Adjust.
* linespec.c (decode_line_2): Adjust.
* memattr.c (mem_enable_command, mem_disable_command)
(mem_delete_command): Adjust.
* printcmd.c (map_display_numbers): Adjust.
* reverse.c (delete_bookmark_command, bookmarks_info): Adjust.
* thread.c (thread_apply_command): Adjust.
2016-10-13 02:54:07 +02:00
|
|
|
int bnum = parser.get_number ();
|
2011-03-10 19:33:59 +01:00
|
|
|
bookmark_1 (bnum);
|
|
|
|
}
|
|
|
|
}
|
2009-11-20 18:23:38 +01:00
|
|
|
}
|
|
|
|
|
2008-10-17 21:43:47 +02:00
|
|
|
void
|
|
|
|
_initialize_reverse (void)
|
|
|
|
{
|
|
|
|
add_com ("reverse-step", class_run, reverse_step, _("\
|
|
|
|
Step program backward until it reaches the beginning of another source line.\n\
|
|
|
|
Argument N means do this N times (or till program stops for another reason).")
|
|
|
|
);
|
|
|
|
add_com_alias ("rs", "reverse-step", class_alias, 1);
|
|
|
|
|
|
|
|
add_com ("reverse-next", class_run, reverse_next, _("\
|
|
|
|
Step program backward, proceeding through subroutine calls.\n\
|
|
|
|
Like the \"reverse-step\" command as long as subroutine calls do not happen;\n\
|
|
|
|
when they do, the call is treated as one instruction.\n\
|
|
|
|
Argument N means do this N times (or till program stops for another reason).")
|
|
|
|
);
|
|
|
|
add_com_alias ("rn", "reverse-next", class_alias, 1);
|
|
|
|
|
|
|
|
add_com ("reverse-stepi", class_run, reverse_stepi, _("\
|
|
|
|
Step backward exactly one instruction.\n\
|
|
|
|
Argument N means do this N times (or till program stops for another reason).")
|
|
|
|
);
|
|
|
|
add_com_alias ("rsi", "reverse-stepi", class_alias, 0);
|
|
|
|
|
|
|
|
add_com ("reverse-nexti", class_run, reverse_nexti, _("\
|
|
|
|
Step backward one instruction, but proceed through called subroutines.\n\
|
|
|
|
Argument N means do this N times (or till program stops for another reason).")
|
|
|
|
);
|
|
|
|
add_com_alias ("rni", "reverse-nexti", class_alias, 0);
|
|
|
|
|
|
|
|
add_com ("reverse-continue", class_run, reverse_continue, _("\
|
|
|
|
Continue program being debugged but run it in reverse.\n\
|
|
|
|
If proceeding from breakpoint, a number N may be used as an argument,\n\
|
|
|
|
which means to set the ignore count of that breakpoint to N - 1 (so that\n\
|
|
|
|
the breakpoint won't break until the Nth time it is reached)."));
|
|
|
|
add_com_alias ("rc", "reverse-continue", class_alias, 0);
|
|
|
|
|
|
|
|
add_com ("reverse-finish", class_run, reverse_finish, _("\
|
|
|
|
Execute backward until just before selected stack frame is called."));
|
2009-11-20 18:23:38 +01:00
|
|
|
|
|
|
|
add_com ("bookmark", class_bookmark, save_bookmark_command, _("\
|
|
|
|
Set a bookmark in the program's execution history.\n\
|
|
|
|
A bookmark represents a point in the execution history \n\
|
|
|
|
that can be returned to at a later point in the debug session."));
|
2017-08-22 22:09:55 +02:00
|
|
|
add_info ("bookmarks", info_bookmarks_command, _("\
|
2009-11-20 18:23:38 +01:00
|
|
|
Status of user-settable bookmarks.\n\
|
|
|
|
Bookmarks are user-settable markers representing a point in the \n\
|
|
|
|
execution history that can be returned to later in the same debug \n\
|
|
|
|
session."));
|
|
|
|
add_cmd ("bookmark", class_bookmark, delete_bookmark_command, _("\
|
|
|
|
Delete a bookmark from the bookmark list.\n\
|
2011-02-19 20:10:48 +01:00
|
|
|
Argument is a bookmark number or numbers,\n\
|
|
|
|
or no argument to delete all bookmarks.\n"),
|
2009-11-20 18:23:38 +01:00
|
|
|
&deletelist);
|
|
|
|
add_com ("goto-bookmark", class_bookmark, goto_bookmark_command, _("\
|
|
|
|
Go to an earlier-bookmarked point in the program's execution history.\n\
|
|
|
|
Argument is the bookmark number of a bookmark saved earlier by using \n\
|
|
|
|
the 'bookmark' command, or the special arguments:\n\
|
|
|
|
start (beginning of recording)\n\
|
|
|
|
end (end of recording)\n"));
|
2008-10-17 21:43:47 +02:00
|
|
|
}
|