如何运行时调试共享库?

时间:2009-04-29 08:24:57

标签: linux debugging aix

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

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

我在AIX上使用dbx。 对于我想做的事情,gdb比dbx更好吗?。

6 个答案:

答案 0 :(得分:30)

您只需要使用可执行文件调用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自动管理可执行文件使用的所有线程。你不必为那里的线程做任何特别的事情。断点可以在任何线程中使用。

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

ps ux | grep tail
lothar    8496  0.0  0.0   9352   804 pts/3    S+   12:38   0:00 tail -f /tmp/ttt
lothar    8510  0.0  0.0   5164   840 pts/4    S+   12:39   0:00 grep tail

gdb
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) attach 8496
Attaching to program: /usr/bin/tail, process 8496
Reading symbols from /lib/librt.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib/librt.so.1
Reading symbols from /lib/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/libpthread.so.0...(no debugging symbols found)...done.
[Thread debugging using libthread_db enabled]
[New Thread 0x7f24853f56e0 (LWP 8496)]
Loaded symbols for /lib/libpthread.so.0
Reading symbols from /lib/ld-linux-x86-64.so.2...
(no debugging symbols found)...done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
(no debugging symbols found)
0x00007f2484d2bb50 in nanosleep () from /lib/libc.so.6
(gdb) b write
Breakpoint 1 at 0x7f2484d57bb0
(gdb) c
Continuing.
[Switching to Thread 0x7f24853f56e0 (LWP 8496)]

Breakpoint 1, 0x00007f2484d57bb0 in write () from /lib/libc.so.6
(gdb)

答案 1 :(得分:9)

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

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

答案 2 :(得分:3)

另一个例子是lothar的回答:

我使用test.so和python的单元测试库{{1}在Linux上运行动态库test.c(从python编译)的测试叫unittest。 (命名方案有点单调,我现在意识到)

tests/test_pwmbasic.py

我想从~/my/test/path/ tests/ __init__.py test_pwmbasic.py test.c test.so 中的刺激中调试test.so中的内容。 所以这就是我如何运作......

test_pwmbasic.py

现在我想和gdb结婚

注意:$ 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 还包含test.c,因此我也可以使用

在该库中断点
../pwm.c

答案 3 :(得分:1)

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

当然,永远不要怀疑打印好的printf和fprintf的力量。

答案 4 :(得分:1)

自从我不得不在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

答案 5 :(得分:0)

您可以尝试静态编译和链接库以进行调试 如果您的错误仅在编译为共享时出现,那么这可能会为您提供一些线索。