DWARF DIE 和跟踪变量的问题

问题描述 投票:0回答:1

我的编译器正在编写 DWARF DIE,我目前遇到跟踪变量的问题。 例如,缩写看起来像:

DW_AT_name         DW_FORM_string
DW_AT_decl_file    DW_FORM_data1
DW_AT_decl_line    DW_FORM_data1
DW_AT_decl_column  DW_FORM_data1
DW_AT_type         DW_FORM_ref4
DW_AT_location     DW_FORM_exprloc

缩写的 debug_info 如下所示:

DW_AT_name        : x
DW_AT_decl_file   : 1
DW_AT_decl_line   : 2
DW_AT_decl_column : 24
DW_AT_type        : <0x65>
DW_AT_location    : 2 byte block: 91 68      (DW_OP_fbreg: -24)

C 向该位置添加 -16 的偏移量,该位置在程序集中应为 -8(%rbp)。 在我的语言中,变量也存储在 -8(%rbp) 上,偏移量也为 -24。 除了 FORM_string 是 FORM_strp(我认为这在实际调试过程中没有区别)之外,我看不到任何其他差异。 为什么我的语言在使用 gdb 时会返回这样的错误,有什么原因吗?

(gdb) start
........ Not important
(gdb) watch x
Hardware watchpoint 2: x
(gdb) step
Warning:
Cannot insert breakpoint -1.
Cannot access memory at address 0x1

Command aborted.

我尝试删除-16偏移量,但无济于事。 注意:GDB版本15.2,使用gcc 14.2.1编译AT&T语法汇编。 DWARF 版本 5.

这是编译器生成的 asm 的示例

.file "main.zu"
.text
.globl main
.file 0 "main.zu"
.Ltext0:
.weak .Ltext0
.loc 0 1 6
    
.Ldie1_debug_start:
    
.type main, @function
main:
    .loc 0 1 17
    .cfi_startproc
    pushq %rbp
    .cfi_def_cfa_offset 16
    movq %rsp, %rbp
    .cfi_def_cfa_register 6
    .loc 0 1 26
    # Variable declaration for 'stinky'
    movq $415, -8(%rbp)
    # End of variable declaration for 'stinky'
    movq $913, -8(%rbp)
    movq $69, %rdi
    movq $60, %rax
    syscall # SYS_EXIT
    ret
    .Ldie1_debug_end:
.cfi_endproc
.size main, .-main
    .Ldebug_text0:
.section    .debug_info,"",@progbits
    
.long .Ldebug_end - .Ldebug_info
.Ldebug_info:
.weak .Ldebug_info
.word 0x5
.byte 0x1
.byte 0x8
.long .Ldebug_abbrev

.uleb128 1
.long .Ldebug_producer_string
.byte 0x8042
.long .Ldebug_file_string
.long .Ldebug_file_dir
.quad .Ltext0
.quad .Ldebug_text0 - .Ltext0
.long .Ldebug_line0
.uleb128 2
.long .Ldie1_string
.byte 0
.byte 1
.byte 17
.long .Lint_debug_type
.quad .Ldie1_debug_start
.quad .Ldie1_debug_end - .Ldie1_debug_start
.uleb128 0x01
.byte 0x9c
.uleb128 7
.long .Ldie2_string
.byte 0
.byte 2
.byte 7
.long .Lint_debug_type
.uleb128 0x02
.byte 0x91
.sleb128 -24
.byte 0

.Lint_debug_type:
.uleb128 8
.byte 8
.byte 5
.string "int"
.Lfloat_debug_type:
.uleb128 8
.byte 4
.byte 4
.string "float"
.Lstr_debug_type:
.uleb128 9
.byte 8
.long .Lchar_debug_type
.Lchar_debug_type:
.uleb128 8
.byte 1
.byte 6
.string "char"

.byte 0
.Ldebug_end:
.section .debug_abbrev,"",@progbits
.Ldebug_abbrev:

.uleb128 1
.uleb128 0x11 # TAG_compile_unit
.byte   0x1 # No children
.uleb128 0x25 # AT_producer
.uleb128 0xe # FORM_strp
.uleb128 0x13 # AT_language
.uleb128 0xb # FORM_data1
.uleb128 0x3 # AT_name
.uleb128 0x1f # FORM_line_strp
.uleb128 0x1b # AT_comp_dir
.uleb128 0x1f # FORM_line_strp
.uleb128 0x11 # AT_low_pc
.uleb128 0x1 # FORM_addr
.uleb128 0x12 # AT_high_pc
.uleb128 0x7 # FORM_data8
.uleb128 0x10 # AT_stmt_list
.uleb128 0x17 # FORM_sec_offset
.byte 0
.byte 0

