文章目录
  1. 1. 1.总体选项
  2. 2. 2.目录选项
  3. 3. 3.调试选项
  4. 4. 4.链接方式选项:
  5. 5. 一、Linux程序gcc编译步骤:
  6. 6. 二、Linux程序gdb调试步骤:
1. 编译与重命名等

g++ –c Hello.cpp 编译文件,生成目标文件 Hello.o

g++ Hello.o –o abc 连接 并重命名为可执行文件 abc

g++ Hello.cpp 编译连接一起,生成a.out

g++ Hello.cpp –o hello 生成a.out并命名为hello

2. 使用GDB调试:
C:\c>g++ hello.cpp -o helloDebug -g
———————>生成可调试文件

C:\c>dir

驱动器 C 中的卷是 BOOTCAMP

卷的序列号是 1A3B-190C


C:\c 的目录


2015/09/09 19:18 <DIR> .

2015/09/09 19:18 <DIR> ..

2015/09/09 13:16 26,256 a.exe

2015/09/09 13:16 26,256 abc.exe

2015/09/09 13:08 26,256 b.exe

2015/09/09 13:07 26,256 c.exe

2014/09/24 16:06 274 hello.cpp

2015/09/09 13:17 26,256 hello.exe

2015/09/09 13:15 1,942 hello.o

2015/09/09 19:18 39,630 helloDebug.exe

2015/09/09 13:09 39,630 test.exe

9 个文件 212,756 字节

2 个目录 13,267,927,040 可用字节


C:\c>gdb helloDebug.exe
————————–>启动GDB开始调试

GNU gdb (GDB) 7.2

Copyright (C) 2010 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 "mingw32".

For bug reporting instructions, please see:

<http://www.gnu.org/software/gdb/bugs/>...

Reading symbols from C:\c/helloDebug.exe…done.

(gdb) l —-> l命令相当于list,从第一行开始例出原码。
1 //2_3.cpp

2 #include<iostream>

3 using namespace std;

4 int main()

5 {

6 int x,y;

7 cout<<"Enter x and y:";

8 cin>>x>>y;

9 if (x!=y)

10 if (x>y)

(gdb) —–> 直接回车表示,重复上一次命令

11 cout<<"x>y"<<endl;

12 else

13 cout<<"x<y"<<endl;

14 else

15 cout<<"x=y"<<endl;

16 }

(gdb) b 6 —–>设置断点,在源程序第6行处

Breakpoint 1 at 0x4013ce: file hello.cpp, line 6.

(gdb) break 8 –>设置断点,在源程序第8行处

Breakpoint 2 at 0x4013e2: file hello.cpp, line 8.

(gdb) info b —->查看断点信息。

Num Type Disp Enb Address What

1 breakpoint keep y 0x004013ce in main() at hello.cpp:6

2 breakpoint keep y 0x004013e2 in main() at hello.cpp:8

(gdb) r —->运行程序,run命令简写

Starting program: C:\c/helloDebug.exe

[New Thread 5896.0x19d8]


Breakpoint 1, main () at hello.cpp:7 -–>在断点处停住

7 cout<<"Enter x and y:";
(gdb) n —>单条语句执行,next命令简写

Enter x and y:

Breakpoint 2, _fu0___ZSt4cout () at hello.cpp:8

8 cin>>x>>y;

(gdb) –> 直接回车表示,重复上一次命令

3 2

9 if (x!=y)
(gdb) p x –>打印变量x的值,print命令简写

$1 = 3

(gdb) p y –>打印变量y的值

$2 = 2
(gdb) c –>继续运行程序,continue命令简写

Continuing.

x>y


Program exited normally.
(gdb) q —>退出gdb


C:\c>

3. 备注

使用GDB

————

一般来说GDB主要调试的是C/C++的程序。要调试C/C++的程序,首先在编译时,我们必须要把调试信息加到可执行文件中。使用编译器(cc/gcc/g++)的 -g 参数可以做到这一点。如:

> cc -g hello.c -o hello

> g++ -g hello.cpp -o hello

