在MacOS上,我看到一个堆栈看起来是这样的(堆栈的最顶部是一个陷阱,有问题的代码,但我想了解我是如何到达那里的)
(gdb) where
...
#4 0x0000000112fdefc8 in appLibInit::appLibInit ()
#5 0x0000000112fdef71 in __sti__$E ()
#6 0x00007fff5fc112f7 in __dyld__ZN16ImageLoaderMachO18doModInitFunctionsERKN11ImageLoader11LinkContextE ()
#7 0x00007fff5fc0d20c in __dyld__ZN11ImageLoader23recursiveInitializationERKNS_11LinkContextEj ()
#8 0x00007fff5fc0d1b0 in __dyld__ZN11ImageLoader23recursiveInitializationERKNS_11LinkContextEj ()
#9 0x00007fff5fc0d1b0 in __dyld__ZN11ImageLoader23recursiveInitializationERKNS_11LinkContextEj ()
#10 0x00007fff5fc0d1b0 in __dyld__ZN11ImageLoader23recursiveInitializationERKNS_11LinkContextEj ()
#11 0x00007fff5fc0d2f4 in __dyld__ZN11ImageLoader15runInitializersERKNS_11LinkContextE ()
#12 0x00007fff5fc038b4 in __dyld__ZN4dyld24initializeMainExecutableEv ()
#13 0x00007fff5fc06ea1 in __dyld__ZN4dyld5_mainEPK11mach_headermiPPKcS5_S5_ ()
#14 0x00007fff5fc01695 in __dyld__ZN13dyldbootstrap5startEPK11mach_headeriPPKcl ()
#15 0x00007fff5fc0103a in __dyld__dyld_start ()
#16 0x0000000100000000 in ?? ()
#17 0x0000000000000001 in ?? ()
函数appLibInit::appLibInit是我们代码中全局对象的C++构造函数,所以我猜我在某种预主代码中,可能正在处理链接到的所有共享库(奇怪的是,有问题的代码不是我们期望链接到的东西,除非它被其他东西拖进来)。
mac c++过滤器似乎无法解码这些带有__dyld前缀的符号。
有人知道一些描述MacOS进程启动顺序的文档吗?这可能会给我更多的线索?
dyld的来源可以在线获得:
http://www.opensource.apple.com/source/dyld/
您可以通过简单地删除__dyld
前缀来解码损坏的符号名称。添加前缀可能是为了防止与恰好定义相同C++函数的用户代码发生冲突(例如,如果您自己编译dyld的部分)。
更一般地说,您所看到的是库加载和初始化。动态库可以声明函数在加载时应该运行;看起来你的appLibInit::appLibInit()
就是这样。(如果库是由主二进制文件加载的,这可能会在main()
之前发生。)
在C++中发生这种情况的一种方法是,全局声明任何具有构造函数的对象。