如何在动态打开的共享库条目上设置断点? 在某些上下文中,我用G++编译的实验事务内存模型来检查一个简单的C++程序。我想知道调用register\u tm\u clones的确切位置(通过objdump一个简单的程序可以看到fn)。即使在像int main(){}这样的程序中,也会调用此函数
我想知道在通用程序的整个范围内调用如何在动态打开的共享库条目上设置断点? 在某些上下文中,我用G++编译的实验事务内存模型来检查一个简单的C++程序。我想知道调用register\u tm\u clones的确切位置(通过objdump一个简单的程序可以看到fn)。即使在像int main(){}这样的程序中,也会调用此函数,c++,linux,gdb,ld,C++,Linux,Gdb,Ld,我想知道在通用程序的整个范围内调用register\u tm\u clones的地方。我在GDB中设置了一个断点,并回溯: Breakpoint 1, 0x00007ffff7c5e6e0 in register_tm_clones () from /usr/lib/libgcc_s.so.1 (gdb) bt #0 0x00007ffff7c5e6e0 in register_tm_clones () from /usr/lib/libgcc_s.so.1 #1 0x00007ffff7f
register\u tm\u clones
的地方。我在GDB中设置了一个断点,并回溯:
Breakpoint 1, 0x00007ffff7c5e6e0 in register_tm_clones () from /usr/lib/libgcc_s.so.1
(gdb) bt
#0 0x00007ffff7c5e6e0 in register_tm_clones () from /usr/lib/libgcc_s.so.1
#1 0x00007ffff7fe209a in call_init.part () from /lib64/ld-linux-x86-64.so.2
#2 0x00007ffff7fe21a1 in _dl_init () from /lib64/ld-linux-x86-64.so.2
#3 0x00007ffff7fd313a in _dl_start_user () from /lib64/ld-linux-x86-64.so.2
#4 0x0000000000000001 in ?? ()
#5 0x00007fffffffe390 in ?? ()
#6 0x0000000000000000 in ?? ()
当ld linux
在程序中的某个点打开libgcc
时,会调用它。我确保我们已链接到libgcc
。是的:
❯ ldd main
linux-vdso.so.1 (0x00007fff985e4000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007f7eb82dc000)
libm.so.6 => /usr/lib/libm.so.6 (0x00007f7eb8196000)
libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x00007f7eb817c000)
libc.so.6 => /usr/lib/libc.so.6 (0x00007f7eb7fb6000)
/lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f7eb84ec000)
但是。。。我如何知道何时调用它(它肯定不在main
中)?我知道\uu libc\u csu\u init
,然后有一些步骤,我们进入main。我如何设置断点,以便在全局图中查看ld
何时决定打开libgcc
,从而查看调用register\u tm\u clone
的位置
我如何设置断点,以便在全局图中看到ld何时决定打开libgcc,以及由此调用register_tm_克隆的位置
你已经看到了
我认为您的困惑在于不理解动态链接流程运行时会发生什么。大致来说,步骤如下:
mmap
s将可执行文件放入其中
PT_INTERP
段,并且mmap
s将其中引用的文件也放入进程中。这里,PT_INTERP
的内容是/lib64/ld-linux-x86-64.so.2
,又名动态加载程序,不要与/usr/bin/ld
(又名静态链接器)混淆
此外,由于有一个程序解释器,内核将控制权转移给它(而不是在主可执行文件中调用\u start
),因为主可执行文件还没有准备好运行
ld linux
开始运行时,它首先重新定位自身,然后mmap
s主可执行文件直接链接到的所有库。您可以使用readelf-da.out | grep NEEDED
查看这些库
注意:由于这些库中的每个库本身可能直接依赖于其他库,因此这个过程是递归重复的
\u init
,但也可以有不同的名称)
我如何设置断点,以便在全局图中看到ld何时决定打开libgcc,以及由此调用register_tm_克隆的位置
你已经看到了
我认为您的困惑在于不理解动态链接流程运行时会发生什么。大致来说,步骤如下:
mmap
s将可执行文件放入其中
PT_INTERP
段,并且mmap
s将其中引用的文件也放入进程中。这里,PT_INTERP
的内容是/lib64/ld-linux-x86-64.so.2
,又名动态加载程序,不要与/usr/bin/ld
(又名静态链接器)混淆
此外,由于有一个程序解释器,内核将控制权转移给它(而不是在主可执行文件中调用\u start
),因为主可执行文件还没有准备好运行
ld linux
开始运行时,它首先重新定位自身,然后mmap
s主可执行文件直接链接到的所有库。您可以使用readelf-da.out | grep NEEDED
查看这些库
注意:由于这些库中的每个库本身可能直接依赖于其他库,因此这个过程是递归重复的
\u init
,但也可以有不同的名称)您的问题不清楚:您已经看到了调用它的确切位置。另外,ld!=ld linux
,请不要混淆它们,以免混淆每个人。抱歉,我应该更清楚我的要求。我的意思是我想确切地知道,从\u开始
到程序结束,调用register\u tm\u clones
的位置。另外,我想我不熟悉ld
和ldlinux
之间的区别。你能给我解释一下区别吗?这样我就可以编辑问题陈述了?我已经更新了问题,使我要问的问题更清楚。你的问题不清楚:你已经看到了它的确切名称。另外,ld!=ld linux
,请不要混淆它们,以免混淆每个人。抱歉,我应该更清楚我的要求。我的意思是我想确切地知道,从\u开始
到程序结束,调用register\u tm\u clones
的位置。另外,我想我不熟悉ld
和ldlinux
之间的区别。你能给我解释一下区别吗?这样我就可以编辑问题陈述了?我已经更新了问题,使我要问的问题更清楚。我明白了。谢谢你的详细解释!我不确定动态链接器何时完成整个mmaping。我一直认为\u start
才是程序的真正开始。因此,如果我没有弄错的话(只是总结一下):动态链接器会映射所有需要的共享库,运行它们的\u init
(或任何调用),然后在主可执行文件中调用\u start
,对吗?@OneRaynyDay是的,对\u start
是程序的实际开始,但是ld linux
运行