【问题标题】:lldb does not allow to set breakpoint nor list the source filelldb 不允许设置断点也不允许列出源文件
【发布时间】:2021-04-22 05:33:00
【问题描述】:

具有以下汇编源:

# hello_asm.s
# as hello_asm.s -o hello_asm.o
# ld hello_asm.o -e _main -o hello_asm
.section __DATA,__data
str:
  .asciz "Hello world!\n"

.section __TEXT,__text
.globl _main
_main:
  movl $0x2000004, %eax           # preparing system call 4
  movl $1, %edi                    # STDOUT file descriptor is 1
  movq str@GOTPCREL(%rip), %rsi   # The value to print
  movq $100, %rdx                 # the size of the value to print
  syscall

#
# EXITING
#
  movl $0, %ebx
  movl $0x2000001, %eax           # exit 0
  syscall

通过编译和链接以下指令:

as sum.s -g -o sum.o
ld -arch x86_64 -e main -L /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/lib -lSystem sum.o -o sum

通过尝试在 LLDB 上对其进行调试,我得到以下结果:

❯❯❯❯ lldb sum.o                                                                                                                   ~/D/test
(lldb) target create "sum.o"
Current executable set to '/Users/mbertamini/Downloads/test/sum.o' (x86_64).
(lldb) list
(lldb) b 16
error: No selected frame to use to find the default file.
error: No file supplied and no default file available.
(lldb)

这是侏儒:

❯❯❯❯ dwarfdump sum.o                                                                                                                     ~/D/t/summ
sum.o:  file format Mach-O 64-bit x86-64

.debug_info contents:
0x00000000: Compile Unit: length = 0x00000094 version = 0x0004 abbr_offset = 0x0000 addr_size = 0x08 (next unit at 0x00000098)

0x0000000b: DW_TAG_compile_unit
              DW_AT_stmt_list   (0x00000000)
              DW_AT_low_pc  (0x0000000000000000)
              DW_AT_high_pc (0x0000000000000026)
              DW_AT_name    ("sum.s")
              DW_AT_comp_dir    ("<filepath>")
              DW_AT_producer    ("Apple clang version 12.0.0 (clang-1200.0.32.27)")
              DW_AT_language    (DW_LANG_Mips_Assembler)

0x0000007e:   DW_TAG_label
                DW_AT_name  ("main")
                DW_AT_decl_file ("<filepath-file>")
                DW_AT_decl_line (10)
                DW_AT_low_pc    (0x0000000000000000)
                DW_AT_prototyped    (0x00)

0x00000095:     DW_TAG_unspecified_parameters

0x00000096:     NULL

0x00000097:   NULL
❯❯❯❯ as -v                                                                                                                               ~/D/t/summ
Apple clang version 12.0.0 (clang-1200.0.32.27)
Target: x86_64-apple-darwin20.2.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
 "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang" -cc1as -triple x86_64-apple-macosx11.0.0 -filetype obj -main-file-name - -target-cpu penryn -fdebug-compilation-dir /Users/mbertamini/Downloads/test/summ -dwarf-debug-producer "Apple clang version 12.0.0 (clang-1200.0.32.27)" -dwarf-version=4 -mrelocation-model pic -o a.out -

有什么问题?我该怎么办?

【问题讨论】:

标签: macos assembly lldb macos-big-sur


【解决方案1】:

问题是应该使用映射调试信息的源文件(sum.s):

$ as sum.s -g -o sum.o
$ ld -arch x86_64 -e _main -macosx_version_min 10.13 -lSystem sum.o -o sum
$ lldb sum
(lldb) target create "sum"
Current executable set to 'sum' (x86_64).
(lldb) b sum.s:16
Breakpoint 1: where = sum`main + 26, address = 0x0000000100000fac
(lldb) 

在组装时使用 -O0 优化以及 -g 代码生成选项。
(这仅在使用 clang 编译时很重要;这不适用于 @ 987654325@)

lldb: resolving breakpoints to locations

【讨论】:

  • -O0 是否为as 做任何事情,汇编程序?对于 GNU Binutils,我认为 -O0 已经是默认值,例如它不会将mov $1, %rax 优化为mov $1, %eax。即使您的汇编程序优化了单个指令,也不应该阻止它提供有用的调试信息;指令的数量和顺序不会改变,只是有时它们的大小。 (对于.c 源文件,clang -O0clang -O2 非常不同)。我猜可能存在错误或设计限制,但这是一个令人惊讶的说法。
  • @PeterCordes:除了调试选项之外,设置优化级别会影响编译器是否可以正确关联调试映射对象。在上面的 OP 命令中,它真的归结为仅用于生成符号的命令;一般情况下,llvm 很常见。
  • @PeterCordes:如果你查看我之前发布的关于dSYM 的答案,有人说他们必须为-g 设置-O0 才能正常工作,所以我'我不确定那里发生了什么(也许他们设置了多个优化?)。但是在 llvm 文档中,他们确实提到“调试信息在 -O0 时效果最好。当指定了多个以 -g 开头的选项时,最后一个会获胜”......所以他们的意思是不管它是否是默认的都设置它不清楚。
  • 很明显,提到-O0 的 LLVM 文档是在谈论来自 C 或 LLVM-IR 的代码生成,而不仅仅是使用内置的汇编程序。就像我说的,使用-O2 -g 进行调试通常是可能的(在大多数平台上),但对于小规模单步执行而言,效果并不理想。组装.s从根本上不同于编译.c,因为使用.s,您已经指定了说明; LLVM 根本不做代码生成,只是将你的 asm 源代码 1:1 转换为机器代码。
  • 当然,当clang 必须有效地编写 .s 然后组装它时,它与您的clang -O0 -g foo.c 答案完全不同。 (与 GCC 不同,clang 实际上不会从 .c 生成文本 .s,它只是在进行代码生成之前使用内部数据结构。不过,GCC 确实如此。)无论如何,TL:DR : 这就是为什么我们强调“汇编”asm,而不是“编译”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-01
  • 2016-05-18
  • 2012-04-05
  • 1970-01-01
  • 2018-08-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多