首页 > 代码库 > 手把手教你调试Linux C++ 代码

手把手教你调试Linux C++ 代码

手把手教你调试Linux C++ 代码

软件调试本身就是一项相对复杂的活动,他不仅要求调试者有着清晰的思路,而且对调试者本身的技能也有很高的要求。Windows下Visual Studio为我们做了很多的工作,使初学者基本上可以获得一个所见即所得的调试体验,相对来说也比较容易上手。然而在linux平台下,一切都显得有些不同,倒不是说GDB有多难,只是对于习惯了visual studio的人来说刚开始会有些不适应。然而对于那些在windows 平台下使用windbg调试代码的人来说,情况会好很多,但是也要有个思维方式的转变以及调试命令的再适应过程。本文将带你开启GDB 调试 Linux 下 C/C++的大门。

Agenda

1. 准备条件

2. GDB调试单执行文件

3. GDB调试静态链接库

4. GDB调试动态链接库

 

1. 准备条件

由于Linux下没有visual studio, 对于程序的编译需要借助makefile,下面我先晒出一个简单的makefile,不求大而全,小巧可用就好。

#makefile
CC=gccCXX=g++RM=rm -fCPPFLAGS=-gLDFLAGS=-gLDLIBS=AR=arSRCS=main.cc functions.ccOBJS=$(subst .cc,.o,$(SRCS))all: mainmain: $(OBJS) $(CXX) $(LDFLAGS) -o main $(OBJS) -L. $(LDLIBS) main.o: main.cc functions.h testobj.hfunctions.o: functions.h functions.ccclean: $(RM) $(OBJS)all-clean: clean $(RM) main

如下是相关的三个文件直接copy就可以使用

main.cc/functions.cc/functions.h

 1 #include<iostream> 2 #include"functions.h" 5 int main() 6 { 7 std::cout << "Enter two numbers:" << std::endl; 8 int v1 = 0, v2 = 0; 9 std::cin >> v1 >> v2;10 std::cout << "The sum of " << v1 << " and " << v211 << " is " << v1 + v2 << std::endl;12 13 function();14 15 return 0;16 }
1 #include<iostream>2 int function(void)3 {4     std::cout << "I am in a function!" << std::endl;5     return 0;6 }
1 int function(void);

将这4个文件放入一个目录下,到这个目录下直接执行make就会产生一个可执行文件main。

2. GDB调试单执行文件

调试结果如下:
solidmango@solidmango-pc:~/testmake/Test_L1$ gdb mainGNU gdb (Ubuntu 7.7-0ubuntu3) 7.7Copyright (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/mainBreakpoint 1, main () at main.cc:77 std::cout << "Enter two numbers:" << std::endl;//断点命中(gdb) sEnter two numbers:8 int v1 = 0, v2 = 0;(gdb) s //单步执行9 std::cin >> v1 >> v2;(gdb) n5611 << " is " << v1 + v2 << std::endl;(gdb) s10 std::cout << "The sum of " << v1 << " and " << v2(gdb) s11 << " is " << v1 + v2 << std::endl;(gdb) sThe sum of 5 and 6 is 1114 function();(gdb)

 

3. GDB调试静态链接库

对于静态链接库的调试和单个的执行文件相似,因为最终的文件都被链接在一起。对于静态链接库的调试需要两个额外两个辅助文件以及对makefile和main.cc稍作修改,具体改动如下:

#makefileCC=gccCXX=g++RM=rm -fCPPFLAGS=-gLDFLAGS=-gLDLIBS=-ltest #changedAR=arSRCS=main.cc functions.ccOBJS=$(subst .cc,.o,$(SRCS))all: mainmain: $(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::endl;int v1 = 0, v2 = 0;std::cin >> v1 >> v2;std::cout << "The sum of " << v1 << " and " << v2<< " is " << v1 + v2 << std::endl;function();TestObj();return 0;}

 

#include<iostream>int TestObj(void){    std::cout << "I am in TestObj!" << std::endl;    return 0;}
int TestObj(void);

执行结果如下:

solidmango@solidmango-pc:~/testmake/Test_L1$ g++ -g -c -o testobj.o testobj.ccsolidmango@solidmango-pc:~/testmake/Test_L1$ ar rv libtest.a testobj.oar: creating libtest.aa - testobj.osolidmango@solidmango-pc:~/testmake/Test_L1$ makeg++  -g  -c -o main.o main.ccg++  -g  -c -o functions.o functions.ccg++ -g -o main main.o functions.o -L. -ltest solidmango@solidmango-pc:~/testmake/Test_L1$ ./mainEnter two numbers:56The sum of 5 and 6 is 11I 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.ccg++ -g  -shared -o libtest.so testobj.osudo cp libtest.so /lib/libtest.so

makefile

CC=gccCXX=g++RM=rm -fCPPFLAGS=-gLDFLAGS=-gLDLIBS=-ltestAR=arSRCS=main.cc functions.ccOBJS=$(subst .cc,.o,$(SRCS))all: mainmain: $(OBJS) libtest.so    $(CXX) $(LDFLAGS) -o main $(OBJS) -L. $(LDLIBS)     main.o: main.cc functions.h testobj.hfunctions.o: functions.h functions.ccclean:    $(RM) $(OBJS)all-clean: clean    $(RM) main
调试结果如下:
solidmango@solidmango-pc:~/testmake/Test_L1$ gdb mainGNU gdb (Ubuntu 7.7-0ubuntu3) 7.7Copyright (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 TestObjBreakpoint 1 at 0x400910(gdb) rStarting program: /home/solidmango/testmake/Test_L1/main Enter two numbers:78The sum of 7 and 8 is 15I am in a function!Breakpoint 1, 0x0000000000400910 in TestObj()@plt ()(gdb) sSingle stepping until exit from function _Z7TestObjv@plt,which has no line number information.TestObj () at testobj.cc:33 {(gdb) bt#0 TestObj () at testobj.cc:3#1 0x0000000000400b05 in main () at main.cc:17(gdb) info sharedlibrary From To Syms Read Shared Object Library0x00007ffff7ddaae0 0x00007ffff7df54e0 Yes /lib64/ld-linux-x86-64.so.20x00007ffff7bd8850 0x00007ffff7bd89c5 Yes /lib/libtest.so0x00007ffff792f5c0 0x00007ffff799299a Yes (*) /usr/lib/x86_64-linux-gnu/libstdc++.so.60x00007ffff752d4a0 0x00007ffff7673413 Yes /lib/x86_64-linux-gnu/libc.so.60x00007ffff720d610 0x00007ffff727c1b6 Yes /lib/x86_64-linux-gnu/libm.so.60x00007ffff6ff4ab0 0x00007ffff7004995 Yes (*) /lib/x86_64-linux-gnu/libgcc_s.so.1(*): Shared library is missing debugging information.(gdb) list1 #include<iostream>2 int TestObj(void)3 {4 std::cout << "I am in TestObj!" << std::endl;5 return 0;6 }(gdb)

总结

本文总结了Linux下基于GDB的3种情况的调试方式,其中包括单个可执行文件,静态链接,动态链接,并给出了完整的makefile, 源文件,可操作性极强,建议感兴趣的朋友亲自动手操作演练,希望对大家有所帮助。

手把手教你调试Linux C++ 代码