简体   繁体   English

Apples GCC 在哪里/如何将 DWARF 存储在可执行文件中

[英]where/how does Apples GCC store DWARF inside an executable

Where/how does Apples GCC store DWARF inside an executable? Apples GCC 在哪里/如何将 DWARF 存储在可执行文件中?

I compiled a binary via gcc -gdwarf-2 (Apples GCC).我通过gcc -gdwarf-2 (Apples GCC) 编译了一个二进制文件。 However, neither objdump -g nor objdump -h does show me any debug information.但是, objdump -gobjdump -h都没有向我显示任何调试信息。

Also libbfd does not find any debug information. libbfd 也没有找到任何调试信息。 (I asked on the binutils-mailinglist about it here .) (我在 binutils-mailinglist 上询问它。)

I am able however to extract the debugging information via dsymutil (into a dSYM).但是,我能够通过dsymutil (到 dSYM)提取调试信息。 libbfd is also able to read those debug info then. libbfd 也能够读取这些调试信息。

On Mac OS X there was a decision to have the linker id not process all of the debug information when you link your program.在 Mac OS X 上,当您链接您的程序时,决定让 linker id不处理所有调试信息。 The debug information is often 10x the size of the program executable so having the linker process all of the debug info and include it in the executable binary was a serious detriment to link times.调试信息通常是可执行程序大小的10x ,因此让 linker 处理所有调试信息并将其包含在可执行二进制文件中会严重影响链接时间。 For iterative development - compile, link, compile, link, debug, compile link - this was a real hit.对于迭代开发——编译、链接、编译、链接、调试、编译链接——这是一个真正的成功。

Instead, the compiler generates the DWARF debug information in the.s files, the assembler outputs it in the.o files, and the linker includes a "debug map" in the executable binary which tells debug info users where all of the symbols were relocated during the link.相反,编译器在 .s 文件中生成DWARF调试信息,汇编器在 .o 文件中输出它,而 linker 在可执行二进制文件中包含一个“调试映射”,它告诉调试信息用户所有符号被重新定位的位置在链接期间。

A consumer (doing.o-file debugging) loads the debug map from the executable and processes all of the DWARF in the.o files as-needed, remapping the symbols as per the debug map's instructions.消费者(进行 .o 文件调试)从可执行文件加载调试 map 并根据需要处理 .o 文件中的所有 DWARF,根据调试映射的说明重新映射符号。

dsymutil can be thought of as a debug info linker. It does this same process -- read the debug map, load the DWARF from the.o files, relocate all the addresses -- and then outputs a single binary of all the DWARF at their final, linked addresses. dsymutil可以被认为是调试信息 linker。它执行相同的过程——读取调试 map,从 .o 文件加载 DWARF,重新定位所有地址——然后在它们的位置输出所有 DWARF 的单个二进制文件最终链接地址。 This is the dSYM bundle.这是 dSYM 包。

Once you have a dSYM bundle, you've got plain old standard DWARF that any dwarf reading tool (which can deal with Mach-O binary files) can process.一旦你有了 dSYM 包,你就有了普通的旧标准 DWARF,任何 dwarf 阅读工具(可以处理 Mach-O 二进制文件)都可以处理。

There is an additional refinement that makes all of this work, the UUIDs included in Mach-O binaries. Mach-O 二进制文件中包含的 UUID 使所有这些工作都进行了额外的改进。 Every time the linker creates a binary, it emits a 128-bit UUID in the LC_UUID load command (v. otool -hlv or dwarfdump --uuid ).每次 linker 创建二进制文件时,它都会在 LC_UUID 加载命令( otool -hlvdwarfdump --uuid )中发出一个 128 位 UUID。 This uniquely identifies that binary file.这唯一标识该二进制文件。 When dsymutil creates the dSYM, it includes that UUID.dsymutil创建 dSYM 时,它包含该 UUID。 The debuggers will only associate a dSYM and an executable if they have matching UUIDs -- no dodgy file mod timestamps or anything like that.如果调试器具有匹配的 UUID,调试器只会将 dSYM 和可执行文件相关联——没有狡猾的文件 mod 时间戳或类似的东西。

We can also use the UUIDs to locate the dSYMs for binaries.我们还可以使用 UUID 来定位二进制文件的 dSYM。 They show up in crash reports, we include a Spotlight importer that you can use to search for them, eg mdfind "com_apple_xcode_dsym_uuids == E21A4165-29D5-35DC-D08D-368476F85EE1" if the dSYM is located in a Spotlight indexed location.它们出现在崩溃报告中,我们包含一个 Spotlight 导入程序,您可以使用它来搜索它们,例如,如果 dSYM 位于 Spotlight 索引位置,则mdfind "com_apple_xcode_dsym_uuids == E21A4165-29D5-35DC-D08D-368476F85EE1" You can even have a repository of dSYMs for your company and a program that can retrieve the correct dSYM given a UUID - maybe a little mysql database or something like that - so you run the debugger on a random executable and you instantly have all the debug info for that executable.您甚至可以为您的公司拥有一个 dSYM 存储库和一个程序,该程序可以在给定 UUID 的情况下检索正确的 dSYM - 可能是一个小的 mysql 数据库或类似的东西 - 所以你在随机可执行文件上运行调试器,你会立即获得所有调试该可执行文件的信息。 There are some pretty neat things you can do with the UUIDs.您可以使用 UUID 做一些非常巧妙的事情。