如果没有-g,你将看不见程序的函数名、变量名,所代替的全是运行时的内存地址。当你用-g把调试信息加入之后,并成功编译目标代码以后,让我们来看看如何用gdb来调试他。

启动GDB的方法有以下几种:

1、gdb <program>

program也就是你的执行文件,一般在当然目录下。

2、gdb <program> core

用gdb同时调试一个运行程序和core文件,core是程序非法执行后core dump后产生的文件。

3、gdb <program> <PID>

如果你的程序是一个服务程序,那么你可以指定这个服务程序运行时的进程ID。gdb会自动attach上去,并调试他。program应该在PATH环境变量中搜索得到。

GDB启动时,可以加上一些GDB的启动开关,详细的开关可以用gdb -help查看。我在下面只例举一些比较常用的参数:

-symbols <file>

-s <file>

从指定文件中读取符号表。

-se file

从指定文件中读取符号表信息,并把他用在可执行文件中。

-core <file>

-c <file>

调试时core dump的core文件。

-directory <directory>

-d <directory>

加入一个源文件的搜索路径。默认搜索路径是环境变量中PATH所定义的路径。

4. 其他

1.总体选项

-E

只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里

面.

例子用法:

gcc -E hello.c > pianoapan.txt

gcc -E hello.c | more

慢慢看吧,一个hello word 也要与处理成800行的代码

-S

只激活预处理和编译,就是指把文件编译成为汇编代码。

例子用法

gcc -S hello.c

他将生成.s的汇编代码,你可以用文本编辑器察看

-c

只激活预处理,编译,和汇编,也就是他只把程序做成obj文件

例子用法:

gcc -c hello.c

他将生成.o的obj文件

2.目录选项

-Idir

在你是用#include"file"的时候,gcc/g++会先在当前目录查找你所制定的头

文件,如果没有找到,他回到缺省的头文件目录找,如果使用-I制定了目录,他

回先在你所制定的目录查找,然后再按常规的顺序去找.

对于#include,gcc/g++会到-I制定的目录查找,查找不到,然后将到系

统的缺省的头文件目录查找

-include file

-i

相当于“#include”

包含某个代码,简单来说,就是便以某个文件,需要另一个文件的时候,就可以

用它设定,功能就相当于在代码中使用#include

例子用法:

gcc hello.c -include /root/pianopan.h

-I-

就是取消前一个参数的功能,所以一般在-Idir之后使用

-idirafter dir

在-I的目录里面查找失败,讲到这个目录里面查找.

-iprefix prefix

-iwithprefix dir


一般一起使用,当-I的目录查找失败,会到prefix+dir下查找

-Ldir

制定编译的时候,搜索库的路径。比如你自己的库,可以用它制定目录,不然

编译器将只在标准库的目录找。这个dir就是目录的名称。

-llibrary

制定编译的时候使用的库

例子用法

gcc -lcurses hello.c

使用ncurses库编译程序

3.调试选项

-g

只是编译器,在编译的时候,产生调试信息。

-gstabs

此选项以stabs格式声称调试信息,但是不包括gdb调试信息.

-gstabs+

此选项以stabs格式声称调试信息,并且包含仅供gdb使用的额外调试信息.

-ggdb

此选项将尽可能的生成gdb的可以使用的调试信息.

-glevel

请求生成调试信息,同时用level指出需要多少信息,默认的level值是2

4.链接方式选项:

-static 此选项将禁止使用动态库。

优点:程序运行不依赖于其他库

缺点:文件比较大

-shared (-G) 此选项将尽量使用动态库,为默认选项

优点:生成文件比较小

缺点:运行时需要系统提供动态库

-symbolic 建立共享目标文件的时候,把引用绑定到全局符号上.

