如何在 Linux 下调试动态链接库
大家都知道在 Linux 可以用 gdb 来调试应用程序,当然前提是用 gcc 编译程序时要加上
-g 参数。
我这篇文章里将讨论一下用 gdb 来调试动态链接库的问题。
首先,假设我们准备这样的一个动态链接库:
QUOTE:
库名称是: ggg
动态链接库文件名是: libggg.so
头文件是: get.h
提供这样两个函数调用接口:
int get ();
int set (int a);
要生成这样一个动态链接库,我们首先编写这样一个头文件:
[Copy to clipboard]
CODE:
/************关于本文档********************************************
*filename: get.h
*purpose: 一个动态链接库头文件示例
*tided by: zhoulifa() 周立发 ()
Linux 爱好者 Linux 知识传播者 SOHO 族 开发者 最擅长 C 语言
*date time: 2006-11-15 21:11:54
*Note: 任何人可以任意复制代码并运用这些文档,当然包括你的商业用途
* 但请遵循 GPL
*Hope:希望越来越多的人贡献自己的力量,为科学技术发展出力
* 科技站在巨人的肩膀上进步更快!感谢有开源前辈的贡献!
*感谢 提供原始代码,
我在他的基础上整理了此文
*********************************************************************/
int get ();
int set (int a);
然后准备这样一个生成动态链接库的源文件:
[Copy to clipboard]
CODE:
/************关于本文档********************************************
*filename: get.cpp
*purpose: 一个动态链接库源文件示例
*tided by: zhoulifa() 周立发 ()
Linux 爱好者 Linux 知识传播者 SOHO 族 开发者 最擅长 C 语言
*date time:2006-11-15 21:11:54
*Note: 任何人可以任意复制代码并运用这些文档,当然包括你的商业用途
* 但请遵循 GPL
*Hope:希望越来越多的人贡献自己的力量,为科学技术发展出力
* 科技站在巨人的肩膀上进步更快!感谢有开源前辈的贡献!
*感谢 提供原始代码,
我在他的基础上整理了此文
*********************************************************************/
#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++ 编译器来生成动态链接库,编译命令如下:
QUOTE:
g++ get.cpp -shared -g -DDEBUG -o
libggg.so
这样我们就准备好了动态链接库了,下面我们编写一个应用程序来调用此动态链接库,源代码如下:
[Copy to clipboard]
CODE:
/************关于本文档********************************************
*filename: pk.cpp
*purpose: 一个调用动态链接库的示例
*tided by: zhoulifa() 周立发 ()
Linux 爱好者 Linux 知识传播者 SOHO 族 开发者 最擅长 C 语言
*date time:2006-11-15 21:11:54
*Note: 任何人可以任意复制代码并运用这些文档,当然包括你的商业用途
* 但请遵循 GPL
*Hope:希望越来越多的人贡献自己的力量,为科学技术发展出力
* 科技站在巨人的肩膀上进步更快!感谢有开源前辈的贡献!
*感谢 提供原始代码,
我在他的基础上整理了此文
*********************************************************************/
#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 之类的,就用下面这条命令:
QUOTE:
g++ pk.cpp -o app -Wall -g -lggg
否则就用下面这条命令:
QUOTE:
g++ pk.cpp -o app -Wall -g -lggg -L`pwd`
下面我们就开始调试上面命令生成的 app 程序吧。如果已经把上面生成的 libggg.so 放到了库文件搜索路径指定的文件目录,比如 /lib或 /usr/lib 之类的,调试就顺利完成,如下
:
QUOTE:
./app
GNU gdb 6.4-debian
Copyright 2005 Free Software Foundation,Inc.
GDB is free software, covered by the GNU
General Public License, and you are
welcome to change it and/or distribute
copies of it under certain conditions.
Type "show copying" to see theconditions.
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/app
Breakpoint 3 at 0xb7f665f8: file get.cpp,line 11.
Pending breakpoint "set" resolved
Breakpoint 1, main (argc=1,argv=0xbf990504) at pk.cpp:7
7 int a = 100;
(gdb) n /* 继续执行程序的下一行代码
*/
8 int b = get ();
(gdb) n /* 程序执行到了我们断点所在的动态链接库了 */
get x=0
9 int c = set (a);(gdb) n
Breakpoint 3, set (a=100) at get.cpp:11
11 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) n
set a=100
12 x = a;(gdb) n
13 return x;(gdb) n
14 }
(gdb) n
main (argc=1, argv=0xbf990504) at
pk.cpp:10
10 int d = get ();
(gdb) n
get x=100
11 printf ("a=%d,b=%d,c=%
d,d=%d\n",a,b,c,d);
(gdb) n
a=100,b=0,c=100,d=100
12 return 0;
(gdb) c
Continuing.
Program exited normally.
(gdb) quit /* 程序顺利执行结束 */#
如果我们没有把动态链接库放到指定目录,比如/lib里面,调试就会失败,过程如下:
QUOTE:
# gdb ./app
GNU gdb 6.4-debian
Copyright 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 theconditions.
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
Breakpoint 1 at 0x804853c: file pk.cpp,
line 7.
(gdb) b set
Function "set" not defined.
Make breakpoint pending on future shared
library load? (y or [n]) y
Breakpoint 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
directory
Program exited with code 0177.
(gdb) quit
#
本次实验的环境是:
CPU:AMD Athlon(tm) 64 Processor 3000+
内存:512M
OS:Ubuntu GNU/Linux 6.06 dapper LTS
gcc:gcc 版本 4.0.3 (Ubuntu 4.0.3-1ubuntu5)
break(b) 行号:在某一行设置断点
break 函数名:在某个函数开头设置断点
break...if...:设置条件断点
continue(或c):从当前位置开始连续而非单步执行程序
delete breakpoints:删除所有断点
delete breakpoints n:删除序号为n的断点
disable breakpoints:禁用断点
enable breakpoints:启用断点
info(或i) breakpoints:参看当前设置了哪些断点
run(或r):从开始连续而非单步执行程序
display 变量名:跟踪查看一个变量,每次停下来都显示它的值
undisplay:取消对先前设置的那些变量的跟踪
如何在 Linux 下调试动态链接库的更多相关文章
- 一步一步教你如何在linux下配置apache+tomcat(转)
一步一步教你如何在linux下配置apache+tomcat 一.安装前准备. 1. 所有组件都安装到/usr/local/e789目录下 2. 解压缩命令:tar —vxzf 文件名(. ...
- Linux下生成动态链接库是否必须使用 -fPIC 的问题[转]
在 Linux 下制作动态链接库,“标准” 的做法是编译成位置无关代码(Position Independent Code,PIC),然后链接成一个动态链接库.经常遇到的一个问题是 -fPIC 是不是 ...
- 如何在Linux下拷贝一个目录呢
cp -af newadmin/movie/. uploadfile/mallvideo/ 如何在Linux下拷贝一个目录呢?这好像是再简单不过的问题了. 比如要把/home/usera拷贝到/m ...
- 如何在linux下制作一个windows的可启动u盘?
如何在linux下制作一个windows的可启动u盘? 情景是这样的,有一个windows10的iso,现在想通过U盘安装,要求即支持UEFI(启动引导器),又支持Legacy(启动引导器),因为有一 ...
- 如何在linux下开启FTP服务
如何在linux下开启FTP服务 1. 首先服务器要安装ftp软件,查看是否已经安装ftp软件下: #which vsftpd 如果看到有vsftpd的目录说明服务器已经安装了ftp软件 2. ...
- 如何在Linux下禁用IPv6
如何在Linux下禁用IPv6 echo 1 > /proc/sys/net/ipv6/conf/all/disable_ipv6 禁用IP ...
- 如何在Linux下使用Rsync
如何在Linux下使用Rsync 吐槽 昨天对scp进行总结之后看到最后有说到Rsync,俗语有云:好奇心害死猫.抱着学习的态度将Rsync给找了出来,然后进行了一些简单的学习.下面介绍一些个常用的命 ...
- Dcloud课程6 php脚本如何在Linux下定时更新数据
Dcloud课程6 php脚本如何在Linux下定时更新数据 一.总结 一句话总结:linux下用crontab命令实现定时任务. 1.linux下执行php脚本用什么命令? 直接用php命令php ...
- linux下查看动态链接库依赖关系的命令 x86: ldd *.so arm: arm-linux-readelf -d *.so 实际例子: 以项目中用到的库librtsp.so分析: lijun@ubuntu:~/workspace$ arm-hisiv100nptl-linux-ld -d librtsp.so arm-hisiv100nptl-linux-ld:
linux下查看动态链接库依赖关系的命令 x86:ldd *.so arm:arm-linux-readelf -d *.so 实际例子:以项目中用到的库librtsp.so分析:l ...
随机推荐
- IOS开发之----代码块的使用(二)
iOS4引入了一个新特性,支持代码块的使用,这将从根本上改变你的编程方式.代码块是对C语言的一个扩展,因此在Objective-C中完全支持.如果你学过Ruby,Python或Lisp编程语言,那么你 ...
- SQL游标、函数的使用方法
游标的的使用有日常的开发和维护的过程不使用的并不多,但是碰到一些棘手的问题的时候,游标时常是个非常好的帮手,下面就说下游标的使用方法,方法自己以后查阅,和加深一些印象,下面以一个存储过程为例 ...
- .NET:如何实现 “热插拔”?
背景 如果某个“功能”需要动态更新?这种动态更新,可能是需求驱动的,也可能是为了修改 BUG,面对这种场景,如何实现“热插拔”呢?先解释一下“热插拔”:在系统运行过程动态替换某些功能,不用重启系统进程 ...
- plsql调用无参/有参存储过程
--有参调用方式:declare STERMINAL ); SPROCESS NUMBER; begin sj_transfera_digi_getmapping(,,'DYH010006783031 ...
- C++ 转型动作 尽量避免 以及 那些意想不到的威胁
看完EffectiveC++的关于转型的章节,顿时认为周围的代码都处在悬崖边上~~ C的旧式转型:inta = 10; double b = (double)a; 对于C++的四种转型函数, cons ...
- 《mahout实战》
<mahout实战> 基本信息 原书名:Mahout in action 作者: (美)Sean Owen Robin Anil Ted Dunning Ellen Fr ...
- Mysql中与时间相关的统计分析
最近项目需要统计一段日期范围内,根据每分钟.几分钟.每天分别统计汇总某些事件/指标的发生总次数,平均发生次数,因此总结了Mysql中与时间处理.统计相关的资料. 按分钟统计某一时间段内的数据 SELE ...
- 接口处理篇 accept bind connect atan2 htons inet_addr inet_aton inet_ntoa listen ntohl recv send sendto socket
accept(接受socket连线) 相关函数 socket,bind,listen,connect 表头文件 #include<sys/types.h> #include<sys/ ...
- 编译打包工具sbt的镜像设置
sbt可以和maven共用一个镜像,公司内部有的自然最后不过 创建文件:~/.sbt/repositories [repositories] local aliyun: http://maven.al ...
- uva 10618 Tango Tango Insurrection 解题报告
Tango Tango Insurrection Time Limit: 3000MS 64bit IO Format: %lld & %llu Submit Status uDebu ...