gdb 调试记录

gdb 调试记录

  • 参考
    • 编译
    • 调试
  • 符号表读取
  • 信号接收
  • 断点
    • 源码
    • 执行程序
  • 打印
    • 调试

参考

  • gdb wiki
  • GDB 源码分析系列文章一:ptrace 系统调用和事件循环
  • gdb 镜像源码

编译

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

你可能感兴趣的:(debug,gdb)