对所有无法解析的引用作出警告(除非用连接编辑选项 -Xlinker -z -Xlinker defs'取代)。</p><p style="color: rgb(54, 46, 43); margin: 10px auto; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; text-align: justify; background-color: rgb(255, 255, 255);">注:只有部分系统支持该选项.</p><h1 style="margin: 0px; padding: 0px; color: rgb(54, 46, 43); font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 19px; text-align: justify; background-color: rgb(255, 255, 255);"><font size="3"><a name="t4" style="color: rgb(106, 57, 6);"></a>5.错误与告警选项</font></h1><p style="color: rgb(54, 46, 43); margin: 10px auto; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; text-align: justify; background-color: rgb(255, 255, 255);"> <span style="color: rgb(255, 0, 0);"> -Wall</span> 一般使用该选项,允许发出GCC能够提供的所有有用的警告。也可以用-W{warning}来标记指定的警告。</p><p style="color: rgb(54, 46, 43); margin: 10px auto; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; text-align: justify; background-color: rgb(255, 255, 255);"> <span style="color: rgb(255, 0, 0);">-pedantic </span>允许发出ANSI/ISO C标准所列出的所有警告</p><p style="color: rgb(54, 46, 43); margin: 10px auto; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; text-align: justify; background-color: rgb(255, 255, 255);"> <span style="color: rgb(255, 0, 0);">-pedantic-errors</span> 允许发出ANSI/ISO C标准所列出的错误</p><p style="color: rgb(54, 46, 43); margin: 10px auto; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; text-align: justify; background-color: rgb(255, 255, 255);"> <span style="color: rgb(255, 0, 0);"> -werror</span> 把所有警告转换为错误,以在警告发生时中止编译过程</p><p style="color: rgb(54, 46, 43); margin: 10px auto; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; text-align: justify; background-color: rgb(255, 255, 255);"> <span style="color: rgb(255, 0, 0);">-w</span> 关闭所有警告,建议不要使用此项</p><h1 style="margin: 0px; padding: 0px; color: rgb(54, 46, 43); font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 19px; text-align: justify; background-color: rgb(255, 255, 255);"><font size="3"><a name="t5" style="color: rgb(106, 57, 6);"></a>6.预处理选项</font></h1><p style="color: rgb(54, 46, 43); margin: 10px auto; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; text-align: justify; background-color: rgb(255, 255, 255);"><span style="color: rgb(255, 0, 0);"> -Dmacro </span><br/> 相当于C语言中的#define macro <br/> <span style="color: rgb(255, 0, 0);">-Dmacro=defn </span><br/> 相当于C语言中的#define macro=defn <br/> <span style="color: rgb(255, 0, 0);"> -Umacro </span><br/> 相当于C语言中的#undef macro <br/> <span style="color: rgb(255, 0, 0);"> -undef </span><br/> 取消对任何非标准宏的定义 </p><h1 style="margin: 0px; padding: 0px; color: rgb(54, 46, 43); font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 19px; text-align: justify; background-color: rgb(255, 255, 255);"><font size="3"><a name="t6" style="color: rgb(106, 57, 6);"></a>7.其他选项</font></h1><p style="color: rgb(54, 46, 43); margin: 10px auto; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; text-align: justify; background-color: rgb(255, 255, 255);"><span style="color: rgb(255, 0, 0);"> -o</span></p><p style="color: rgb(54, 46, 43); margin: 10px auto; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; text-align: justify; background-color: rgb(255, 255, 255);">制定目标名称,缺省的时候,gcc 编译出来的文件是a.out,很难听,如果你和我有同感,改掉它,哈哈</p><p style="color: rgb(54, 46, 43); margin: 10px auto; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; text-align: justify; background-color: rgb(255, 255, 255);">例子用法 <br/> gcc -o hello.exe hello.c (哦,windows用习惯了) <br/> gcc -o hello.asm -S hello.c <br/> <span style="color: rgb(255, 0, 0);">-O0 <br/> -O1 <br/> -O2 <br/> -O3 </span><br/> 编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高</p><p style="color: rgb(54, 46, 43); margin: 10px auto; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; text-align: justify; background-color: rgb(255, 255, 255);"> <span style="color: rgb(255, 0, 0);">-fpic </span>编译器就生成位置无关目标码.适用于共享库(shared library).</p><p style="color: rgb(54, 46, 43); margin: 10px auto; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; text-align: justify; background-color: rgb(255, 255, 255);"> <span style="color: rgb(255, 0, 0);">-fPIC</span> 编译器就输出位置无关目标码.适用于动态连接(dynamic linking),即使分支需要大范围转移.</p><p style="color: rgb(54, 46, 43); margin: 10px auto; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; text-align: justify; background-color: rgb(255, 255, 255);"> <span style="color: rgb(255, 0, 0);">-v</span> 显示详细的编译、汇编、连接命令<br/> <span style="color: rgb(255, 0, 0);">-pipe </span><br/> 使用管道代替编译中临时文件,在使用非gnu汇编工具的时候,可能有些问题 <br/> gcc -pipe -o hello.exe hello.c <br/> <span style="color: rgb(255, 0, 0);"> -ansi </span> <br/> 关闭gnu c中与ansi c不兼容的特性,激活ansi c的专有特性(包括禁止一些asm inline typeof关键字,以及UNIX,vax等预处理宏, <br/> <span style="color: rgb(255, 0, 0);"> -fno-asm </span><br/> 此选项实现ansi选项的功能的一部分,它禁止将asm,inline和typeof用作关键字。 <br/> <span style="color: rgb(255, 0, 0);">-fno-strict-prototype </span><br/> 只对g++起作用,使用这个选项,g++将对不带参数的函数,都认为是没有显式的对参数的个数和类型说明,而不是没有参数.而gcc无论是否使用这个参数,都将对没有带参数的函数,认为城没有显式说明的类型 <br/> <span style="color: rgb(255, 0, 0);"> -fthis-is-varialble </span><br/> 就是向传统c++看齐,可以使用this当一般变量使用. <br/> <span style="color: rgb(255, 0, 0);">-fcond-mismatch </span><br/> 允许条件表达式的第二和第三参数类型不匹配,表达式的值将为void类型 <br/> <span style="color: rgb(255, 0, 0);"> -funsigned-char <br/> -fno-signed-char <br/> -fsigned-char <br/> -fno-unsigned-char </span><br/> 这四个参数是对char类型进行设置,决定将char类型设置成unsigned char(前 <br/> 两个参数)或者 signed char(后两个参数) <br/> <span style="color: rgb(255, 0, 0);"> -imacros file </span><br/> 将file文件的宏,扩展到gcc/g++的输入文件,宏定义本身并不出现在输入文件中 <br/> <span style="color: rgb(255, 0, 0);"> -nostdinc </span><br/> 使编译器不再系统缺省的头文件目录里面找头文件,一般和-I联合使用,明确限定头文件的位置 <br/> <span style="color: rgb(255, 0, 0);">-nostdin C++ </span><br/> 规定不在g++指定的标准路经中搜索,但仍在其他路径中搜索,.此选项在创建libg++库使用 <br/> <span style="color: rgb(255, 0, 0);"> -C </span><br/> 在预处理的时候,不删除注释信息,一般和-E使用,有时候分析程序,用这个很方便的 <br/> <span style="color: rgb(255, 0, 0);"> -M </span><br/> 生成文件关联的信息。包含目标文件所依赖的所有源代码你可以用gcc -M hello.c来测试一下,很简单。 <br/> <span style="color: rgb(255, 0, 0);"> -MM </span><br/> 和上面的那个一样,但是它将忽略由#include造成的依赖关系。 <br/> <span style="color: rgb(255, 0, 0);">-MD </span><br/> 和-M相同,但是输出将导入到.d的文件里面 <br/> <span style="color: rgb(255, 0, 0);"> -MMD </span><br/> 和-MM相同,但是输出将导入到.d的文件里面 <br/> <span style="color: rgb(255, 0, 0);">-Wa,option </span><br/> 此选项传递option给汇编程序;如果option中间有逗号,就将option分成多个选项,然后传递给会汇编程序 <br/> <span style="color: rgb(255, 0, 0);">-Wl.option </span><br/> 此选项传递option给连接程序;如果option中间有逗号,就将option分成多个选项,然后传递给会连接程序.</p><p style="color: rgb(54, 46, 43); margin: 10px auto; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; text-align: justify; background-color: rgb(255, 255, 255);"> <span style="color: rgb(255, 0, 0);"> -x language filename </span></p><div>设定文件所使用的语言,使后缀名无效,对以后的多个有效.也就是根 <br/> 据约定C语言的后缀名称是.c的,而C++的后缀名是.C或者.cpp,如果 <br/> 你很个性,决定你的C代码文件的后缀名是.pig 哈哈,那你就要用这 <br/> 个参数,这个参数对他后面的文件名都起作用,除非到了下一个参数 <br/> 的使用。 <br/> 可以使用的参数吗有下面的这些 <br/>c’, objective-c’,c-header’, c++’,cpp-output’,

assembler’, andassembler-with-cpp’.

看到英文,应该可以理解的。

例子用法:

gcc -x c hello.pig

-x none filename

关掉上一个选项,也就是让gcc根据文件名后缀,自动识别文件类型


一、Linux程序gcc编译步骤:

Gcc编译过程主要的4个阶段:

l 预处理阶段,完成宏定义和include文件展开等工作;(.i)

l 根据编译参数进行不同程度的优化,编译成汇编代码(.s.S)

l 用汇编器把汇编代码进一步生成目标代码(.o)

l 用连接器把生成的目标代码和系统或用户提供的库连接起来,生成可执行文件

格式:

l gcc -E test.c//预处理阶段

l Gcc -S test.c//编译阶段

l Gcc -c test.c//汇编阶段

l Gcc -o test test.c//链接阶段

二、Linux程序gdb调试步骤:

Gdb的功能:

l 设置断点

l 监视程序变量的值

l 程序的单步执行

l 显示、修改变量的值

l 显示、修改寄存器

l 查看程序的堆栈情况

l 远程调试

Gdb调试过程:

1、程序经过预处理后,即进入编译阶段,进入编译阶段,首先声明编译:

2、格式:g++ -o test test.c -g

3、进入编译:gdb test

4、显示需要编译调试的源程序:l(list)//list filename

5、设置断点:b(break)行号

6、查看设置的断点:info b

7、运行调试程序:run

8、跳到下一个断点:c(continue)

9、单步运行的话使用:n(next)/s(step into)跳到函数体 //区别在与:next执行函数体,而step不执行函数体

10、调试过程中查看某个变量的变化:print i (每次都要手动设置)//display i(设置一次一直尾随,直到用“undisplay 变量标号” 停止)

11、退出当前的调试使用finish 跳出函数

12、清楚断点 clear 行号

13、Delete 断点信息序号// 删除所有断点或设置的要删除的断点

14、退出调试 q

15、b num if i==20 设置断点的触发条件

16、condition num i==50 改变断点的触发条件
——————其他————-

手把手教你调试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

复制代码
 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 " << v2
11 << " 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 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:77 std::cout << "Enter two numbers:" << std::endl;//断点命中(gdb) s
Enter two numbers:
8 int v1 = 0, v2 = 0;
(gdb) s
//单步执行9 std::cin >> v1 >> v2;
(gdb) n
5611 << " is " << v1 + v2 << std::endl;
(gdb) s
10 std::cout << "The sum of " << v1 << " and " << v2
(gdb) s
11 << " is " << v1 + v2 << std::endl;
(gdb) s
The
sum of 5 and 6 is 1114 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 = 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.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:
56
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
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
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
调试结果如下:<br>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:
Find the GDB manual and other documentation resources online at:
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, 源文件,可操作性极强,建议感兴趣的朋友亲自动手操作演练,希望对大家有所帮助。


文章目录
  1. 1. 1.总体选项
  2. 2. 2.目录选项
  3. 3. 3.调试选项
  4. 4. 4.链接方式选项:
  5. 5. 一、Linux程序gcc编译步骤:
  6. 6. 二、Linux程序gdb调试步骤: