Linux 如何在运行时调试共享库?

Linux 如何在运行时调试共享库?,linux,debugging,aix,Linux,Debugging,Aix,有人能告诉我如何在共享库上进行运行时调试吗 我需要运行时调试共享库中的函数,但它被另一个程序调用。 如何使用共享库执行类似dbx的操作 我正在AIX上使用dbx。 gdb比dbx更好吗?通常,调试共享库的过程与调试可执行文件的过程基本相同-主要区别在于,在共享库加载到内存之前,您可能无法设置断点。将调试器附加到主可执行文件 如果您正在调试一个不属于您的应用程序,但正在插件体系结构中使用您的模块,那么您仍然使用相同的方法。确保(一如既往)您有可用于共享库的调试信息。在windows中,您将生成一个

有人能告诉我如何在共享库上进行运行时调试吗

我需要运行时调试共享库中的函数,但它被另一个程序调用。 如何使用共享库执行类似dbx的操作

我正在AIX上使用dbx。
gdb比dbx更好吗?

通常,调试共享库的过程与调试可执行文件的过程基本相同-主要区别在于,在共享库加载到内存之前,您可能无法设置断点。将调试器附加到主可执行文件


如果您正在调试一个不属于您的应用程序,但正在插件体系结构中使用您的模块,那么您仍然使用相同的方法。确保(一如既往)您有可用于共享库的调试信息。在windows中,您将生成一个.pdb文件。对于gcc,我认为您可以指定一个特殊的编译器标志(-g?),以确保提供调试信息。您将调试器附加到第三方应用程序。

我记得通过创建使用它的模拟应用程序来测试共享库。如果您愿意做大量工作,您可以创建第二个模拟共享库,该库只收集有关第三方应用程序如何使用该库的信息,然后让您的模拟应用程序重播该信息


当然,永远不要怀疑位置良好的printf和fprintf调用的威力。

您可以尝试静态编译和链接库以调试它。

如果您的bug只在编译为共享时出现,那么这可能会给您一些线索。

您只需要使用可执行文件调用gdb(不管它是您的还是第三方的)。下面是一个示例,我调试ls命令并在(共享)c库中设置断点。本例使用gdb 6.8,它支持延迟(挂起)断点,这使得操作变得简单:

gdb /bin/ls
GNU gdb 6.8-debian
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu"...
(no debugging symbols found)
(gdb) b write
Function "write" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (write) pending.
(gdb) r
Starting program: /bin/ls
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
[Thread debugging using libthread_db enabled]
(no debugging symbols found)
(no debugging symbols found)
[New Thread 0x7f98d2d23780 (LWP 7029)]
[Switching to Thread 0x7f98d2d23780 (LWP 7029)]

Breakpoint 1, 0x00007f98d2264bb0 in write () from /lib/libc.so.6
(gdb)
gdb/bin/ls
GNU gdb 6.8-debian
版权所有(C)2008免费软件基金会。
许可证GPLv3+:GNU GPL版本3或更高版本
这是自由软件:您可以自由更改和重新发布它。
在法律允许的范围内,不存在任何担保。键入“显示复制”
和“显示保修”了解详细信息。
此GDB配置为“x86_64-linux-gnu”。。。
(未找到调试符号)
(gdb)b写入
未定义函数“写入”。
是否在将来加载共享库时使断点挂起?(y或[n])y
断点1(写入)挂起。
(gdb)r
启动程序:/bin/ls
(未找到调试符号)
(未找到调试符号)
(未找到调试符号)
(未找到调试符号)
(未找到调试符号)
(未找到调试符号)
(未找到调试符号)
[已启用使用libthread_db的线程调试]
(未找到调试符号)
(未找到调试符号)
[新螺纹0x7f98d2d23780(LWP 7029)]
[切换到线程0x7f98d2d23780(LWP 7029)]
/lib/libc.so.6的write()中的断点1 0x00007f98d2264bb0
(gdb)
如您所见,gdb自动管理可执行文件使用的所有线程。你不必为线程做任何特殊的事情。断点将在任何线程中工作

或者,如果您想将调试器附加到已经运行的应用程序(这里我使用tail-f/tmp/ttt作为示例):

