【转】gdb调试动态链接库
来源:互联网 发布:阿里云服务器好用吗 编辑:程序博客网 时间:2024/05/29 11:49
【转】gdb调试动态链接库
【原文地址】http://www.microsuncn.com/index.php?title=%E7%94%A8gdb%E8%B0%83%E8%AF%95%E5%8A%A8%E6%80%81%E9%93%BE%E6%8E%A5%E5%BA%93
在 Linux 可以用 gdb 来调试应用程序,当然前提是用 gcc 编译程序时要加上 -g 参数。我这篇文章里将讨论一下用 gdb 来调试动态链接库的问题。首先,假设我们准备这样的一个动态链接库:引用:库名称是: ggg 动态链接库文件名是: libggg.so 头文件是: get.h 提供这样两个函数调用接口:
int get (); int set (int a);
要生成这样一个动态链接库,我们首先编写这样一个头文件:
/************关于本文档*********************************************filename: get.h*********************************************************************/int get ();int set (int a);
然后准备这样一个生成动态链接库的源文件:
/************关于本文档*********************************************filename: get.cpp*********************************************************************/#include <stdio.h>#include "get.h"static int x=0;int get (){ printf ("get x=%d\n", x); return x;}int set (int a){ printf ("set a=%d\n", a); x = a; return x;}
然后我们用 GNU 的 C/C++ 编译器来生成动态链接库,编译命令如下:
g++ get.cpp -shared -g -DDEBUG -o libggg.sog++ get.cpp -shared -g -fPIC -DDEBUG -o libggg.so (64位机器)
这样我们就准备好了动态链接库了,下面我们编写一个应用程序来调用此动态链接库,源代码如下:
/************关于本文档*********************************************filename: pk.cpp*********************************************************************/#include <stdio.h>#include "get.h"int main (int argc, char** argv){ int a = 100; int b = get (); int c = set (a); int d = get (); printf ("a=%d,b=%d,c=%d,d=%d\n",a,b,c,d); return 0;}
编译此程序用下列命令,如果已经把上面生成的 libggg.so 放到了库文件搜索路径指定的文件目录,比如 /lib 或 /usr/lib 之类的,就用下面这条命令:
g++ pk.cpp -o app -Wall -g -lggg
否则就用下面这条命令:
g++ pk.cpp -o app -Wall -g -lggg -L`pwd`
下面我们就开始调试上面命令生成的 app 程序吧。如果已经把上面生成的 libggg.so 放到了库文件搜索路径指定的文件目录,比如 /lib 或 /usr/lib 之类的,调试就顺利完成,如下:
#gdb ./appGNU gdb 6.4-debianCopyright 2005 Free Software Foundation, Inc.GDB is free software, covered by the GNU General Public License, and you arewelcome to change it and/or distribute copies of it under certain conditions.Type "show copying" to see the conditions.There is absolutely no warranty for GDB. Type "show warranty" for details.This GDB was configured as "i486-linux-gnu"...Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1".(gdb) b main /* 这是在程序的 main 处设置断点 */Breakpoint 1 at 0x804853c: file pk.cpp, line 7.(gdb) b set /* 这是在程序的 set 处设置断点 */Function "set" not defined.Make breakpoint pending on future shared library load? (y or [n]) y /* 这里必须选择 y 调试程序才会跟踪到动态链接库内部去 */Breakpoint 2 (set) pending.(gdb) run /* 开始运行我们的程序,直到遇见断点时暂停 */Starting program: /data/example/c/appBreakpoint 3 at 0xb7f665f8: file get.cpp, line 11.Pending breakpoint "set" resolvedBreakpoint 1, main (argc=1, argv=0xbf990504) at pk.cpp:77 int a = 100;(gdb) n /* 继续执行程序的下一行代码 */8 int b = get ();(gdb) n /* 程序执行到了我们断点所在的动态链接库了 */get x=09 int c = set (a);(gdb) nBreakpoint 3, set (a=100) at get.cpp:1111 printf ("set a=%d\n", a);(gdb) list /* 查看当前代码行周围的代码,证明我们已经跟踪到动态链接库的源代码里面了 */6 printf ("get x=%d\n", x);7 return x;8 }9 int set (int a)10 {11 printf ("set a=%d\n", a);12 x = a;13 return x;14 }(gdb) nset a=10012 x = a;(gdb) n13 return x;(gdb) n14 }(gdb) nmain (argc=1, argv=0xbf990504) at pk.cpp:1010 int d = get ();(gdb) nget x=10011 printf ("a=%d,b=%d,c=%d,d=%d\n",a,b,c,d);(gdb) na=100,b=0,c=100,d=10012 return 0;(gdb) cContinuing.Program exited normally.(gdb) quit /* 程序顺利执行结束 */如果我们没有把动态链接库放到指定目录,比如/lib里面,调试就会失败,过程如下:# gdb ./appGNU gdb 6.4-debianCopyright 2005 Free Software Foundation, Inc.GDB is free software, covered by the GNU General Public License, and you arewelcome to change it and/or distribute copies of it under certain conditions.Type "show copying" to see the conditions.There is absolutely no warranty for GDB. Type "show warranty" for details.This GDB was configured as "i486-linux-gnu"...Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1".(gdb) b mainBreakpoint 1 at 0x804853c: file pk.cpp, line 7.(gdb) b setFunction "set" not defined.Make breakpoint pending on future shared library load? (y or [n]) yBreakpoint 2 (set) pending.(gdb) run /* 虽然调试操作都一样,但程序执行失败 */Starting program: /data/example/c/app/data/example/c/app: error while loading shared libraries: libggg.so: cannot open shared object file: No such file or directoryProgram exited with code 0177.(gdb) quit
调试失败的原因是因为gdb不能找到libggg.so,可以通过下面的方法解决:
1) 将库路径加到LD_LIBRARY_PATH里2) 执行:ldconfig YOUR_LIB_PATH3) 在/etc/ld.so.conf里加入库所在路径。然后执行:ldconfig上面3个方法任意一个都可以,然后再去用gdb调试就没有问题了。
另:
1、假设我的可执行程序是ServerName,共享库为worker.so2、我用gdb调试ServerName,想在B的某个源文件(比如worker.cpp,worker.cpp与ServerName不在同一个目录下)中设置断点,使用下面的命令行break worker.cpp:123若找不到源文件可使用如下命令设定源文件目录:设定gdb环境变量 LD_PRELOAD,在执行程序前先把共享库代码load进来指定你的链接库的位置,可以通过设定环境变量LD_LIBRARY_PATH来实现拷贝到标准的lib搜寻目录下,例如/usr/lib等b main, r,然后再设置断点就可以了,共享库只有当程序运行才开始加载的
0 0
- 【转】gdb调试动态链接库
- 【转】gdb调试动态链接库
- gdb调试动态链接库
- 用gdb调试动态链接库
- 用gdb调试动态链接库
- 用gdb调试动态链接库
- 用gdb调试动态链接库
- gdb如何调试动态链接库问题
- gdb调试动态链接so
- GDB调试动态库
- Day22、大型项目开发的文件组织、动态链接、动态库、静态链接、静态库gdb调试工具
- gdb调试运行程序带参数(调用动态链接库),debug过程记录
- Gdb+gdbserver无源码调试Android 动态链接库的技巧
- Linux GCC编译、gdb调试、makefile、动态链接库的创建
- Linux gdb 动态链接库 so 问题
- 如何调试动态链接库
- 调试动态链接库(DLL)
- 调试动态链接库(DLL)
- spring多数据源的配置-以及原理
- iOS并发编程-锁
- Android —— NFC详解
- 浅析GTK 输入法模块 GTK IMContext
- 使用ProgressDialog时出现窗体泄露解决方案
- 【转】gdb调试动态链接库
- SQL学习 欢迎来到SQL世界
- 记录ReactNative在windows下Android环境配置
- iOS SEL的简单总结
- swift属性
- 查看linux磁盘的各个目录大小
- Android(Android5.0)下毛玻璃(磨砂)效果如何实现?
- iOS--错误集锦--iOS7.1系统,xcodeVersion 7.2,运行app出现上下黑边
- android-Ultra-Pull-To-Refresh 源码解析