Linux 如何运行时调试共享库?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/801423/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to runtime debug shared libraries?
提问by
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?
我需要运行时调试共享库中的一个函数,但它被另一个程序调用。如何使用共享库执行 dbx 之类的操作?
I m using dbx on AIX. is gdb better than dbx for what I m trying to do?.
我在 AIX 上使用 dbx。对于我正在尝试做的事情,gdb 是否比 dbx 更好?
采纳答案by lothar
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 lscommand 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(无论它是您的还是第 3 方的都没有关系)。这是我调试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)
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.
如您所见,gdb 自动管理可执行文件使用的所有线程。您不必为那里的线程做任何特别的事情。断点将在任何线程中工作。
Alternatively if you want to attach the debugger to an already running application (I use tail -f /tmp/ttthere as an example):
或者,如果您想将调试器附加到已经运行的应用程序(我在这里使用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)
回答by 1800 INFORMATION
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.
如果您正在调试一个不属于您的应用程序,而是在插件架构中使用您的模块,您仍然使用相同的方法。确保(一如既往)您有可用于共享库的调试信息。在 Windows 中,您将生成一个 .pdb 文件。对于 gcc,我认为您指定了一个特殊的编译器标志 (-g?) 以确保提供调试信息。您将调试器附加到第三方应用程序。
回答by Chas. Owens
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.
当然,永远不要怀疑 printf 和 fprintf 调用的强大功能。
回答by PiedPiper
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.
您可以尝试静态编译和链接库以调试它。
如果您的错误仅在编译为共享时出现,那么这可能会给您一些线索。
回答by codeDr
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.
自从我不得不在 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
回答by FraggaMuffin
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)
我运行一个动态库测试test.so
(编译自test.c
使用的Linux)python
和Python的单元测试库unittest
叫tests/test_pwmbasic.py
。(命名方案有点单调,我现在意识到了)
~/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...
我想调试什么是在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
= PWM_ERROR_NONE
and now I want to marry gdb
现在我想嫁给gdb
note: test.c
also includes ../pwm.c
, so I can also breakpoint within that library with
注意:test.c
也包括../pwm.c
,所以我也可以在该库中使用断点
(gdb) b pwm.c:123