手把手教你调试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=gcc
CXX=g++
RM=rm -f
CPPFLAGS=-g
LDFLAGS=-g
LDLIBS=
AR=ar SRCS=main.cc functions.cc
OBJS=$(subst .cc,.o,$(SRCS)) all: main
main: $(OBJS)
$(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

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

main.cc/functions.cc/functions.h

 #include<iostream>
#include"functions.h"
int main()
{
std::cout << "Enter two numbers:" << std::endl;
int v1 = , v2 = ;
std::cin >> v1 >> v2;
std::cout << "The sum of " << v1 << " and " << v2
<< " is " << v1 + v2 << std::endl; function(); return ;
}
 #include<iostream>
int function(void)
{
std::cout << "I am in a function!" << std::endl;
return ;
}
 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) Free Software Foundation, Inc.
License GPLv3+: GNU GPL version or later <http://gnu.org/licenses/gpl.html>
Reading symbols from main...done. (gdb) b //在第二行设置断点
Breakpoint at 0x400a4a: file main.cc, line .
(gdb) r //全速运行
Starting program: /home/solidmango/testmake/Test_L1/main Breakpoint , main () at main.cc:
std::cout << "Enter two numbers:" << std::endl;//断点命中
(gdb) s
Enter two numbers:
int v1 = , v2 = ;
(gdb) s //单步执行
std::cin >> v1 >> v2;
(gdb) n << " is " << v1 + v2 << std::endl;
(gdb) s
std::cout << "The sum of " << v1 << " and " << v2
(gdb) s
<< " is " << v1 + v2 << std::endl;
(gdb) s
The sum of and is
function();
(gdb)

3. GDB调试静态链接库

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

#makefile
CC=gcc
CXX=g++
RM=rm -f
CPPFLAGS=-g
LDFLAGS=-g
LDLIBS=-ltest #changed
AR=ar SRCS=main.cc functions.cc
OBJS=$(subst .cc,.o,$(SRCS)) all: main
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::endl;
int v1 = , v2 = ;
std::cin >> v1 >> v2;
std::cout << "The sum of " << v1 << " and " << v2
<< " is " << v1 + v2 << std::endl; function(); TestObj(); return ;
}
#include<iostream>
int TestObj(void)
{
std::cout << "I am in TestObj!" << std::endl;
return ;
}
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
g++ -g -c -o main.o main.cc
g++ -g -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 and is
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
g++ -g -shared -o libtest.so testobj.o
sudo cp libtest.so /lib/libtest.so

makefile

