如何在 Linux 下gdb调试动态链接库库

如何在 Linux 下调试动态链接库_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
如何在 Linux 下调试动态链接库
上传于||文档简介
&&L​i​n​u​x​下​动​态​链​接​库​的​调​试​方​法
阅读已结束,如果下载本文需要使用0下载券
想免费下载更多文档?
下载文档到电脑,查找使用更方便
还剩2页未读,继续阅读
你可能喜欢laokaddk 的BLOG
用户名:laokaddk
文章数:983
评论数:99
访问量:2026198
注册日期:
阅读量:24883
阅读量:275257
阅读量:1006132
阅读量:153410
51CTO推荐博文
今天由于要用到静态链接库,所以就学习了一下相关知识,总结如下:
静态链接库(一般命名为libxxx.a)就是很多.o文件的集合,在你的项目中如果有一个子模快,这个子模块只是给总控模块提供一个函数接口,那么你就可以考虑把这个子模快编译成静态链接库libxxx.a,然后在总控模块中编译的时候,只需-L包含链接库所在的目录,再-lxxx引用链接库就行.
当然,你也可以用动态链接库,具体的动态链接库创建和引用,做法和静态链接库大同小异,只是动态链接库是在程序执行的时候是动态的添加到内存的,所以可以实现进程之间的资源共享.
另外动态链接库可以做到所有的函数本着&有需求才调入&的原则,于是大大节省了系统资源:也就是说什么时候或者什么情况下,链接载入哪个动态链接库函数,完全由程序员在程序代码中控制。这样,当你有一个相当大的工程,每次运行的时候,由于不同的操作需求,就只会有一小部分程序被载入内存。
具体给一个例子,先看一下工程的目录结构:
lib/& main.c& Makefile
Makefile.a& Makefile.so& string.h& strlen.c& strnlen.c
在工程主目录下有main.c主控程序,Makefile文件和lib目录
lib目录下有string.h头文件,strlen.c和strnlen.c,这三个文件里的函数就是我们想生成的库函数
Makefile.a生成静态链接库的makefile文件
Makefile.so生成动态链接库的makefile文件
好,让我们看一看这些文件的具体内容:
头文件string.h,声明相关函数原形
$cat lib/string.h
int Strlen(char *pStr);
int StrNlen(char *pStr, unsigned long ulMaxLen);
strlen.c:函数Strlen的实现,获取给定字符串的长度
$cat lib/strlen.c
#include &stdio.h&
#include &assert.h&
int Strlen(char *pStr)
&&&&unsigned long ulLength;
&&&&assert(NULL != pStr);
&&&&ulLength = 0;
&&&&while(*pStr++)
&&&&&&&&ulLength++;
&&&&return ulLength;
strnlen.c:函数StrNlen的实现,获取给定字符串的长度,如果输入字符串的长度大于指定的最大长度,则返回最大长度,否者返回字符串的实际长度
$cat lib/strnlen.c
#include&stdio.h&
#include&assert.h&
int StrNlen(char *pStr, unsigned long ulMaxLen)
&&&&unsigned long ulLength;
&&&&assert(NULL != pStr);
&&&&if(ulMaxLen &= 0)
&&&&&&&&printf(&Wrong Max Length!\n&);
&&&&&&&&return -1;
&&&&ulLength = 0;
&&&&while(*pStr++ && ulLength & ulMaxLen)
&&&&&&&&ulLength++;
&&&&return ulLength;
这三个文件是在lib/目录下.
Makefile.a:生成静态链接库的makefile文件
$ cat lib/Makefile.a
libstr.a: strlen.o strnlen.o
&&&&$(AR) r $@ $^
&&&&$(RM) $^
.PHONY : clean
&&&&rm -f libstr.a
Makefile.so:生成动态链接库的makefile文件
$ cat Makefile.so
libstr.so: strlen.o strnlen.o
&&&&gcc -fpic -shared -o $@ $^
&&&&$(RM) $^
.PHONY : clean
&&&&rm -f libstr.so
-fpic 使输出的对象模块是按照可重定位地址方式生成的
-shared指定把对应的源文件生成对应的动态链接库文件libstr.so文件
main.c:总控程序
#include &stdio.h&
#include &./lib/string.h& //静态库对应函数的头文件
int main(int argc, char* argv[])
&&&&char str[] = {&hello world&};
&&&&unsigned long ulLength = 0;
&&&&printf(&The string is : %s\n&, str);
&&&&ulLength = Strlen(str);
&&&&printf(&The string length is : %d(use Strlen)\n&, ulLength);
&&&&ulLength = StrNlen(str, 10);
&&&&printf(&The string length is : %d(use StrNlen)\n&, ulLength);
&&&&return 0;
总控Makefile
$ cat Makefile
CFLAGS = -Wall -g
LIBPATH = -L./lib
LIB = -lstr
main: main.o
&&&&$(CC) $(CFLAGS) -o $@ main.o $(LIBPATH) $(LIB)
&&&&$(RM) *.o
.PHONY:clean
&&&&-rm -f main
下面看一看怎么生成和使用静态链接库/动态链接库
1.静态链接库的生成:
$ make -f Makefile.a
cc&&& -c -o strlen.o strlen.c
cc&&& -c -o strnlen.o strnlen.c
ar r libstr.a strlen.o strnlen.o
ar: creating libstr.a
rm -f strlen.o strnlen.o
这样就生成了静态链接库libstr.a了.
2.静态链接库的使用:
$ cat Makefile
CFLAGS = -Wall -g
LIBPATH = -L./lib
LIB = -lstr
main: main.o
&& &$(CC) $(CFLAGS) -o $@ main.o $(LIBPATH) $(LIB)
&& &$(RM) *.o
.PHONY:clean
&& &-rm -f main
-L指定库文件的路径
-l引用库文件
gcc -Wall -g&& -c -o main.o main.c
gcc -Wall -g -o main main.o -L./lib -lstr
lib& main& main.c& Makefile
生成了可执行文件main
The string is : hello world
The string length is : 11(use Strlen)
The string length is : 10(use StrNlen)
3.动态链接库的生成:
先删除刚才生成的静态链接库
$ make clean -f Makefile.a
rm -f libstr.a
$ make -f Makefile.so
cc&&& -c -o strlen.o strlen.c
cc&&& -c -o strnlen.o strnlen.c
gcc -fpic -shared -o libstr.so strlen.o strnlen.o
rm -f strlen.o strnlen.o
libstr.so& Makefile.a& Makefile.so& string.h& strlen.c& strnlen.c
生成了动态链接库libstr.so
4.动态链接库的使用:
使用方法和静态链接库一样,还用的是静态链接库的那个Makefile
$ cat Makefile
CFLAGS = -Wall -g
LIBPATH = -L./lib
LIB = -lstr
main: main.o
&& &$(CC) $(CFLAGS) -o $@ main.o $(LIBPATH) $(LIB)
&& &$(RM) *.o
.PHONY:clean
&& &-rm -f main
-L指定库文件的路径
-l引用库文件
gcc -Wall -g&& -c -o main.o main.c
gcc -Wall -g -o main main.o -L./lib -lstr
lib& main& main.c& Makefile
生成了可执行文件main
./main: error while loading shared libraries: libstr.so: cannot open shared object file: No such file or directory
这就是动态链接库和静态链接库使用时唯一的区别:
在程序运行期间,也需要告诉系统去哪里找你的动态链接库文件.在UNIX下是通过定义名为LD_LIBRARY_PATH 的环境变量来实现的.只需将动态链接库的目录path赋值给此变量即可。
为了让执行程序顺利找到动态库,有三种方法:
1)把库拷贝到/usr/lib和/lib目录下.
2)在LD_LIBRARY_PATH环境变量中加上库所在路径.例如动态库libstr.so在/home/xulei/test/lib目录下,以bash为例,使用命令:
$export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/xulei/test/lib
在环境变量LD_LIBRARY_PATH后添加/home/xulei/test/lib
3) 修改/etc/ld.so.conf文件,把库所在的路径加到文件末尾
然后sudo ldconfig
这样,加入的目录下的所有库文件都可见.
在我的ubuntu下是这样的:
$ cat /etc/ld.so.conf
include /etc/ld.so.conf.d/*.conf
$ ls /etc/ld.so.conf.d/
i486-linux-gnu.conf& libc.conf
$ cat /etc/ld.so.conf.d/libc.conf
# libc default configuration
/usr/local/lib
当然由于ld.so.conf包含/etc/ld.so.conf.d/*.conf,你也可以自己新建个文件vi /etc/ld.so.conf.d/myownlib.conf,然后在其中输入/home/xulei/test/lib
我用的是第二种方法:
$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/xulei/test/lib
The string is : hello world
The string length is : 11(use Strlen)
The string length is : 10(use StrNlen)
最后,使用ldd命令查看可执行文件依赖于哪些库,
$ ldd main
&& &linux-gate.so.1 =&& (0xb7f43000)
&& &libstr.so =& /home/xulei/test/lib/libstr.so (0xb7f3f000)
&& &libc.so.6 =& /lib/tls/i686/cmov/libc.so.6 (0xb7dd9000)
&& &/lib/ld-linux.so.2 (0xb7f44000)
reference:
linux静态链接库与动态链接库
Linux静态/动态链接库的创建和使用
相关代码在附件中
了这篇文章
附件下载:    
类别:┆阅读(0)┆评论(0)
请输入验证码:手把手教你调试Linux C++ 代码
软件调试本身就是一项相对复杂的活动,他不仅要求调试者有着清晰的思路,而且对调试者本身的技能也有很高的要求。Windows下Visual Studio为我们做了很多的工作,使初学者基本上可以获得一个所见即所得的调试体验,相对来说也比较容易上手。然而在linux平台下,一切都显得有些不同,倒不是说GDB有多难,只是对于习惯了visual studio的人来说刚开始会有些不适应。然而对于那些在windows 平台下使用windbg调试代码的人来说,情况会好很多,但是也要有个思维方式的转变以及调试命令的再适应过程。本文将带你开启GDB 调试 Linux 下 C/C++的大门。
1. 准备条件
2. GDB调试单执行文件
3. GDB调试静态链接库
4. GDB调试动态链接库
1. 准备条件
由于Linux下没有visual studio, 对于程序的编译需要借助makefile,下面我先晒出一个简单的makefile,不求大而全,小巧可用就好。
#makefileCC=gcc
CPPFLAGS=-g
LDFLAGS=-g
SRCS=main.cc functions.cc
OBJS=$(subst .cc,.o,$(SRCS))
main: $(OBJS)
$(CXX) $(LDFLAGS) -o main $(OBJS) -L. $(LDLIBS)
main.o: main.cc functions.h testobj.h
functions.o: functions.h functions.cc
$(RM) $(OBJS)
all-clean: clean
$(RM) main
如下是相关的三个文件直接copy就可以使用
main.cc/functions.cc/functions.h
1 #include&iostream&
2 #include"functions.h"
5 int main()
7 std::cout && "Enter two numbers:" && std::
8 int v1 = 0, v2 = 0;
9 std::cin && v1 && v2;
10 std::cout && "The sum of " && v1 && " and " && v2
11 && " is " && v1 + v2 && std::
13 function();
15 return 0;
1 #include&iostream&
2 int function(void)
std::cout && "I am in a function!" && std::
1 int function(void);
将这4个文件放入一个目录下,到这个目录下直接执行make就会产生一个可执行文件main。
2. GDB调试单执行文件
调试结果如下:solidmango@solidmango-pc:~/testmake/Test_L1$ gdb main
GNU gdb (Ubuntu 7.7-0ubuntu3) 7.7
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later &http://gnu.org/licenses/gpl.html&
Reading symbols from main...done.
(gdb) b 2 //在第二行设置断点
Breakpoint 1 at 0x400a4a: file main.cc, line 2.
(gdb) r //全速运行
Starting program: /home/solidmango/testmake/Test_L1/main
Breakpoint 1, main () at main.cc:7
std::cout && "Enter two numbers:" && std:://断点命中
Enter two numbers:
int v1 = 0, v2 = 0;
(gdb) s //单步执行
std::cin && v1 && v2;
&& " is " && v1 + v2 && std::
std::cout && "The sum of " && v1 && " and " && v2
&& " is " && v1 + v2 && std::
The sum of 5 and 6 is 11
function();
3. GDB调试静态链接库
对于静态链接库的调试和单个的执行文件相似,因为最终的文件都被链接在一起。对于静态链接库的调试需要两个额外两个辅助文件以及对makefile和main.cc稍作修改,具体改动如下:
CPPFLAGS=-g
LDFLAGS=-g
LDLIBS=-ltest #changed
SRCS=main.cc functions.cc
OBJS=$(subst .cc,.o,$(SRCS))
main: $(OBJS) libtest.a #changed
$(CXX) $(LDFLAGS) -o main $(OBJS) -L. $(LDLIBS) main.o: main.cc functions.h testobj.h functions.o: functions.h functions.cc clean: $(RM) $(OBJS) all-clean: clean $(RM) main
main.cc/testobj.cc/testobj.h
#include&iostream&
#include"functions.h"
#include"testobj.h"
int main()
std::cout && "Enter two numbers:" && std::
int v1 = 0, v2 = 0;
std::cin && v1 && v2;
std::cout && "The sum of " && v1 && " and " && v2
&& " is " && v1 + v2 && std::
function();
TestObj();
#include&iostream&
int TestObj(void)
std::cout && "I am in TestObj!" && std::
int TestObj(void);
执行结果如下:
solidmango@solidmango-pc:~/testmake/Test_L1$ g++ -g -c -o testobj.o testobj.cc
solidmango@solidmango-pc:~/testmake/Test_L1$ ar rv libtest.a testobj.o
ar: creating libtest.a
a - testobj.o
solidmango@solidmango-pc:~/testmake/Test_L1$ make
-c -o main.o main.cc
-c -o functions.o functions.cc
g++ -g -o main main.o functions.o -L. -ltest
solidmango@solidmango-pc:~/testmake/Test_L1$ ./main
Enter two numbers:
The sum of 5 and 6 is 11
I am in a function!
I am in TestObj!
solidmango@solidmango-pc:~/testmake/Test_L1$
4. GDB调试动态链接库对于动态链接库的调试和单个的执行文件差别较大,相对于静态链接库的调试只需要对makefile
稍作修改,具体改动如下:
生成相应的动态库并copy到系统目录
g++ -g -c -fPIC -o testobj.o testobj.cc
-shared -o libtest.so testobj.o
sudo cp libtest.so /lib/libtest.so
CPPFLAGS=-g
LDFLAGS=-g
LDLIBS=-ltest
SRCS=main.cc functions.cc
OBJS=$(subst .cc,.o,$(SRCS))
main: $(OBJS) libtest.so
$(CXX) $(LDFLAGS) -o main $(OBJS) -L. $(LDLIBS)
main.o: main.cc functions.h testobj.h
functions.o: functions.h functions.cc
$(RM) $(OBJS)
all-clean: clean
$(RM) main
调试结果如下:solidmango@solidmango-pc:~/testmake/Test_L1$ gdb main
GNU gdb (Ubuntu 7.7-0ubuntu3) 7.7
Copyright (C) 2014 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".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
&http://www.gnu.org/software/gdb/bugs/&.
Find the GDB manual and other documentation resources online at:
&http://www.gnu.org/software/gdb/documentation/&.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from main...done.
(gdb) b TestObj
Breakpoint 1 at 0x400910
Starting program: /home/solidmango/testmake/Test_L1/main
Enter two numbers:
The sum of 7 and 8 is 15
I am in a function!
Breakpoint 1, 0x0910 in TestObj()@plt ()
Single stepping until exit from function _Z7TestObjv@plt,
which has no line number information.
TestObj () at testobj.cc:3
TestObj () at testobj.cc:3
0x0b05 in main () at main.cc:17
(gdb) info sharedlibrary
Shared Object Library
0x00007ffff7ddaae0
0x00007ffff7df54e0
/lib64/ld-linux-x86-64.so.2
0x00007ffff7bd07ffff7bd89c5
/lib/libtest.so
0x00007ffff792f5c0
0x00007ffff799299a
/usr/lib/x86_64-linux-gnu/libstdc++.so.6
0x00007ffff752d4a0
0x00007ffff7673413
/lib/x86_64-linux-gnu/libc.so.6
0x00007ffff720d610
0x00007ffff727c1b6
/lib/x86_64-linux-gnu/libm.so.6
0x00007ffff6ff4ab0
0x00007ffff7004995
/lib/x86_64-linux-gnu/libgcc_s.so.1
(*): Shared library is missing debugging information.
(gdb) list
1 #include&iostream&
2 int TestObj(void)
std::cout && "I am in TestObj!" && std::
本文总结了Linux下基于GDB的3种情况的调试方式,其中包括单个可执行文件,静态链接,动态链接,并给出了完整的makefile, 源文件,可操作性极强,建议感兴趣的朋友亲自动手操作演练,希望对大家有所帮助。
阅读(...) 评论()求大神帮忙,gdb怎么调试.so动态链接库?_百度知道
求大神帮忙,gdb怎么调试.so动态链接库?
但是在linux真不知道怎么设置,求大神帮忙?我一直在vc下当码圣士,只有要修改那个模块,把当前项目生成的dll设置到主程序exe的目录下就可以掉.so源代码。最近公司给一个很大linux服务器项目,求帮忙,没有主程序的源代码,该怎么单独调试动态链接库,只要把项目的启动项设为主程序,我知道在vc下这种情况可以很轻松的调有源码的dll,不知道怎么调.exe.so有源码,剩下都没有源码假如只有动态链接库
我有更好的答案
lua加载so,不怎么怎么调,崩在so里好烦
回复 4# linux_c_py_php 非常感谢,你帮了我一个大忙,我本来还是一直用输出来确定变量的值的。每次都要重新编。。谢了。
码圣士 威武.....
其他类似问题
为您推荐:
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁}

我要回帖

更多关于 gdb调试动态链接库 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信