wget https://ftp.gnu.org/gnu/gdb/gdb-9.2.tar.xz
tar -xf gdb-9.2.tar.xz && cd gdb-9.2
mkdir build && cd build
# GDB is now a C++ program
../configure --disable-binutils --disable-ld --disable-gold --disable-gas --disable-sim --disable-gprof CXXFLAGS='-g3 -O0' CFLAGS='-g3 -O0'
make -j
./gdb/gdb --help
This is the GNU debugger. Usage:
gdb [options] [executable-file [core-file or process-id]]
gdb [options] --args executable-file [inferior-arguments ...]
gdb-9.2/build/gdb$ gdb --args ./gdb ../variable
(top-gdb) bt
#0 read_symbols (
objfile=0x555555758590 <std::unordered_map<char const*, int, std::hash<char const*>, std::equal_to<char const*>, std::allocator<std::pair<char const* const, int> > >::clear()+28>, add_flags=...) at ../../gdb/symfile.c:788
#1 0x0000555555ac2827 in syms_from_objfile_1 (objfile=0x555556261c10, addrs=0x7fffffffdcc0, add_flags=...) at ../../gdb/symfile.c:991
#2 0x0000555555ac2914 in syms_from_objfile (objfile=0x555556261c10, addrs=0x0, add_flags=...) at ../../gdb/symfile.c:1008
#3 0x0000555555ac2d92 in symbol_file_add_with_addrs (abfd=0x555556246d30, name=0x7fffffffe641 "../variable", add_flags=..., addrs=0x0, flags=...,
parent=0x0) at ../../gdb/symfile.c:1112
#4 0x0000555555ac3194 in symbol_file_add_from_bfd (abfd=0x555556246d30, name=0x7fffffffe641 "../variable", add_flags=..., addrs=0x0, flags=...,
parent=0x0) at ../../gdb/symfile.c:1193
#5 0x0000555555ac3201 in symbol_file_add (name=0x7fffffffe641 "../variable", add_flags=..., addrs=0x0, flags=...) at ../../gdb/symfile.c:1206
#6 0x0000555555ac3328 in symbol_file_add_main_1 (args=0x7fffffffe641 "../variable", add_flags=..., flags=..., reloff=0x0) at ../../gdb/symfile.c:1230
#7 0x0000555555ac3298 in symbol_file_add_main (args=0x7fffffffe641 "../variable", add_flags=...) at ../../gdb/symfile.c:1221
#8 0x0000555555973916 in symbol_file_add_main_adapter (arg=0x7fffffffe641 "../variable", from_tty=1) at ../../gdb/main.c:423
#9 0x0000555555973857 in catch_command_errors (command=0x5555559738bb <symbol_file_add_main_adapter(char const*, int)>,
arg=0x7fffffffe641 "../variable", from_tty=1) at ../../gdb/main.c:400
#10 0x00005555559749da in captured_main_1 (context=0x7fffffffe260) at ../../gdb/main.c:1072
#11 0x000055555597506d in captured_main (data=0x7fffffffe260) at ../../gdb/main.c:1192
#12 0x00005555559750e4 in gdb_main (args=0x7fffffffe260) at ../../gdb/main.c:1217
#13 0x0000555555609f26 in main (During symbol reading: cannot get low and high bounds for subprogram DIE at 0x9172
argc=2, argv=0x7fffffffe378) at ../../gdb/gdb.c:32
(top-gdb) frame 10
#10 0x00005555559749da in captured_main_1 (context=0x7fffffffe260) at ../../gdb/main.c:1072
1072 ret = catch_command_errors (symbol_file_add_main_adapter,
(top-gdb) bt
#0 linux_nat_wait_1 (ptid=..., ourstatus=0x0, target_options=32767) at ../../gdb/linux-nat.c:3259
#1 0x0000555555947c41 in linux_nat_target::wait (During symbol reading: .debug_line address at offset 0x451b34 is 0 [in module /home/ostest/test/gdb-9.2/build/gdb/gdb]
During symbol reading: unsupported tag: 'DW_TAG_unspecified_type'
During symbol reading: Member function "~_Sp_counted_base" (offset 0x1f63879) is virtual but the vtable offset is not specified
During symbol reading: Multiple children of DIE 0x1fba514 refer to DIE 0x1fba502 as their abstract origin
During symbol reading: debug info gives source 160 included from file at zero line 0
During symbol reading: debug info gives command-line macro definition with non-zero line 19: _STDC_PREDEF_H 1
this=0x555556147b30 <the_amd64_linux_nat_target>, ptid=..., ourstatus=0x7fffffffda40,
target_options=0) at ../../gdb/linux-nat.c:3592
#2 0x0000555555b0c60f in target_wait (ptid=..., status=0x7fffffffda40, options=0) at ../../gdb/target.c:2059
#3 0x00005555559c64c7 in startup_inferior (pid=382713, ntraps=1, last_waitstatus=0x0, last_ptid=0x0) at ../../gdb/nat/fork-inferior.c:485
#4 0x000055555586f4e6 in gdb_startup_inferior (During symbol reading: cannot get low and high bounds for subprogram DIE at 0x10adcb3
pid=382713, num_traps=1) at ../../gdb/fork-child.c:131
#5 0x00005555558eb96d in inf_ptrace_target::create_inferior (this=0x555556147b30 <the_amd64_linux_nat_target>,
exec_file=0x555556250580 "/home/ostest/test/gdb-9.2/build/variable", allargs="", env=0x5555561c2db0, from_tty=1) at ../../gdb/inf-ptrace.c:143
#6 0x00005555559417c2 in linux_nat_target::create_inferior (this=0x555556147b30 <the_amd64_linux_nat_target>,
exec_file=0x555556250580 "/home/ostest/test/gdb-9.2/build/variable", allargs="", env=0x5555561c2db0, from_tty=1) at ../../gdb/linux-nat.c:1095
#7 0x00005555558f2c10 in run_command_1 (args=0x0, from_tty=1, run_how=RUN_NORMAL) at ../../gdb/infcmd.c:633
#8 0x00005555558f2e04 in run_command (During symbol reading: Child DIE 0x562f98 and its abstract origin 0x5659fe have different parents
args=0x0, from_tty=1) at ../../gdb/infcmd.c:677
#9 0x000055555570eeca in do_const_cfunc (c=0x5555561e0ac0, args=0x0, from_tty=1) at ../../gdb/cli/cli-decode.c:107
#10 0x0000555555712619 in cmd_func (cmd=0x5555561e0ac0, args=0x0, from_tty=1) at ../../gdb/cli/cli-decode.c:1952
#11 0x0000555555b32724 in execute_command (p=0x5555561819f1 "", from_tty=1) at ../../gdb/top.c:651
#12 0x0000555555856fb6 in command_handler (command=0x5555561819f0 "") at ../../gdb/event-top.c:587
#13 0x000055555585743f in command_line_handler (rl=...) at ../../gdb/event-top.c:772
#14 0x00005555558566d3 in gdb_rl_callback_handler (rl=0x555556183850 "r") at ../../gdb/event-top.c:218
#15 0x0000555555be749e in rl_callback_read_char () at ../../../readline/readline/callback.c:281
#16 0x00005555558564f0 in gdb_rl_callback_read_char_wrapper_noexcept () at ../../gdb/event-top.c:176
#17 0x000055555585659e in gdb_rl_callback_read_char_wrapper (client_data=0x5555561817a0) at ../../gdb/event-top.c:193
#18 0x0000555555856e35 in stdin_event_handler (error=0, client_data=0x5555561817a0) at ../../gdb/event-top.c:515
#19 0x0000555555854a47 in handle_file_event (file_ptr=0x55555624fb70, ready_mask=1) at ../../gdb/event-loop.c:731
#20 0x0000555555855010 in gdb_wait_for_event (block=1) at ../../gdb/event-loop.c:857
#21 0x0000555555853df1 in gdb_do_one_event () at ../../gdb/event-loop.c:346
#22 0x0000555555853e1f in start_event_loop () at ../../gdb/event-loop.c:370
#23 0x00005555559737ac in captured_command_loop () at ../../gdb/main.c:359
#24 0x0000555555975072 in captured_main (data=0x7fffffffe260) at ../../gdb/main.c:1202
#25 0x00005555559750e4 in gdb_main (args=0x7fffffffe260) at ../../gdb/main.c:1217
#26 0x0000555555609f26 in main (argc=2, argv=0x7fffffffe378) at ../../gdb/gdb.c:32
(top-gdb) frame 11
#11 0x0000555555b32724 in execute_command (p=0x5555561819f1 "", from_tty=1) at ../../gdb/top.c:651
651 cmd_func (c, arg, from_tty);
(top-gdb) p c
$4 = (cmd_list_element *) 0x5555561e0ac0
(top-gdb) p *c
$5 = {next = 0x55555622d200, name = 0x555555daf571 "run", theclass = class_run, cmd_deprecated = 0, deprecated_warn_user = 0,
malloced_replacement = 0, doc_allocated = 0, name_allocated = 0, hook_in = 0, allow_unknown = 0, abbrev_flag = 0, type = not_set_cmd,
var_type = var_boolean, func = 0x55555570ee9d <do_const_cfunc(cmd_list_element*, char const*, int)>, function = {
const_cfunc = 0x5555558f2ddb <run_command(char const*, int)>, sfunc = 0x5555558f2ddb <run_command(char const*, int)>}, context = 0x0,
doc = 0x555555daf360 "Start debugged program.\nYou may specify arguments to give it.\nArgs may include \"*\", or \"[...]\"; they are expanded using the\nshell that will start the program (specified by the \"$SHELL\" environment\nvar"..., show_value_func = 0x0, replacement = 0x0,
pre_show_hook = 0x0, hook_pre = 0x0, hook_post = 0x0, prefixlist = 0x0, prefixname = 0x0, prefix = 0x0,
completer = 0x555555759f1e <filename_completer(cmd_list_element*, completion_tracker&, char const*, char const*)>, completer_handle_brkchars = 0x0,
destroyer = 0x0, var = 0x0, enums = 0x0, user_commands = std::shared_ptr<command_line> (empty) = {get() = 0x0}, hookee_pre = 0x0,
hookee_post = 0x0, cmd_pointer = 0x0, aliases = 0x5555561e0bb0, alias_chain = 0x0, suppress_notification = 0x0}
在 gdb源码 中搜索 add_cmd ("breakpoints"
void _initialize_cli_cmds ()
{
add_cmd ("breakpoints", class_breakpoint,
_("Making program stop at certain points."), &cmdlist);
}
(top-gdb) b execute_command
(gdb) b main
(top-gdb) n
589 = make_scoped_restore (&repeat_arguments, nullptr);
(top-gdb) p *c
$5 = {next = 0x5555561c06c0, name = 0x555555d4aeaa "break", theclass = class_breakpoint, cmd_deprecated = 0, deprecated_warn_user = 0,
malloced_replacement = 0, doc_allocated = 0, name_allocated = 0, hook_in = 0, allow_unknown = 0, abbrev_flag = 0, type = not_set_cmd,
var_type = var_boolean, func = 0x55555570ee9d <do_const_cfunc(cmd_list_element*, char const*, int)>, function = {
const_cfunc = 0x5555556a07a5 <break_command(char const*, int)>, sfunc = 0x5555556a07a5 <break_command(char const*, int)>}
(top-gdb) b break_command
#1 0x00005555556a0498 in break_command_1 (arg=0x5555561819f6 "", flag=0, from_tty=1) at ../../gdb/breakpoint.c:9390
#2 0x00005555556a07cc in break_command (arg=0x5555561819f2 "main", from_tty=1) at ../../gdb/breakpoint.c:9461
// location 保存需要打断点的信息
(top-gdb) p *location
$3 = {type = LINESPEC_LOCATION, u = {addr_string = 0x0, linespec_location = {match_type = symbol_name_match_type::WILD,
spec_string = 0x555556183c40 "main"}, address = 0x0, explicit_loc = {source_filename = 0x0, function_name = 0x555556183c40 "main",
func_name_match_type = symbol_name_match_type::WILD, label_name = 0x0, line_offset = {offset = 0, sign = LINE_OFFSET_NONE}}}, as_string = 0x0}
(top-gdb) n
9232 ops->create_sals_from_location (location, &canonical, type_wanted);
(top-gdb) s
bkpt_create_sals_from_location (location=0x7fffffffdbc0, canonical=0x7fffffffdb20, type_wanted=21845) at ../../gdb/breakpoint.c:12489
(top-gdb) n
8996 if (last_displayed_sal_is_valid ())
(top-gdb) p cursal
$5 = {pspace = 0x555556239b70, symtab = 0x0, symbol = 0x0, section = 0x0, msymbol = 0x0, line = 0, pc = 0x0, end = 0x0, explicit_pc = false,
explicit_line = false, prob = 0x0, objfile = 0x0}
(top-gdb) n
9016 decode_line_full (location, DECODE_LINE_FUNFIRSTLINE, NULL,
9270 if (!pending)
(top-gdb) p canonical
$6 = {special_display = false, pre_expanded = true, location = std::unique_ptr<event_location> = {get() = 0x5555562b7210},
lsals = std::vector of length 1, capacity 1 = {{canonical = 0x0, sals = std::vector of length 1, capacity 1 = {{pspace = 0x555556239b70,
symtab = 0x555556255f00, symbol = 0x55555629c7b0, section = 0x555556255b38, msymbol = 0x0, line = 12, pc = 0x11bf, end = 0x11cb,
explicit_pc = false, explicit_line = false, prob = 0x0, objfile = 0x0}}}}}
9322 ops->create_breakpoints_sal (gdbarch, &canonical,
(top-gdb) s
bkpt_create_breakpoints_sal (gdbarch=0x7fffffffdb58, canonical=0x7fffffffdb58, cond_string=std::unique_ptr<char> = {...},
extra_string=std::unique_ptr<char> = {...}, type_wanted=32767, disposition=4294957912, thread=-1, task=0, ignore_count=0, ops=0x7fffffffda80,
from_tty=1, enabled=1, internal=0, flags=0) at ../../gdb/breakpoint.c:12505
(top-gdb) n
Breakpoint 2 at 0x11bf: file ./variable.c, line 12.
大致查看了源码,然后重新打断点 b init_breakpoint_sal
(top-gdb) info frame
Stack level 0, frame at 0x7fffffffd740:
rip = 0x55555569e19a in init_breakpoint_sal (../../gdb/breakpoint.c:8750); saved rip = 0x55555569e939
called by frame at 0x7fffffffd850
source language c++.
Arglist at 0x7fffffffd608, args: b=0x5555561e5820, gdbarch=0x55555625bb40, sals=..., location=..., filter=std::unique_ptr<char> = {...},
cond_string=std::unique_ptr<char> = {...}, extra_string=std::unique_ptr<char> = {...}, type=bp_breakpoint, disposition=disp_donttouch, thread=-1,
task=0, ignore_count=0, ops=0x555556148460 <bkpt_breakpoint_ops>, from_tty=1, enabled=1, internal=0, flags=0, display_canonical=0
Locals at 0x7fffffffd608, Previous frame's sp is 0x7fffffffd740
Saved registers:
rbx at 0x7fffffffd728, rbp at 0x7fffffffd730, rip at 0x7fffffffd738
// 得到不为空
struct gdbarch *loc_gdbarch = get_sal_arch (sal);
(top-gdb) p *loc_gdbarch
$11 = {initialized_p = 1, obstack = 0x555556252810, bfd_arch_info = 0x555556131aa0 <bfd_x86_64_arch>, byte_order = BFD_ENDIAN_LITTLE,
byte_order_for_code = BFD_ENDIAN_LITTLE, osabi = GDB_OSABI_LINUX, During symbol reading: unsupported tag: 'DW_TAG_unspecified_type'
During symbol reading: Member function "~_Sp_counted_base" (offset 0x1f095f5) is virtual but the vtable offset is not specified
target_desc = During symbol reading: Multiple children of DIE 0x1f3bcf0 refer to DIE 0x1f3bcde as their abstract origin
During symbol reading: debug info gives source 129 included from file at zero line 0
During symbol reading: debug info gives command-line macro definition with non-zero line 19: _STDC_PREDEF_H 1
0x0, tdep = 0x55555625b980, dump_tdep = 0x0, nr_data = 22,
data = 0x55555625c110, short_bit = 16, int_bit = 32, long_bit = 64, long_long_bit = 64, half_bit = 16,
half_format = 0x555556137430 <floatformats_ieee_half>, float_bit = 32, float_format = 0x555556137440 <floatformats_ieee_single>, double_bit = 64,
double_format = 0x555556137450 <floatformats_ieee_double>, long_double_bit = 128, long_double_format = 0x555556137470 <floatformats_i387_ext>,
wchar_bit = 32, wchar_signed = 1, floatformat_for_type = 0x5555558e15c1 <i386_floatformat_for_type(gdbarch*, char const*, int)>, ptr_bit = 64,
addr_bit = 64, dwarf2_addr_size = 8, char_signed = 1, read_pc = 0x0, write_pc = 0x55555564edc0 <amd64_linux_write_pc(regcache*, CORE_ADDR)>,
virtual_frame_pointer = 0x55555565ccd7 <legacy_virtual_frame_pointer(gdbarch*, unsigned long, int*, long*)>, pseudo_register_read = 0x0,
pseudo_register_read_value = 0x555555651dc8 <amd64_pseudo_register_read_value(gdbarch*, readable_regcache*, int)>,
pseudo_register_write = 0x5555556522db <amd64_pseudo_register_write(gdbarch*, regcache*, int, gdb_byte const*)>, num_regs = 155,
num_pseudo_regs = 52, ax_pseudo_register_collect = 0x555555652730 <amd64_ax_pseudo_register_collect(gdbarch*, agent_expr*, int)>,
ax_pseudo_register_push_stack = 0x0, handle_segmentation_fault = 0x5555558cfd5b <i386_linux_handle_segmentation_fault(gdbarch*, ui_out*)>,
sp_regnum = 7, pc_regnum = 16, ps_regnum = 17, fp0_regnum = 24, stab_reg_to_regnum = 0x555555651b14 <amd64_dwarf_reg_to_regnum(gdbarch*, int)>,
ecoff_reg_to_regnum = 0x55555565cc45 <no_op_reg_to_regnum(gdbarch*, int)>,
sdb_reg_to_regnum = 0x5555558d1cff <i386_dbx_reg_to_regnum(gdbarch*, int)>,
dwarf2_reg_to_regnum = 0x555555651b14 <amd64_dwarf_reg_to_regnum(gdbarch*, int)>,
register_name = 0x555555af2b70 <tdesc_register_name(gdbarch*, int)>, register_type = 0x555555af2c67 <tdesc_register_type(gdbarch*, int)>,
dummy_id = 0x5555556572de <amd64_dummy_id(gdbarch*, frame_info*)>, deprecated_fp_regnum = -1,
push_dummy_call = 0x555555653a4c <amd64_push_dummy_call(gdbarch*, value*, regcache*, CORE_ADDR, int, value**, CORE_ADDR, function_call_return_method, CORE_ADDR)>, call_dummy_location = 1,
push_dummy_code = 0x5555558d5706 <i386_push_dummy_code(gdbarch*, CORE_ADDR, CORE_ADDR, value**, int, type*, CORE_ADDR*, CORE_ADDR*, regcache*)>,
code_of_frame_writable = 0x55555565cbbe <default_code_of_frame_writable(gdbarch*, frame_info*)>, print_registers_info = 0x5555558f65ba
<default_print_registers_info(gdbarch*, ui_file*, frame_info*, int, int)>,
print_float_info = 0x5555558e5e03 <i387_print_float_info(gdbarch*, ui_file*, frame_info*, char const*)>, print_vector_info = 0x0,
register_sim_regno = 0x55555565cab7 <legacy_register_sim_regno(gdbarch*, int)>,
cannot_fetch_register = 0x55555565ccc1 <cannot_register_not(gdbarch*, int)>,
cannot_store_register = 0x55555565ccc1 <cannot_register_not(gdbarch*, int)>,
get_longjmp_target = 0x5555556574a4 <amd64_get_longjmp_target(frame_info*, CORE_ADDR*)>, believe_pcc_promotion = 0,
convert_register_p = 0x5555558e6460 <i387_convert_register_p(gdbarch*, int, type*)>,
register_to_value = 0x5555558e64d7 <i387_register_to_value(frame_info*, int, type*, unsigned char*, int*, int*)>,
value_to_register = 0x5555558e6670 <i387_value_to_register(frame_info*, int, type*, unsigned char const*)>,
value_from_register = 0x55555586e7b9 <default_value_from_register(gdbarch*, type*, int, frame_id)>,
pointer_to_address = 0x55555586d428 <unsigned_pointer_to_address(gdbarch*, type*, unsigned char const*)>,
address_to_pointer = 0x55555586d4b0 <unsigned_address_to_pointer(gdbarch*, type*, unsigned char*, unsigned long)>, integer_to_address = 0x0,
return_value = 0x55555565300e <amd64_return_value(gdbarch*, value*, type*, regcache*, gdb_byte*, gdb_byte const*)>,
--Type <RET> for more, q to quit, c to continue without paging--
return_in_first_hidden_param_p = 0x55555565df38 <default_return_in_first_hidden_param_p(gdbarch*, type*)>,
skip_prologue = 0x5555556562c3 <amd64_skip_prologue(gdbarch*, CORE_ADDR)>, skip_main_prologue = 0x0, skip_entrypoint = 0x0,
inner_than = 0x55555565cbd5 <core_addr_lessthan(unsigned long, unsigned long)>,
breakpoint_from_pc = 0x55555565de91 <default_breakpoint_from_pc(gdbarch*, unsigned long*, int*)>,
breakpoint_kind_from_pc = 0x5555558e33d9 <bp_manipulation<1, &i386_break_insn>::kind_from_pc(gdbarch*, CORE_ADDR*)>,
sw_breakpoint_from_kind = 0x5555558e33f0 <bp_manipulation<1, &i386_break_insn>::bp_from_kind(gdbarch*, int, int*)>,
breakpoint_kind_from_current_state = 0x55555565ded6 <default_breakpoint_kind_from_current_state(gdbarch*, regcache*, unsigned long*)>,
adjust_breakpoint_address = 0x0, memory_insert_breakpoint = 0x55555598cdc5 <default_memory_insert_breakpoint(gdbarch*, bp_target_info*)>,
memory_remove_breakpoint = 0x55555598cf19 <default_memory_remove_breakpoint(gdbarch*, bp_target_info*)>, decr_pc_after_break = 0x1,
deprecated_function_start_offset = 0x0, remote_register_number = 0x555555af3104 <tdesc_remote_register_number(gdbarch*, int)>,
fetch_tls_load_module_address = 0x555555a8a7d8 <svr4_fetch_objfile_link_map(objfile*)>, get_thread_local_address = 0x0, frame_args_skip = 0x8,
unwind_pc = 0x5555558d42c5 <i386_unwind_pc(gdbarch*, frame_info*)>, unwind_sp = 0x5555558700af <default_unwind_sp(gdbarch*, frame_info*)>,
frame_num_args = 0x0, frame_align = 0x55555565735a <amd64_frame_align(gdbarch*, CORE_ADDR)>,
stabs_argument_has_addr = 0x55555565cefe <default_stabs_argument_has_addr(gdbarch*, type*)>, frame_red_zone_size = 128,
convert_from_func_ptr_addr = 0x55555565cc2b <convert_from_func_ptr_addr_identity(gdbarch*, unsigned long, target_ops*)>,
addr_bits_remove = 0x55555565cc15 <core_addr_identity(gdbarch*, unsigned long)>, significant_addr_bit = 0, software_single_step = 0x0,
single_step_through_delay = 0x0, print_insn = 0x5555558d86f9 <i386_print_insn(bfd_vma, disassemble_info*)>, skip_trampoline_code = 0x5555559c0103During symbol reading: Child DIE 0x16f79a9 and its abstract origin 0x16f79df have different parents
<find_solib_trampoline_target(frame_info*, unsigned long)>,
skip_solib_resolver = 0x5555558c1e78 <glibc_skip_solib_resolver(gdbarch*, unsigned long)>,
in_solib_return_trampoline = 0x55555565cb8c <generic_in_solib_return_trampoline(gdbarch*, unsigned long, char const*)>,
in_indirect_branch_thunk = 0x5555556575c7 <amd64_in_indirect_branch_thunk(gdbarch*, CORE_ADDR)>,
stack_frame_destroyed_p = 0x55555565cba7 <generic_stack_frame_destroyed_p(gdbarch*, unsigned long)>, elf_make_msymbol_special = 0x0,
coff_make_msymbol_special = 0x55555565cc59 <default_coff_make_msymbol_special(int, minimal_symbol*)>,
make_symbol_special = 0x55555565cc6b <default_make_symbol_special(symbol*, objfile*)>,
adjust_dwarf2_addr = 0x55555565cc7e <default_adjust_dwarf2_addr(unsigned long)>,
adjust_dwarf2_line = 0x55555565cc90 <default_adjust_dwarf2_line(unsigned long, int)>, cannot_step_breakpoint = 0, have_nonsteppable_watchpoint = 0,
address_class_type_flags = 0x0, address_class_type_flags_to_name = 0x0,
execute_dwarf_cfa_vendor_op = 0x55555565cca5 <default_execute_dwarf_cfa_vendor_op(gdbarch*, unsigned char, dwarf2_frame_state*)>,
address_class_name_to_type_flags = 0x0, register_reggroup_p = 0x55555564ed3e <amd64_linux_register_reggroup_p(gdbarch*, int, reggroup*)>,
fetch_pointer_argument = 0x5555558da3ba <i386_fetch_pointer_argument(frame_info*, int, type*)>,
iterate_over_regset_sections = 0x55555565004d <amd64_linux_iterate_over_regset_sections(gdbarch*, iterate_over_regset_sections_cb*, void*, regcache const*)>, make_corefile_notes = 0x55555595680a <linux_make_corefile_notes(gdbarch*, bfd*, int*)>,
find_memory_regions = 0x5555559550f5 <linux_find_memory_regions(gdbarch*, find_memory_region_ftype, void*)>, core_xfer_shared_libraries = 0x0,
core_xfer_shared_libraries_aix = 0x0, core_pid_to_str = 0x5555559520c7 <linux_core_pid_to_str(gdbarch*, ptid_t)>, core_thread_name = 0x0,
core_xfer_siginfo = 0x555555954891 <linux_core_xfer_siginfo(gdbarch*, gdb_byte*, ULONGEST, ULONGEST)>, gcore_bfd_target = 0x0,
--Type <RET> for more, q to quit, c to continue without paging--
vtable_function_descriptors = 0, vbit_in_delta = 0, skip_permanent_breakpoint = 0x55555565df9f <default_skip_permanent_breakpoint(regcache*)>,
max_insn_length = 16, displaced_step_copy_insn = 0x55555565436e <amd64_displaced_step_copy_insn(gdbarch*, unsigned long, unsigned long, regcache*)>,
displaced_step_hw_singlestep = 0x55555565ca21 <default_displaced_step_hw_singlestep(gdbarch*, displaced_step_closure*)>,
displaced_step_fixup = 0x55555565496d <amd64_displaced_step_fixup(gdbarch*, displaced_step_closure*, unsigned long, unsigned long, regcache*)>,
displaced_step_location = 0x555555957788 <linux_displaced_step_location(gdbarch*)>,
relocate_instruction = 0x555555654dd8 <amd64_relocate_instruction(gdbarch*, CORE_ADDR*, CORE_ADDR)>, overlay_update = 0x0,
core_read_description = 0x55555564ff89 <amd64_linux_core_read_description(gdbarch*, target_ops*, bfd*)>, static_transform_name = 0x0,
sofun_address_maybe_missing = 0, process_record = 0x5555558db118 <i386_process_record(gdbarch*, regcache*, unsigned long)>,
process_record_signal = 0x55555564fd7a <amd64_linux_record_signal(gdbarch*, regcache*, gdb_signal)>,
gdb_signal_from_target = 0x555555956c68 <linux_gdb_signal_from_target(gdbarch*, int)>,
gdb_signal_to_target = 0x555555956de9 <linux_gdb_signal_to_target(gdbarch*, gdb_signal)>,
get_siginfo_type = 0x5555558d0536 <x86_linux_get_siginfo_type(gdbarch*)>, record_special_symbol = 0x0,
get_syscall_number = 0x55555564ecb5 <amd64_linux_get_syscall_number(gdbarch*, thread_info*)>,
xml_syscall_file = 0x555555d3f538 "syscalls/amd64-linux.xml", syscalls_info = 0x0,
stap_integer_prefixes = 0x5555560586e0 <amd64_init_abi(gdbarch_info, gdbarch*, target_desc const*)::stap_integer_prefixes>,
stap_integer_suffixes = 0x0,
stap_register_prefixes = 0x5555560586f0 <amd64_init_abi(gdbarch_info, gdbarch*, target_desc const*)::stap_register_prefixes>,
stap_register_suffixes = 0x0,
stap_register_indirection_prefixes = 0x555556058700 <amd64_init_abi(gdbarch_info, gdbarch*, target_desc const*)::stap_register_indirection_prefixes>, stap_register_indirection_suffixes = 0x555556058710 <amd64_init_abi(gdbarch_info, gdbarch*, target_desc const*)::stap_register_indirection_suffixes>,
stap_gdb_register_prefix = 0x0, stap_gdb_register_suffix = 0x0,
stap_is_single_operand = 0x5555558d88d3 <i386_stap_is_single_operand(gdbarch*, char const*)>,
stap_parse_special_token = 0x5555558d9698 <i386_stap_parse_special_token(gdbarch*, stap_parse_info*)>, stap_adjust_register = 0x0,
dtrace_parse_probe_argument = 0x5555556502c3 <amd64_dtrace_parse_probe_argument(gdbarch*, expr_builder*, int)>,
dtrace_probe_is_enabled = 0x5555556501c1 <amd64_dtrace_probe_is_enabled(gdbarch*, CORE_ADDR)>,
dtrace_enable_probe = 0x55555565025d <amd64_dtrace_enable_probe(gdbarch*, CORE_ADDR)>,
dtrace_disable_probe = 0x555555650290 <amd64_dtrace_disable_probe(gdbarch*, CORE_ADDR)>, has_global_solist = 0, has_global_breakpoints = 0,
has_shared_address_space = 0x5555559520b0 <linux_has_shared_address_space(gdbarch*)>,
fast_tracepoint_valid_at = 0x5555558e14a7 <i386_fast_tracepoint_valid_at(gdbarch*, CORE_ADDR, std::string*)>,
guess_tracepoint_registers = 0x55555565e130 <default_guess_tracepoint_registers(gdbarch*, regcache*, unsigned long)>, auto_charset = 0x555555700a31
<default_auto_charset()>, auto_wide_charset = 0x555555700a42 <default_auto_wide_charset()>, solib_symbols_extension = 0x0,
has_dos_based_file_system = 0, gen_return_address = 0x5555556569cf <amd64_gen_return_address(gdbarch*, agent_expr*, axs_value*, CORE_ADDR)>,
info_proc = 0x555555952a8c <linux_info_proc(gdbarch*, char const*, info_proc_what)>,
core_info_proc = 0x555555954798 <linux_core_info_proc(gdbarch*, char const*, info_proc_what)>,
iterate_over_objfiles_in_search_order = 0x555555a8e1ea <svr4_iterate_over_objfiles_in_search_order(gdbarch*, iterate_over_objfiles_in_search_order_cb_--Type <RET> for more, q to quit, c to continue without paging--
ftype*, void*, objfile*)>, ravenscar_ops = 0x0, insn_is_call = 0x5555556548dd <amd64_insn_is_call(gdbarch*, CORE_ADDR)>,
insn_is_ret = 0x55555565490d <amd64_insn_is_ret(gdbarch*, CORE_ADDR)>, insn_is_jump = 0x55555565493d <amd64_insn_is_jump(gdbarch*, CORE_ADDR)>,
auxv_parse = 0x0, print_auxv_entry = 0x55555566f6ab <default_print_auxv_entry(gdbarch*, ui_file*, unsigned long, unsigned long)>,
vsyscall_range = 0x5555559573be <linux_vsyscall_range(gdbarch*, mem_range*)>,
infcall_mmap = 0x555555957447 <linux_infcall_mmap(CORE_ADDR, unsigned int)>,
infcall_munmap = 0x55555595764d <linux_infcall_munmap(CORE_ADDR, CORE_ADDR)>,
gcc_target_options = 0x55555565e06f <default_gcc_target_options[abi:cxx11](gdbarch*)>,
gnu_triplet_regexp = 0x5555558d9c7b <i386_gnu_triplet_regexp(gdbarch*)>,
addressable_memory_unit_size = 0x55555565e11d <default_addressable_memory_unit_size(gdbarch*)>, disassembler_options_implicit = 0x0,
disassembler_options = 0x0, valid_disassembler_options = 0x0, type_align = 0x5555558e1cc5 <i386_type_align(gdbarch*, type*)>,
get_pc_address_flags = 0x55555565e3c1 <default_get_pc_address_flags[abi:cxx11](frame_info*, unsigned long)>}
(top-gdb) bt
#0 bkpt_print_mention (b=0x2ffffd7f0) at ../../gdb/breakpoint.c:12431
#1 0x000055555569d844 in mention (b=0x5555561e5820) at ../../gdb/breakpoint.c:8511
#2 0x000055555569c84e in install_breakpoint (internal=0, arg=..., update_gll=0) at ../../gdb/breakpoint.c:8138
#3 0x000055555569e982 in create_breakpoint_sal (gdbarch=0x55555625bb40, sals=..., location=..., filter=std::unique_ptr<char> = {...},
根据 loc_gdbarch
进行猜测 为 default_breakpoint_from_pc
, 然后打断点
(gdb) b main
Breakpoint 1 at 0x5555555551bf: file ./variable.c, line 12.
b default_breakpoint_from_pc
(top-gdb) bt
#0 default_breakpoint_from_pc (gdbarch=0x55555615cde0 <inferior_ptid>, pcptr=0x555555da0340 <null_ptid>, lenptr=0x7fffffffd8f8)
at ../../gdb/arch-utils.c:832
#1 0x0000555555886700 in gdbarch_breakpoint_from_pc (gdbarch=0x55555625bb40, pcptr=0x7fffffffd460, lenptr=0x7fffffffd45c) at ../../gdb/gdbarch.c:2826
#2 0x000055555569dabf in program_breakpoint_here_p (gdbarch=0x55555625bb40, address=0x11bf) at ../../gdb/breakpoint.c:8593
#3 0x000055555569dcc0 in bp_loc_is_permanent (loc=0x5555561838d0) at ../../gdb/breakpoint.c:8632
#4 0x000055555569da65 in add_location_to_breakpoint (b=0x5555561e5820, sal=0x7fffffffd5b0) at ../../gdb/breakpoint.c:8575
#5 0x000055555569a2d1 in init_raw_breakpoint (b=0x5555561e5820, gdbarch=0x55555625bb40, sal=..., bptype=bp_breakpoint,
(top-gdb) s
bp_manipulation<1, &i386_break_insn>::kind_from_pc (gdbarch=0x7ffff79ef648 <__GI_bsearch+88>, pcptr=0x7fffffffd3f8) at ../../gdb/arch-utils.h:35
35 kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
(top-gdb) p bpoint
$33 = (const gdb_byte *) 0x555555da7a9e <i386_break_insn> "\314displaced: copy %s->%s: "
i386_break_insn: 信息
// gdb/i386-tdep.c L:609
constexpr gdb_byte i386_break_insn[] = { 0xcc }; /* int 3 */
#define BP_MANIPULATION(BREAK_INSN) \
bp_manipulation<sizeof (BREAK_INSN), BREAK_INSN>
template <size_t bp_size, const gdb_byte *break_insn>
struct bp_manipulation
{
static int
kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
{
return bp_size;
}
static const gdb_byte *
bp_from_kind (struct gdbarch *gdbarch, int kind, int *size)
{
*size = kind;
return break_insn;
}
};
typedef BP_MANIPULATION (i386_break_insn) i386_breakpoint;
set_gdbarch_breakpoint_kind_from_pc (gdbarch, i386_breakpoint::kind_from_pc);
set_gdbarch_sw_breakpoint_from_kind (gdbarch, i386_breakpoint::bp_from_kind);
int program_breakpoint_here_p (struct gdbarch *gdbarch, CORE_ADDR address)
{
int len;
CORE_ADDR addr;
const gdb_byte *bpoint;
gdb_byte *target_mem;
addr = address;
bpoint = gdbarch_breakpoint_from_pc (gdbarch, &addr, &len);
/* Software breakpoints unsupported? */
if (bpoint == NULL)
return 0;
target_mem = (gdb_byte *) alloca (len);
/* Enable the automatic memory restoration from breakpoints while
we read the memory. Otherwise we could say about our temporary
breakpoints they are permanent. */
scoped_restore restore_memory
= make_scoped_restore_show_memory_breakpoints (0);
if (target_read_memory (address, target_mem, len) == 0
&& memcmp (target_mem, bpoint, len) == 0)
return 1;
return 0;
}
再进行定位:
b init_breakpoint_sal
b set_breakpoint_location_function
// 还没有设置断点位置
(top-gdb) p b->number
$22 = 0
void break_command (const char *arg, int from_tty)
{
break_command_1 (arg, 0, from_tty);
}
// https://github.com/bminor/binutils-gdb/blob/gdb-9-branch/gdb/breakpoint.c#L9379
static void
break_command_1 (const char *arg, int flag, int from_tty)
{
int tempflag = flag & BP_TEMPFLAG;
enum bptype type_wanted = (flag & BP_HARDWAREFLAG
? bp_hardware_breakpoint
: bp_breakpoint);
event_location_up location = string_to_event_location (&arg, current_language);
const struct breakpoint_ops *ops = breakpoint_ops_for_event_location
(location.get (), false /* is_tracepoint */);
create_breakpoint (get_current_arch (),
location.get (),
NULL, 0, arg, 1 /* parse arg */,
tempflag, type_wanted,
0 /* Ignore count */,
pending_break_support,
ops,
from_tty,
1 /* enabled */,
0 /* internal */,
0);
}
int
create_breakpoint (struct gdbarch *gdbarch,
const struct event_location *location,
const char *cond_string,
int thread, const char *extra_string,
int parse_extra,
int tempflag, enum bptype type_wanted,
int ignore_count,
enum auto_boolean pending_break_support,
const struct breakpoint_ops *ops,
int from_tty, int enabled, int internal,
unsigned flags)
{
struct linespec_result canonical;
int pending = 0;
int task = 0;
int prev_bkpt_count = breakpoint_count;
gdb_assert (ops != NULL);
/* If extra_string isn't useful, set it to NULL. */
if (extra_string != NULL && *extra_string == '\0')
extra_string = NULL;
try
{
ops->create_sals_from_location (location, &canonical, type_wanted);
}
catch (const gdb_exception_error &e)
{
/* If caller is interested in rc value from parse, set
value. */
if (e.error == NOT_FOUND_ERROR)
{
/* If pending breakpoint support is turned off, throw
error. */
if (pending_break_support == AUTO_BOOLEAN_FALSE)
throw;
exception_print (gdb_stderr, e);
/* If pending breakpoint support is auto query and the user
selects no, then simply return the error code. */
if (pending_break_support == AUTO_BOOLEAN_AUTO
&& !nquery (_("Make %s pending on future shared library load? "),
bptype_string (type_wanted)))
return 0;
/* At this point, either the user was queried about setting
a pending breakpoint and selected yes, or pending
breakpoint behavior is on and thus a pending breakpoint
is defaulted on behalf of the user. */
pending = 1;
}
else
throw;
}
if (!pending && canonical.lsals.empty ())
return 0;
/* Resolve all line numbers to PC's and verify that the addresses
are ok for the target. */
if (!pending)
{
for (auto &lsal : canonical.lsals)
breakpoint_sals_to_pc (lsal.sals);
}
/* Fast tracepoints may have additional restrictions on location. */
if (!pending && type_wanted == bp_fast_tracepoint)
{
for (const auto &lsal : canonical.lsals)
check_fast_tracepoint_sals (gdbarch, lsal.sals);
}
/* Verify that condition can be parsed, before setting any
breakpoints. Allocate a separate condition expression for each
breakpoint. */
if (!pending)
{
gdb::unique_xmalloc_ptr<char> cond_string_copy;
gdb::unique_xmalloc_ptr<char> extra_string_copy;
if (parse_extra)
{
char *rest;
char *cond;
const linespec_sals &lsal = canonical.lsals[0];
/* Here we only parse 'arg' to separate condition
from thread number, so parsing in context of first
sal is OK. When setting the breakpoint we'll
re-parse it in context of each sal. */
find_condition_and_thread (extra_string, lsal.sals[0].pc,
&cond, &thread, &task, &rest);
cond_string_copy.reset (cond);
extra_string_copy.reset (rest);
}
else
{
if (type_wanted != bp_dprintf
&& extra_string != NULL && *extra_string != '\0')
error (_("Garbage '%s' at end of location"), extra_string);
/* Create a private copy of condition string. */
if (cond_string)
cond_string_copy.reset (xstrdup (cond_string));
/* Create a private copy of any extra string. */
if (extra_string)
extra_string_copy.reset (xstrdup (extra_string));
}
ops->create_breakpoints_sal (gdbarch, &canonical,
std::move (cond_string_copy),
std::move (extra_string_copy),
type_wanted,
tempflag ? disp_del : disp_donttouch,
thread, task, ignore_count, ops,
from_tty, enabled, internal, flags);
}
else
{
std::unique_ptr <breakpoint> b = new_breakpoint_from_type (type_wanted);
init_raw_breakpoint_without_location (b.get (), gdbarch, type_wanted, ops);
b->location = copy_event_location (location);
if (parse_extra)
b->cond_string = NULL;
else
{
/* Create a private copy of condition string. */
b->cond_string = cond_string != NULL ? xstrdup (cond_string) : NULL;
b->thread = thread;
}
/* Create a private copy of any extra string. */
b->extra_string = extra_string != NULL ? xstrdup (extra_string) : NULL;
b->ignore_count = ignore_count;
b->disposition = tempflag ? disp_del : disp_donttouch;
b->condition_not_parsed = 1;
b->enable_state = enabled ? bp_enabled : bp_disabled;
if ((type_wanted != bp_breakpoint
&& type_wanted != bp_hardware_breakpoint) || thread != -1)
b->pspace = current_program_space;
install_breakpoint (internal, std::move (b), 0);
}
if (canonical.lsals.size () > 1)
{
warning (_("Multiple breakpoints were set.\nUse the "
"\"delete\" command to delete unwanted breakpoints."));
prev_breakpoint_count = prev_bkpt_count;
}
update_global_location_list (UGLL_MAY_INSERT);
return 1;
}
// 根据输出进行全局搜索,定位函数
static void bkpt_print_mention (struct breakpoint *b)
{
if (current_uiout->is_mi_like_p ())
return;
switch (b->type)
{
case bp_breakpoint:
case bp_gnu_ifunc_resolver:
if (b->disposition == disp_del)
printf_filtered (_("Temporary breakpoint"));
else
printf_filtered (_("Breakpoint"));
printf_filtered (_(" %d"), b->number);
if (b->type == bp_gnu_ifunc_resolver)
printf_filtered (_(" at gnu-indirect-function resolver"));
break;
case bp_hardware_breakpoint:
printf_filtered (_("Hardware assisted breakpoint %d"), b->number);
break;
case bp_dprintf:
printf_filtered (_("Dprintf %d"), b->number);
break;
}
say_where (b);
}
gdb) r
Starting program: /home/ostest/test/gdb-9.2/build/variable
[Detaching after vfork from child process 13054]
[Detaching after fork from child process 13055]
[Detaching after fork from child process 13057]
(top-gdb) bt
#0 default_breakpoint_from_pc (gdbarch=0x5555562b41d0, pcptr=0x555555da0340 <null_ptid>,
lenptr=0x55555564e43d <ptid_t::operator!=(ptid_t const&) const+39>) at ../../gdb/arch-utils.c:832
#1 0x0000555555886700 in gdbarch_breakpoint_from_pc (gdbarch=0x55555625bb40, pcptr=0x7fffffffd560, lenptr=0x7fffffffd55c) at ../../gdb/gdbarch.c:2826
#2 0x000055555569dabf in program_breakpoint_here_p (gdbarch=0x55555625bb40, address=0x5555555551bf) at ../../gdb/breakpoint.c:8593
#3 0x000055555569dcc0 in bp_loc_is_permanent (loc=0x5555562c6380) at ../../gdb/breakpoint.c:8632
#4 0x000055555569da65 in add_location_to_breakpoint (b=0x5555561e5820, sal=0x5555562c6320) at ../../gdb/breakpoint.c:8575
#5 0x00005555556aa63a in update_breakpoint_locations (b=0x5555561e5820, filter_pspace=0x555556239b70, sals=..., sals_end=...)
at ../../gdb/breakpoint.c:13480
#6 0x00005555556ab078 in breakpoint_re_set_default (b=0x5555561e5820) at ../../gdb/breakpoint.c:13669
#7 0x00005555556a78ab in bkpt_re_set (b=0x5555561e5820) at ../../gdb/breakpoint.c:12320
#8 0x00005555556ab420 in breakpoint_re_set_one (b=0x5555561e5820) at ../../gdb/breakpoint.c:13741
#9 0x00005555556ab4f1 in breakpoint_re_set () at ../../gdb/breakpoint.c:13779
During symbol reading: .debug_line address at offset 0x340f39 is 0 [in module /home/ostest/test/gdb-9.2/build/gdb/gdb]
During symbol reading: Child DIE 0x17b79cf and its abstract origin 0x17bb960 have different parents
During symbol reading: Multiple children of DIE 0x17b8b03 refer to DIE 0x17b8af3 as their abstract origin
During symbol reading: cannot get low and high bounds for subprogram DIE at 0x17bb984
#10 0x00005555559db6ae in objfile_relocate (objfile=0x555556260c00, new_offsets=0x7fffffffd9c0) at ../../gdb/objfiles.c:866
#11 0x0000555555a8dd22 in svr4_relocate_main_executable () at ../../gdb/solib-svr4.c:2967
#12 0x0000555555a8ddfb in svr4_solib_create_inferior_hook (from_tty=0) at ../../gdb/solib-svr4.c:3010
#13 0x0000555555a951c9 in solib_create_inferior_hook (from_tty=0) at ../../gdb/solib.c:1211
#14 0x00005555558f26ca in post_create_inferior (target=0x555556147b30 <the_amd64_linux_nat_target>, from_tty=0) at ../../gdb/infcmd.c:458
#15 0x00005555558f2cbd in run_command_1 (args=0x0, from_tty=1, run_how=RUN_NORMAL) at ../../gdb/infcmd.c:654
修改内存:
b target_write_memory
(gdb) b main
Breakpoint 1 at 0x11bf: file ./variable.c, line 12.
(gdb) r
(top-gdb) bt
#0 target_write_memory (memaddr=0x5555562ff170, myaddr=0x10 <error: Cannot access memory at address 0x10>, len=5802559526894952704)
at ../../gdb/target.c:1335
#1 0x00005555557648dd in write_memory (memaddr=0x555555555042, myaddr=0x5555562bc710 "\220\350\225W\001", len=16) at ../../gdb/corefile.c:376
#2 0x00005555556544b4 in amd64_displaced_step_copy_insn (gdbarch=0x5555562bd200, from=0x7ffff7fd37b5, to=0x555555555042, regs=0x555556272ea0)
at ../../gdb/amd64-tdep.c:1505
#3 0x000055555588a364 in gdbarch_displaced_step_copy_insn (gdbarch=0x5555562bd200, from=0x7ffff7fd37b5, to=0x555555555042, regs=0x555556272ea0)
at ../../gdb/gdbarch.c:3940
#4 0x0000555555901a67 in displaced_step_prepare_throw (tp=0x5555562b41d0) at ../../gdb/infrun.c:1725
#5 0x0000555555901c3a in displaced_step_prepare (thread=0x5555562b41d0) at ../../gdb/infrun.c:1769
#6 0x0000555555903215 in resume_1 (sig=GDB_SIGNAL_0) at ../../gdb/infrun.c:2408
#7 0x0000555555903811 in resume (sig=GDB_SIGNAL_0) at ../../gdb/infrun.c:2604
#8 0x000055555590f247 in keep_going_pass_signal (ecs=0x7fffffffdfb0) at ../../gdb/infrun.c:7549
#9 0x000055555590f3b7 in keep_going (ecs=0x7fffffffdfb0) at ../../gdb/infrun.c:7568
#10 0x000055555590c1bd in process_event_stop_test (ecs=0x7fffffffdfb0) at ../../gdb/infrun.c:6231
#11 0x000055555590b8aa in handle_signal_stop (ecs=0x7fffffffdfb0) at ../../gdb/infrun.c:5936
#12 0x0000555555909b97 in handle_inferior_event (ecs=0x7fffffffdfb0) at ../../gdb/infrun.c:5134
#13 0x000055555590690f in fetch_inferior_event (client_data=0x0) at ../../gdb/infrun.c:3736
#14 0x00005555558eb63e in inferior_event_handler (event_type=INF_REG_EVENT, client_data=0x0) at ../../gdb/inf-loop.c:43
#15 0x0000555555949319 in handle_target_event (error=0, client_data=0x0) at ../../gdb/linux-nat.c:4227
#16 0x0000555555854a47 in handle_file_event (file_ptr=0x55555624fb70, ready_mask=1) at ../../gdb/event-loop.c:731
(top-gdb) c
(top-gdb) bt
#0 target_write_memory (memaddr=0x7fffffffda00, myaddr=0x55555615cde0 <inferior_ptid> "V3", len=140737488345512) at ../../gdb/target.c:1335
#1 0x00005555557648dd in write_memory (memaddr=0x555555555042, myaddr=0x5555562db9b0 "\036\372\061\355I\211\321^H\211\342H\203\344\360P\320T,VUU",
len=16) at ../../gdb/corefile.c:376
#2 0x0000555555901dae in write_memory_ptid (ptid=..., memaddr=0x555555555042,
myaddr=0x5555562db9b0 "\036\372\061\355I\211\321^H\211\342H\203\344\360P\320T,VUU", len=16) at ../../gdb/infrun.c:1810
#3 0x0000555555901e66 in displaced_step_restore (displaced=0x55555623c6a8, ptid=...) at ../../gdb/infrun.c:1821
#4 0x0000555555901fb2 in displaced_step_fixup (event_thread=0x5555562b41d0, signal=GDB_SIGNAL_TRAP) at ../../gdb/infrun.c:1849
#5 0x000055555590a466 in finish_step_over (ecs=0x7fffffffdfb0) at ../../gdb/infrun.c:5282
#6 0x000055555590a7f9 in handle_signal_stop (ecs=0x7fffffffdfb0) at ../../gdb/infrun.c:5411
(top-gdb) c
Continuing.
Breakpoint 1, main () at ./variable.c:12
12 int main() {
(gdb) c
#2 0x00005555556544b4 in amd64_displaced_step_copy_insn (gdbarch=0x5555562bd200, from=0x5555555551bf, to=0x555555555042, regs=0x555556272ea0)
at ../../gdb/amd64-tdep.c:1505
#3 0x000055555588a364 in gdbarch_displaced_step_copy_insn (gdbarch=0x5555562bd200, from=0x5555555551bf, to=0x555555555042, regs=0x555556272ea0)
at ../../gdb/gdbarch.c:3940
#4 0x0000555555901a67 in displaced_step_prepare_throw (tp=0x5555562b41d0) at ../../gdb/infrun.c:1725
#5 0x0000555555901c3a in displaced_step_prepare (thread=0x5555562b41d0) at ../../gdb/infrun.c:1769
#6 0x0000555555903215 in resume_1 (sig=GDB_SIGNAL_0) at ../../gdb/infrun.c:2408
#7 0x0000555555903811 in resume (sig=GDB_SIGNAL_0) at ../../gdb/infrun.c:2604
#8 0x000055555590f247 in keep_going_pass_signal (ecs=0x7fffffffd860) at ../../gdb/infrun.c:7549
#9 0x00005555559024d6 in start_step_over () at ../../gdb/infrun.c:2001
#10 0x000055555590464d in proceed (addr=0xffffffffffffffff, siggnal=GDB_SIGNAL_DEFAULT) at ../../gdb/infrun.c:2977
#11 0x00005555558f3067 in continue_1 (all_threads=0) at ../../gdb/infcmd.c:803
#12 0x00005555558f3370 in continue_command (args=0x0, from_tty=1) at ../../gdb/infcmd.c:895
#13 0x000055555570eeca in do_const_cfunc (c=0x5555561e07f0, args=0x0, from_tty=1) at ../../gdb/cli/cli-decode.c:107
根据上面的事件回调,调用猜测调用 print_command
, 然后进行搜索
c = add_com ("print", class_vars, print_command, print_help.c_str ());
set_cmd_completer_handle_brkchars (c, print_command_completer);
add_com_alias ("p", "print", class_vars, 1);
/* Implementation of the "print" and "call" commands. */
static void print_command_1 (const char *args, int voidprint)
{
struct value *val;
value_print_options print_opts;
get_user_print_options (&print_opts);
/* Override global settings with explicit options, if any. */
auto group = make_value_print_options_def_group (&print_opts);
gdb::option::process_options
(&args, gdb::option::PROCESS_OPTIONS_REQUIRE_DELIMITER, group);
print_command_parse_format (&args, "print", &print_opts);
const char *exp = args;
if (exp != nullptr && *exp)
{
expression_up expr = parse_expression (exp);
val = evaluate_expression (expr.get ());
}
else
val = access_value_history (0);
if (voidprint || (val && value_type (val) &&
TYPE_CODE (value_type (val)) != TYPE_CODE_VOID))
print_value (val, print_opts);
}
b print_command_1
p group
$51 = {options = {m_array = 0x555556163740 <value_print_option_defs>, m_size = 14}, ctx = 0x7fffffffdc60}
(top-gdb) p args
$52 = 0x5555561819d2 "&a"
(top-gdb) p *expr.get()
$55 = {language_defn = 0x55555611eb80 <c_language_defn>, gdbarch = 0x5555562bd2c0, nelts = 5, elts = {{opcode = UNOP_ADDR, symbol = 0x3e,
msymbol = 0x3e, longconst = 62, floatconst = ">", '\000' <repeats 14 times>, string = 62 '>', type = 0x3e, internalvar = 0x3e, block = 0x3e,
objfile = 0x3e}}}
(top-gdb) p *val
$57 = {lval = not_lval, modifiable = 1, lazy = 0, initialized = 1, stack = 0, location = {address = 0x0, reg = {regnum = 0, next_frame_id = {
stack_addr = 0x0, code_addr = 0x0, special_addr = 0x0, stack_status = FID_STACK_INVALID, code_addr_p = 0, special_addr_p = 0,
artificial_depth = 0}}, internalvar = 0x0, xm_worker = 0x0, computed = {funcs = 0x0, closure = 0x0}}, offset = 0, bitsize = 0, bitpos = 0,
reference_count = 1, parent = {m_obj = 0x0}, type = 0x55555629da90, enclosing_type = 0x55555629da90, embedded_offset = 0, pointed_to_offset = 0,
contents = std::unique_ptr<unsigned char> = {get() = 0x55555636b440 "0\342\377\377\377\177"}, unavailable = std::vector of length 0, capacity 0,
optimized_out = std::vector of length 0, capacity 0}
(top-gdb) c
Continuing.
$1 = (long *) 0x7fffffffe230
b evaluate_subexp
retval = (*exp->language_defn->la_exp_desc->evaluate_exp)
(expect_type, exp, pos, noside);
(top-gdb) s
evaluate_subexp_c (expect_type=0x7fffffffdc30, exp=0x7fffffffdbd0, pos=0x0, noside=EVAL_NORMAL) at ../../gdb/c-lang.c:584
// gdb/eval.c L:2701
case UNOP_ADDR:
/* C++: check for and handle pointer to members. */
if (noside == EVAL_SKIP)
{
evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP);
return eval_skip_value (exp);
}
else
{
struct value *retvalp = evaluate_subexp_for_address (exp, pos,
noside);
return retvalp;
}
(top-gdb) s
evaluate_subexp_for_address (exp=0x55555629d6f8, pos=0x55555629d7f8, noside=(EVAL_SKIP | EVAL_AVOID_SIDE_EFFECTS | unknown: 32764))
at ../../gdb/eval.c:2985
(top-gdb) p op
$63 = OP_VAR_VALUE
case OP_VAR_VALUE:
var = exp->elts[pc + 2].symbol;
p *var
$65 = {<general_symbol_info> = {name = 0x555556271200 "a", value = {ivalue = 0, block = 0x0, bytes = 0x0, address = 0x0, common_block = 0x0,
chain = 0x0}, language_specific = {obstack = 0x0, demangled_name = 0x0}, language = language_c, ada_mangled = 0,
section = -1}, <allocate_on_obstack> = {<No data fields>}, type = 0x55555629c870, owner = {symtab = 0x555556255f00, arch = 0x555556255f00},
domain = VAR_DOMAIN, aclass_index = 17, is_objfile_owned = 1, is_argument = 1, is_inlined = 0, maybe_copied = 0, subclass = SYMBOL_NONE, line = 1,
aux_value = 0x55555629d130, hash_next = 0x0}
return address_of_variable (var, exp->elts[pc + 1].block);
(top-gdb) p *type
$70 =
{pointer_type = 0x55555629da90,
reference_type = 0x0,
chain = 0x0,
instance_flags = 0,
length = 8,
main_type = 0x55555629c8b0}
top-gdb) n
1311 CORE_ADDR addr = value_address (val);
(top-gdb) n
1519 return value->location.address + value->offset;
(top-gdb) p addr
$73 = 0x7fffffffe230