苹果GCC在何处/如何将DWARF存储在可执行文件中 [英] where/how does Apples GCC store DWARF inside an executable

查看:203
本文介绍了苹果GCC在何处/如何将DWARF存储在可执行文件中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我通过 gcc -gdwarf-2 (苹果GCC)。但是, objdump -g objdump -h 都没有显示任何调试信息。



另外libbfd没有找到任何调试信息。 (我在binutils邮件列表上询问了这里。)



然而,我可以通过 dsymutil (进入dSYM)提取调试信息。 libbfd也能读取那些调试信息。

解决方案

在Mac OS X上,有一个决定让链接器code> ld )不会在您链接程序时处理所有调试信息。调试信息通常是程序可执行文件大小的10倍,因此链接器处理所有调试信息并将其包含在可执行二进制文件中对链接时间造成严重损害。对于迭代开发 - 编译,链接,编译,链接,调试,编译链接 - 这是一个真正的打击。



相反,编译器在.s中生成DWARF调试信息文件,汇编程序将其输出到.o文件中,并且链接程序在可执行二进制文件中包含一个调试映射,它告诉调试信息用户所有符号在链接过程中的位置。



消费者(执行.o-file调试)从可执行文件加载调试映射,并根据需要处理.o文件中的所有DWARF,并根据调试映射的指示重新映射符号。 p>

dsymutil 可以被认为是一个调试信息链接器。它执行相同的过程 - 读取调试映射,从.o文件加载DWARF,重新定位所有地址 - 然后在其最终的链接地址上输出一个包含所有DWARF的二进制文件。这是dSYM软件包。



一旦你有了一个dSYM软件包,你已经有了普通的标准DWARF,任何矮人阅读工具(可以处理Mach-O二进制文件)可以处理。



还有一项改进,使得所有这些工作都成为可能,包含在Mach-O二进制文件中的UUID。每当链接器创建一个二进制文件时,它会在LC_UUID加载命令中发出一个128位的UUID(例如 otool -hlv dwarfdump --uuid )。这唯一标识该二进制文件。当 dsymutil 创建dSYM时,它会包含该UUID。调试器只会将dSYM和可执行文件相关联(如果它们具有匹配的UUID) - 没有不可靠的文件mod时间戳或类似的东西。



我们也可以使用UUID来定位二进制文件的dSYMs。它们显示在崩溃报告中,我们包含一个Spotlight导入器,您可以使用它搜索它们,例如如果dSYM位于Spotlight索引位置,则
mdfindcom_apple_xcode_dsym_uuids == E21A4165-29D5-35DC-D08D-368476F85EE1
。你甚至可以为你的公司提供一个dSYM的存储库,并且一个程序可以在给定UUID的情况下检索正确的dSYM - 也许是一个小的mysql数据库或类似的东西 - 这样你就可以在随机可执行文件上运行调试器,并且可以立即进行所有的调试该可执行文件的信息。你可以用UUID做一些漂亮的事情。



但是,无论如何,要回答你的原始问题:没有去掉的二进制文件有调试图,.o文件有DWARF和 dsymutil 运行时,它们将被组合起来创建dSYM捆绑包。

如果你想查看调试映射条目,请执行 nm -pa executable ,它们都在那里。它们的形式是旧的nlist记录 - 链接器已经知道如何处理刺,所以最简单的方法是使用它们 - 但是你会看到它是如何工作的,没有太多的麻烦,如果你喜欢,可以参考一些刺伤文档不确定。

Where/how does Apples GCC store DWARF inside an executable?

I compiled a binary via gcc -gdwarf-2 (Apples GCC). However, neither objdump -g nor objdump -h does show me any debug information.

Also libbfd does not find any debug information. (I asked on the binutils-mailinglist about it here.)

I am able however to extract the debugging information via dsymutil (into a dSYM). libbfd is also able to read those debug info then.

解决方案

On Mac OS X there was a decision to have the linker (ld) not process all of the debug information when you link your program. 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. 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.

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.

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. This is the dSYM bundle.

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.

There is an additional refinement that makes all of this work, the UUIDs included in Mach-O binaries. 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). This uniquely identifies that binary file. When dsymutil creates the dSYM, it includes that 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.

We can also use the UUIDs to locate the dSYMs for binaries. They show up in crash reports, we include a Spotlight importer that you can use to search for them, e.g. mdfind "com_apple_xcode_dsym_uuids == E21A4165-29D5-35DC-D08D-368476F85EE1" if the dSYM is located in a Spotlight indexed location. 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. There are some pretty neat things you can do with the UUIDs.

But anyway, to answer your origin 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.

If you want to see the debug map entries, do nm -pa executable and they're all there. 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.

这篇关于苹果GCC在何处/如何将DWARF存储在可执行文件中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