But anyway, to answer your original question: The unstripped binary has the debug map, the.o files have the DWARF, and when dsymutil is run these are combined to create the dSYM bundle.但无论如何,要回答你原来的问题:未剥离的二进制文件有调试 map,.o 文件有 DWARF,当运行dsymutil时,它们被组合以创建 dSYM 包。

If you want to see the debug map entries, do nm -pa executable and they're all there.如果您想查看调试 map 条目,请执行nm -pa executable ,它们都在那里。 They are in the form of the old stabs nlist records - the linker already knew how to process stabs so it was easiest to use them - but you'll see how it works without much trouble, maybe refer to some stabs documentation if you're uncertain.它们采用旧的 stabs nlist记录的形式 - linker 已经知道如何处理 stabs 所以使用它们最简单 - 但你会很容易地看到它是如何工作的,如果你是,也许可以参考一些 stabs 文档不确定。

It seems it actually doesn't.好像真的没有。

I traced dsymutil and it reads all the *.o files.我跟踪dsymutil ,它读取了所有*.o文件。 objdump -h also lists all the debug info in them. objdump -h还列出了其中的所有调试信息。

So it seems that those info isn't copied over to the binary.所以这些信息似乎没有复制到二进制文件中。


Some related comments about this can also be foundhere .关于此的一些相关评论也可以在这里找到。

It seems there are two ways for OSX to place debug information: OSX 似乎有两种放置调试信息的方法:

  1. In the .o object files used for compilation.在用于编译的.o object 文件中。 The binary stores a reference to these files (by absolute path).二进制文件存储对这些文件的引用(通过绝对路径)。

  2. In a separate bundle (directory) called.dSYM在一个名为.dSYM 的单独包(目录)中

If I compile with Apple's Clang using g++ -g main.cpp -o foo I get the bundle called foo.dSYM .如果我使用g++ -g main.cpp -o foo使用 Apple 的 Clang 进行编译,我会得到名为foo.dSYM的包。 However if I use CMake I get the debug info in the object files.但是,如果我使用 CMake,我会在 object 文件中获得调试信息。 I guess because it does a separate gcc -c main.cpp -o main.o step?我猜是因为它执行了一个单独的gcc -c main.cpp -o main.o步骤?

Anyway I found this command very useful for case 1:不管怎样,我发现这个命令对案例 1 非常有用:

$ dsymutil -dump-debug-map main
---
triple:          'x86_64-apple-darwin'
binary-path:     main
objects:         
  - filename:        /Users/tim/foo/build/CMakeFiles/main.dir/main.cpp.o
    timestamp:       1485951213
    symbols:         
      - { sym: __ZNSt3__111char_traitsIcE11eq_int_typeEii, objAddr: 0x0000000000000D50, binAddr: 0x0000000100001C90, size: 0x00000020 }
      - { sym: __ZNSt3__111char_traitsIcE6lengthEPKc, objAddr: 0x0000000000000660, binAddr: 0x00000001000015A0, size: 0x00000020 }
      - { sym: GCC_except_table3, objAddr: 0x0000000000000DBC, binAddr: 0x0000000100001E2C, size: 0x00000000 }
      - { sym: _main, objAddr: 0x0000000000000000, binAddr: 0x0000000100000F40, size: 0x00000090 }
      - { sym: __ZNSt3__124__put_character_sequenceIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_PKS4_m, objAddr: 0x00000000000001F0, binAddr: 0x0000000100001130, size: 0x00000470 }
      - { sym: ___clang_call_terminate, objAddr: 0x0000000000000D40, binAddr: 0x0000000100001C80, size: 0x00000010 }
      - { sym: GCC_except_table5, objAddr: 0x0000000000000E6C, binAddr: 0x0000000100001EDC, size: 0x00000000 }
      - { sym: __ZNSt3__116__pad_and_outputIcNS_11char_traitsIcEEEENS_19ostreambuf_iteratorIT_T0_EES6_PKS4_S8_S8_RNS_8ios_baseES4_, objAddr: 0x0000000000000680, binAddr: 0x00000001000015C0, size: 0x000006C0 }
      - { sym: __ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_, objAddr: 0x00000000000000E0, binAddr: 0x0000000100001020, size: 0x00000110 }
      - { sym: GCC_except_table2, objAddr: 0x0000000000000D7C, binAddr: 0x0000000100001DEC, size: 0x00000000 }
      - { sym: __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc, objAddr: 0x0000000000000090, binAddr: 0x0000000100000FD0, size: 0x00000050 }
      - { sym: __ZNSt3__111char_traitsIcE3eofEv, objAddr: 0x0000000000000D70, binAddr: 0x0000000100001CB0, size: 0x0000000B }
...

Apple stores debugging information in separate files named *.dSYM. Apple 将调试信息存储在名为 *.dSYM 的单独文件中。 You can run dwarfdump on those files and see the DWARF Debug Info Entries.您可以对这些文件运行 dwarfdump 并查看 DWARF 调试信息条目。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM