如何运行时调试共享库?

发布于 2024-07-18 08:52:32 字数 145 浏览 7 评论 0原文

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

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

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

Can anyone tell me how to do runtime debugging on shared libraries?

I need to runtime-debug a function in my shared library, but its called by another program.
How can I do something like dbx with shared libraries?

I m using dbx on AIX.
is gdb better than dbx for what I m trying to do?.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

萌辣 2024-07-25 08:52:32

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

You just need to call gdb with the executable (it does not matter if it is yours or a 3rd party one). Here is an example where I debug the ls command and set a breakpoint in the (shared) c library. This example uses gdb 6.8 which supports deferred (pending) breakpoints which makes this easy:

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)

As you can see gdb automatically manages all threads used by the executable. You don't have to do anything special for threads there. The breakpoint will work in any thread.

Alternatively if you want to attach the debugger to an already running application (I use tail -f /tmp/ttt here as an example):

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)
鱼窥荷 2024-07-25 08:52:32

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

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

Normally the procedure for debugging a shared library is much the same as for debugging an executable - the main difference is that you may be unable to set a breakpoint until the shared library is loaded into memory. You attach the debugger to the main executable.

If you are debugging an application that is not owned by you, but is using your module in a plugin architecture, you still use the same method. Make sure (as always) that you have debugging information available for your shared library. In windows, you would generate a .pdb file. With gcc, I think you specify a special compiler flag (-g?) to ensure that debugging information is supplied. You attach the debugger to the third party application.

摇划花蜜的午后 2024-07-25 08:52:32

另一个进一步回答lothar答案的例子:

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

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

我想从 test_pwmbasic.py 中的刺激中调试 test.so 中的内容。
所以这就是我让它工作的方式......

$ 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

Another example further to lothar's answer:

I'm running tests on a dynamic library test.so (compiled from test.c) in Linux using python and python's unit-testing library unittest called tests/test_pwmbasic.py. (naming scheme is a bit monotone, I realise that now)

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

I want to debug what's in test.so from stimulus in test_pwmbasic.py.
So this is how I got it working...

$ 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

and now I want to marry gdb

note: test.c also includes ../pwm.c, so I can also breakpoint within that library with

(gdb) b pwm.c:123
空心空情空意 2024-07-25 08:52:32

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

当然,永远不要怀疑适当放置的 printf 和 fprintf 调用的力量。

I remember testing shared libraries by creating a mock app that used it. If you are willing to do a lot of work, you could create a second, mock shared library that just collects information about how the library is being used by the third party app, and then have your mock app replay that information.

Of course, never doubt the power of well placed printf and fprintf calls.

ㄖ落Θ余辉 2024-07-25 08:52:32

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

You could try compiling and linking the library statically to debug it.
If your bug only shows up when it's compiled as shared, than that might give you some clues.

一江春梦 2024-07-25 08:52:32

我已经很长时间没有在 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

It has been a long time since I had to use dbx on AIX, and I faced this problem too. Installing gdb was not an option for me.

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文