.uleb128 2
.uleb128 0x2e # TAG_subprogram - FunctionNoParams, non-void
.byte 0x1 # Has children
.uleb128 0x3f # AT_external
.uleb128 0x19 # FORM_flag_present
.uleb128 0x3 # AT_name
.uleb128 0xe # FORM_strp
.uleb128 0x3a # AT_decl_file
.uleb128 0xb # FORM_data1
.uleb128 0x3b # AT_decl_line
.uleb128 0xb # FORM_data1
.uleb128 0x39 # AT_decl_column
.uleb128 0xb # FORM_data1
.uleb128 0x49 # AT_type
.uleb128 0x13 # FORM_ref4
.uleb128 0x11 # AT_low_pc
.uleb128 0x1 # FORM_addr
.uleb128 0x12 # AT_high_pc
.uleb128 0x7 # FORM_data8
.uleb128 0x40 # AT_frame_base
.uleb128 0x18 # FORM_exprloc
.uleb128 0x7a # AT_call_all_calls
.uleb128 0x19 # FORM_flag_present

.byte 0
.byte 0

.uleb128 7
.uleb128 0x34 # TAG_variable
.byte 0 # No children
.uleb128 0x3 # AT_name
.uleb128 0xe # FORM_strp
.uleb128 0x3a # AT_decl_file
.uleb128 0xb # FORM_data1
.uleb128 0x3b # AT_decl_line
.uleb128 0xb # FORM_data1
.uleb128 0x39 # AT_decl_column
.uleb128 0xb # FORM_data1
.uleb128 0x49 # AT_type
.uleb128 0x13 # FORM_ref4
.uleb128 0x2 # AT_location
.uleb128 0x18 # FORM_exprloc

.byte 0
.byte 0

.uleb128 8
.uleb128 0x24 # TAG_base_type
.byte   0 # no children
.uleb128 0xb # AT_byte_size
.uleb128 0xb # FORM_data1
.uleb128 0x3e # AT_encoding
.uleb128 0xb # FORM_data1
.uleb128 0x3 # AT_name
.uleb128 0x8 # FORM_string

.byte 0
.byte 0

.uleb128 9
.uleb128 0xF # TAG_pointer_type
.byte 0 # No children
.uleb128 0xB # AT_byte_size
.uleb128 0xb # FORM_data1
.uleb128 0x49 #  AT_type
.uleb128 0x13 #  FORM_ref4
.byte 0
.byte 0
.byte 0
.byte 0
.section .debug_aranges,"",@progbits
.Ldebug_aranges:
.long .Ldebug_aranges_end - 4 - .Ldebug_aranges
.value 0x5
.long .Ldebug_text0
.byte 0x8
.byte 0x0
.value 0
.value 0
.quad .Ltext0
.quad .Ldebug_text0-.Ltext0
.quad 0
.quad 0
.Ldebug_aranges_end:
.section .debug_line,"",@progbits
.Ldebug_line0:
.section .debug_str,"MS",@progbits,1
.Ldebug_producer_string: .string "Zura compiler v0.1.25"
.Ldie1_string: .string "main"

.Ldie2_string:
    .string "stinky"

.section .debug_line_str,"MS",@progbits,1
.Ldebug_file_string: .string "main.zu"
.Ldebug_file_dir: .string "zura_files"
assembly gcc x86-64 low-level dwarf
1个回答
0
投票

您忘记提供构建说明。仅当代码not链接到libc,而是

main
是进程入口点时,我才能重现该问题。在这种情况下,堆栈最上面的项目将是
argv
。当为局部变量添加观察点时,gdb 还会插入一个内部断点(我相信可以检测是否离开框架)。展开器使用堆栈最顶层的项作为断点的地址,假设这是返回地址。然而,在这种情况下,如果不使用命令行参数,则为
argv
,即
1
。这就是
Cannot access memory at address 0x1
错误的来源。您可以通过传递一个参数来验证这一点,其中您应该看到更改为
0x2
(或者无论您传递多少个参数 + 1)。如果您与 libc 链接,那将
call
您的
main
,因此堆栈上将有一个正确的返回地址,并且 gdb 不会被混淆:

Hardware watchpoint 2: stinky

Old value = 0
New value = 415
© www.soinside.com 2019 - 2024. All rights reserved.