ps-ux | grep-tail
洛萨8496 0.0 0.0 9352 804分/3秒+12:38 0:00尾部-f/tmp/ttt
洛萨8510 0.0 0.0 5164 840分/4秒+12:39 0:00格雷普尾巴
gdb
GNU gdb 6.8-debian
版权所有(C)2008免费软件基金会。
许可证GPLv3+:GNU GPL版本3或更高版本
这是自由软件:您可以自由更改和重新发布它。
在法律允许的范围内,不存在任何担保。键入“显示复制”
和“显示保修”了解详细信息。
此GDB配置为“x86_64-linux-gnu”。。。
(未找到调试符号)
(gdb)附上8496
附加到程序:/usr/bin/tail,进程8496
正在从/lib/librt.so.1读取符号…(未找到调试符号)…已完成。
为/lib/librt.so.1加载的符号
正在从/lib/libc.so.6读取符号…(未找到调试符号)…已完成。
为/lib/libc.so.6加载的符号
正在从/lib/libpthread.so.0读取符号…(未找到调试符号)…已完成。
[已启用使用libthread_db的线程调试]
[新螺纹0x7f24853f56e0(LWP 8496)]
为/lib/libpthread.so.0加载的符号
正在从/lib/ld-linux-x86-64.so.2读取符号。。。
(未找到调试符号)…完成。
为/lib64/ld-linux-x86-64.so.2加载的符号
(未找到调试符号)
/lib/libc.so.6中的nanosleep()中的0x00007f2484d2bb50
(gdb)b写入
断点1位于0x7f2484d57bb0
(gdb)c
持续的。
[切换到线程0x7f24853f56e0(LWP 8496)]
/lib/libc.so.6的write()中的断点1 0x00007f2484d57bb0
(gdb)

我已经很久没有在AIX上使用dbx了,我也遇到了这个问题。安装gdb不是我的选择

dbx  /path/to/your/program
(dbx) run [args to your program]
(dbx) set $ignoreonbptrap           # I kept hitting a trace/bpt trap
(dbx) set $deferevents              # allows setting bp in not loaded shared library
(dbx) set $repeat                   # useful, repeat commands with <enter> tjust like gdb
(dbx) stop in MySharedLibraryFunc   # defers breakpoint
(dbx) cont
dbx/path/to/your/program
(dbx)运行[args到您的程序]
(dbx)设置$ignoreonbptrap#我一直碰到跟踪/bpt陷阱
(dbx)set$deferevents#允许在未加载的共享库中设置bp
(dbx)设置$repeat#与gdb一样,使用tq重复有用的命令
(dbx)在MySharedLibraryFunc中停止#延迟断点
(dbx)续

洛萨回答的另一个例子:

我正在Linux中运行一个动态库
test.so
(由
test.c
编译)上的测试,使用
python
和名为
tests/test\u pwmbasic.py
的python单元测试库
unittest
。(我现在意识到,命名方案有点单调)

我想调试
测试中的内容。因此
来自
测试中的刺激。
这就是我让它工作的方式

$ cd ~/my/test/path
$ gdb $(which python)
   ... gdb blah ...
(gdb) b test.c:179
(gdb) run
>>> from tests.test_pwmbasic import *
>>> import unittest
>>> unittest.main()
   ... unittest blah ...
Breakpoint 1, pwmTest_setDutyCycles (dutyCycles=0x7ffff7ece910) at ./test.c:179
(gdb) print pwm_errorCode
$1 = PWM_ERROR_NONE
现在我想和gdb结婚

注意:
test.c
还包括
。/pwm.c
,因此我还可以使用

(gdb) b pwm.c:123

如果主可执行文件不是我的,而是某个第三方的。。。。但是我正在写一个模块,它将被使用
$ cd ~/my/test/path
$ gdb $(which python)
   ... gdb blah ...
(gdb) b test.c:179
(gdb) run
>>> from tests.test_pwmbasic import *
>>> import unittest
>>> unittest.main()
   ... unittest blah ...
Breakpoint 1, pwmTest_setDutyCycles (dutyCycles=0x7ffff7ece910) at ./test.c:179
(gdb) print pwm_errorCode
$1 = PWM_ERROR_NONE
(gdb) b pwm.c:123