CC=gcc
CXX=g++
RM=rm -f
CPPFLAGS=-g
LDFLAGS=-g
LDLIBS=-ltest
AR=ar SRCS=main.cc functions.cc
OBJS=$(subst .cc,.o,$(SRCS)) all: main
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 clean:
$(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
(gdb) r
Starting program: /home/solidmango/testmake/Test_L1/main
Enter two numbers:
7
8
The sum of 7 and 8 is 15
I am in a function! Breakpoint 1, 0x0000000000400910 in TestObj()@plt ()
(gdb) s
Single stepping until exit from function _Z7TestObjv@plt,
which has no line number information.
TestObj () at testobj.cc:3
3 {
(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 Library
0x00007ffff7ddaae0 0x00007ffff7df54e0 Yes /lib64/ld-linux-x86-64.so.2
0x00007ffff7bd8850 0x00007ffff7bd89c5 Yes /lib/libtest.so
0x00007ffff792f5c0 0x00007ffff799299a Yes (*) /usr/lib/x86_64-linux-gnu/libstdc++.so.6
0x00007ffff752d4a0 0x00007ffff7673413 Yes /lib/x86_64-linux-gnu/libc.so.6
0x00007ffff720d610 0x00007ffff727c1b6 Yes /lib/x86_64-linux-gnu/libm.so.6
0x00007ffff6ff4ab0 0x00007ffff7004995 Yes (*) /lib/x86_64-linux-gnu/libgcc_s.so.1
(*): Shared library is missing debugging information.
(gdb) list
1 #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++ 代码(一步到位包含静态库和动态库调试)的更多相关文章

  1. 使用QEMU调试Linux内核代码

    http://blog.chinaunix.net/uid-20729583-id-1884617.html http://www.linuxidc.com/Linux/2014-08/105510. ...

  2. 静态库和动态库的区别和win平台和linux平台代码实现

    静态库和动态库的区别   什么是库 库是写好的,现有的,成熟的,可以复用的代码.现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常. 本质上来说,库是一种可 ...

  3. Linux下c函数dlopen实现加载动态库so文件代码举例

    dlopen()是一个强大的库函数.该函数将打开一个新库,并把它装入内存.该函数主要用来加载库中的符号,这些符号在编译的时候是不知道的.这种机制使得在系统中添加或者删除一个模块时,都不需要重新编译了. ...

  4. 转:手把手教你如何玩转Solr(包含项目实战)

    原文地址:手把手教你如何玩转Solr(包含项目实战) 参考原文

  5. 详细讲解 关于Linux静态库和动态库的分析

    基本概念 库有动态与静态两种,动态通常用.so为后缀,静态用.a为后缀. 例如:libhello.so libhello.a 为了在同一系统中使用不同版本的库,可以在库文件名后加上版本号为后缀,例如: ...

  6. 浅谈linux静态库、动态库。

    动态库又叫动态共享文件(.so,Dynamic Shared Objects)和静态库(.a)都是将一些待重用的公共代码打包成一种特殊的重定位目标文件. 在使用时,连接器会将静态库中所有的代码,编译到 ...

  7. linux下静态库和动态库一些东西

    http://www.cnblogs.com/changefuture/archive/2011/12/22/2297460.html Linux  动态链接库和静态库示例 文件预览 文件目录树如下, ...

  8. VisualGDB系列7:使用VS创建Linux静态库和动态库

    根据VisualGDB官网(https://visualgdb.com)的帮助文档大致翻译而成.主要是作为个人学习记录.有错误的地方,Robin欢迎大家指正. 本文介绍如何在VS中创建静态库和动态库, ...

  9. 【C/C++开发】C++静态库与动态库以及在Linux和Windows上的创建使用

    原文出处: 吴秦的博客    这次分享的宗旨是--让大家学会创建与使用静态库.动态库,知道静态库与动态库的区别,知道使用的时候如何选择.这里不深入介绍静态库.动态库的底层格式,内存布局等,有兴趣的同学 ...

随机推荐

  1. JavaFX結合 JDBC, Servlet, Swing, Google Map及動態產生比例圖 (2):JavaFX建立及程式碼說明 (转帖)

    說明:就如同標題一樣,前端會用到JavaFX.Swing.Java Web Start.Google Map 的技術, 後端就是JDBC.Servlet的技術,以及我們會簽署認證jar檔案,這樣才可存 ...

  2. seajs 源码阅读笔记

    代码概览 src目录文件列表如下: 代码以模块化的方式来组织,构建的时候会合并为一个js文件(sea.js 或 sea-debug.js),其中,intro.js和 outro.js 分别是这个js文 ...

  3. [教程]怎么用百度云观看和下载"磁力链接"无需下载直接观看.

    1, 打开网址 http://okbt.net/  输入你想要看的电影名字, 点搜索,鼠标右键点击拷贝磁力链接.或者 电脑装了迅雷的话.可以直接点击.用迅雷下载. 磁力链接都是这种格式的.例: mag ...

  4. EF6(CodeFirst)+MySql开发脱坑指南

    废话 话说当年,在一个春光明媚的晌午,邂逅了迷人的丁香姑娘,从此拜倒在了她的石榴裙下,至今不能自拔,这位丁香姑娘就是ORM思想. 所谓ORM思想,我的理解就是根据一定的规则,把程序中的对象和数据库中的 ...

  5. 【C语言学习】《C Primer Plus》第7章 C控制语句:分支与跳转

    学习总结 1.if…else…从语义上看就能出用途,跟其他语言没差多少,只需要记住,世界上最遥远的距离之一:我走if你却走else. 2.根据个人几年的编程经验,太多的if…else…嵌套会加大代码的 ...

  6. 使用NPOI读写Excel、Word

    NPOI 是 POI 项目的 .NET 版本.POI是一个开源的Java读写Excel.WORD等微软OLE2组件文档的项目. 使用 NPOI 你就可以在没有安装 Office 或者相应环境的机器上对 ...

  7. Java-继承,多态0922-05

    28.按要求编写一个Java应用程序: (1)定义一个类,描述一个矩形,包含有长.宽两种属性,和计算面积方法. (2)编写一个类,继承自矩形类,同时该类描述长方体,具有长.宽.高属性, 和计算体积的方 ...

  8. MVVM架构~knockoutjs实现简单的购物车

    返回目录 概念相关 购物车相信大家都用过,很方便,可以将多个商品添加到购物车,并且可以修改购买商品的数据,当然为了用户体验好,在修改数据时,你的价格也会出现变化的,这使用JS可以实现,但我认为,代码量 ...

  9. 基础才是重中之重~AutoMapper为已有目标对象映射

    回到目录 AutoMapper各位一定不会陌生,大叔之前的文章中也提到过,曾经也写过扩展方法,以方便程序开发人员去使用它,而在最近,大叔在一个API项目里,在一个POST请求由DTO对象为实体对象赋值 ...

  10. C#学习系列-String与string的区别

    参考:http://www.microsoftvirtualacademy.com/Content/ViewContent.aspx?et=9851&m=9832&ct=31042 如 ...