如何运行时debugging共享库?

任何人都可以告诉我如何执行共享库的运行时debugging

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

我在AIX上使用dbx。 是gdb好于dbx为我正在尝试做什么?

你只需要用可执行文件调用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) 

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

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

另外一个例子lothar的答案是:

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

 ~/my/test/path/ tests/ __init__.py test_pwmbasic.py test.c test.so 

我想从test.so的刺激中调试test.so中的test_pwmbasic.py 。 所以这就是我的工作原理

 $ 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 

在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 

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

当然,不要怀疑正确放置printf和fprintf调用的能力。

您可以尝试静态编译和链接库来调试它。
如果你的bug只在被编译为共享的时候才显示,那么可能会给你一些线索。