linux下gcc.gdb整理

gcc

常用选项

-c 只编译不链接,生成目标文件".o"
-S 只编译不汇编,生成汇编代码
-E 只进行预编译,不做其他处理
-g 在可执行程序中包含标准调试信息
-o file 将file文件指定为输出文件
-v 打印出编译器内部编译各过程的命令行信息和编译器的版本
-I dir 在头文件的搜索路径列表中添加dir目录


gcc库选项列表

-static 进行静态编译,即链接静态库,禁止使用动态库
-shared
1.可以生成动态库文件
2.进行动态编译,尽可能地链接动态库,只有当没有动态库时才会链接同名的静态库(默认选项,即可省略)

-L dir 在库文件的搜索路径列表中添加dir目录
-lname 链接称为libname.a(静态库)或者libname.so(动态库)的库文件。若两个库都存在则根据编译方式(-static还是-shared)而进行链接
-fPIC(或-fpic)生成使用相对地址的位置无关的目标代码。然后通常使用gcc的-static选项从该PIC目标文件生成动态库文件

链接到静态库会使用户的程序臃肿,并且难以升级,但是可能会比较容易部署。而链接到动态库会使用户的程序轻便,并且易于升级,但是会难以部署


gcc警告和出错选项选项列表
-ansi 支持符合ANSI标准的C程序
-pedantic 允许发出ANSI C标准所列的全部警告信息
-pedantic-error 允许发出ANSI C标准所列的全部错误信息
-w 关闭所有告警
-Wall 允许发出gcc提供的所有有用的报警信息
-werror 把所有的告警信息转化为错误信息,并在告警发生时终止编译过程

#include<stdio.h>
void main()
{
    long long tmp = 1;
    printf("bad code\n");
    return 0;
}
gcc –ansi warning.c –o warning
warning.c: 在函数“main”中:
warning.c:7 警告:在无返回值的函数中,“return”带返回值
warning.c:4 警告:“main”的返回类型不是“int”
该选项并没有发现“long long”

gcc –pedantic warning.c –o warning
warning.c: 在函数“main”中:
warning.c:5 警告:ISO C90不支持“long long”
warning.c:7 警告:在无返回值的函数中,“return”带返回值
warning.c:4 警告:“main”的返回类型不是“int”
使用该选项查出了“long long”

gcc –Wall warning.c –o warning
warning.c:4 警告:“main”的返回类型不是“int”
warning.c: 在函数“main”中:
warning.c:7 警告:在无返回值的函数中,“return”带返回值
warning.c:5 警告:未使用的变量“tmp”
使用该选项查出了未使用的变量tmp,但它并没有找出无效数据类型

gcc还可以利用选项对单独的常见错误分别指定警告


优化选项 -On
n 是一个代表优化级别的整数 n 的取值范围及其对应的优化效果可能并不完全相同,比较典型的范围是从0变化到2或3;

"-O" 主要进行线程跳转(Thread Jump)和延迟退栈(Deferred Stack Pops)两种优化
"-O2" 除了完成所有"-O1"级别的优化之外,同时还要进行一些额外的调整工作,如处理器指令调度等。
"-O3"则还包括循环展开和其他一些与处理器特性相关的优化工作。

弊端:
虽然优化选项可以加速代码的运行速度,但对于调试而言将是一个很大的挑战。
因为代码在经过优化之后,原先在源程序中声明和使用的变量很可能不再使用,控制流也可能会突然跳转到意外的地方,循环语句也有可能因为循环展开而变得到处都有,所有这些对调试来讲都将是一场噩梦。建议在调试的时候最好不使用任何优化选项,只有当程序在最终发行的时候才考虑对其进行优化。


gcc体系结构相关选项列表
-mcpu=type 针对不同的CPU使用相应的CPU指令。可选择的type有i386、i486、pentium及i686
-mieee-fp 使用IEEE标准进行浮点数的比较
-mno-ieee-fp 不使用IEEE标准进行浮点数的比较
-msoft-float 输出包含浮点库调用的目标代码
-mshort 把int类型作为16位处理,相当于short int
-mrtd 强行将函数参数个数固定的函数用ret NUM返回,节省调用函数的一条指令

 

 

 

 

gdb 调试器

 

 

 

 

 

#include <stdio.h>
int sum(int);
int main(){
    printf("the sum of 1-50 is %d\n",sum(50));
}

int sum(int n){
    int i,sum;
    for(i = 1,sum = 0; i <= n; ++i){
        sum += i;
    }
    return sum;
}


gcc -g gdbt.c -o gdbt

gdb gdbt
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-60.el6_4.1)
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 "i686-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /root/gdbt...done.
(gdb) 


(1)查看文件。
键入“l”(list)查看所载入的文件

 

(gdb) l
1	#include <stdio.h>
2	
3	int sum(int);
4	
5	int main(){
6	    printf("the sum of 1-50 is %d\n",sum(50));
7	}
8	
9	int sum(int n){
10	    int i,sum;
(gdb) 
11	    for(i = 1,sum = 0; i <= n; ++i){
12	        sum += i;
13	    }
14	    return sum;
15	}
(gdb) 
Line number 16 out of range; gdbt.c has 15 lines.

gdb 列出的源代码中明确地给出了对应的行号,这样就可以大大地方便代码的定位。


(2)设置断点。
在 gdb 中设置断点非常简单,只需在“b”后加入对应的行号即可(这是最常用的方式,另外还有其他方式设置断点)
(gdb) b 12
Breakpoint 1 at 0x8048402: file gdbt.c, line 12.

利用行号设置断点是指代码运行到对应行之前将其停止,如上例中,代码运行到第12 行之前暂停(并没有运行第12 行)


(3)查看断点情况。
在设置完断点之后,用户可以键入“info b”来查看设置断点情况,在gdb 中可以设置多个断点。
(gdb) info b
Num     Type           Disp Enb Address    What
1       breakpoint     keep y   0x08048402 in sum at gdbt.c:12

用户在断点键入“backrace”(只输入“bt”即可)可以查到调用函数(堆栈)的情况,这个功能在程序调试之中使用非常广泛,经常用于排除错误或者监视调用堆栈的情况。
(gdb) bt
#0  sum (n=50) at gdbt.c:12
#1  0x080483d9 in main () at gdbt.c:6


(4)运行代码。
接下来就可运行代码了,gdb默认从首行开始运行代码,键入“r”(run)即可(若想从程序中指定行开始运行,可在r后面加上行号)。
(gdb) r
Starting program: /root/gdbt 
Breakpoint 1, sum (n=50) at gdbt.c:12
12        sum += i;


(5)查看变量值。
在程序停止运行之后,程序员所要做的工作是查看断点处的相关变量值。在gdb中键入“p”+变量值即可
(gdb) p sum
$1 = 0
(gdb) p i
$2 = 1
(gdb)

gdb 在显示变量值时都会在对应值之前加上“$N”标记,它是当前变量值的引用标记,所以以后若想再次引用此变量就可以直接写作“$N”,而无需写冗长的变量名。
(gdb) p $2
$3 = 1


(6)单步运行。
单步运行可以使用命令“n”(next)或“s”(step),它们之间的区别在于:若有函数调用的时候,“s”会进入该函数而“n”不会进入该函数。因此,“s”就类似于Uisual等工具中的“step in”,“n”类似与Uisual等工具中的“step over”
(gdb) n
11    for(i = 1,sum = 0; i <= n; ++i){
(gdb) s
Breakpoint 1, sum (n=50) at gdbt.c:12
12        sum += i;


(7)删除断点 
delete Num 这个Num是info b的Num 
(gdb) delete 1(d 1同效)
(gdb) info b
Num     Type           Disp Enb Address    What
2       breakpoint     keep y   0x080483cd in main at gdbt.c:6


(8)恢复程序运行
在查看完所需变量及堆栈情况后,就可以使用命令“c”(continue)恢复程序的正常运行了。这时,它会把剩余还未执行的程序执行完,并显示剩余程序中的执行结果
(gdb) c
Continuing.
the sum of 1-50 is 1275

在gdb中,程序的运行状态有“运行”、“暂停”和“停止”3种,其中“暂停”状态为程序遇到了断点或观察点之类的,程序暂时停止运行,而此时函数的地址、函数参数、函数内的局部变量都会被压入“栈”(Stack)中。故在这种状态下可以查看函数的变量值等各种属性。但在函数处于“停止”状态之后,“栈”就会自动撤消,它也就无法查看各种信息了。

(9)现实跟踪代码
focus next 显示代码跟踪,重复此命令可以在代码框和输入框之间切换焦点

(10)格式化显示打印信息
set print pretty on

(11)调试父进程或者子进程
set follow-fork-mode [parent|child]
parent: fork之后继续调试父进程,子进程不受影响
child: fork之后调试子进程,父进程不受影响


gdb基本命令
gdb 的命令可以通过查看help进行查找,由于gdb 的命令很多,因此gdb 的help将其分成了很多种类(class),用户可以通过进一步查看相关class找到相应命令

(gdb) help(简写h)
List of classes of commands:

aliases -- Aliases of other commands
breakpoints -- Making program stop at certain points
data -- Examining data
files -- Specifying and examining files
internals -- Maintenance commands
obscure -- Obscure features
running -- Running the program
stack -- Examining the stack
status -- Status inquiries
support -- Support facilities
tracepoints -- Tracing of program execution without stopping the program
user-defined -- User-defined commands

Type "help" followed by a class name for a list of commands in that class.
Type "help all" for the list of all commands.
Type "help" followed by command name for full documentation.
Type "apropos word" to search for commands related to "word".
Command name abbreviations are allowed if unambiguous.


(gdb) h data
Examining data.

List of commands:

append -- Append target code/data to a local file
append binary -- Append target code/data to a raw binary file
append binary memory -- Append contents of memory to a raw binary file
append binary value -- Append the value of an expression to a raw binary file
append memory -- Append contents of memory to a raw binary file
append value -- Append the value of an expression to a raw binary file
call -- Call a function in the program
disassemble -- Disassemble a specified section of memory
display -- Print value of expression EXP each time the program stops
...

(gdb) h append
Append target code/data to a local file.

List of append subcommands:

append binary -- Append target code/data to a raw binary file
append memory -- Append contents of memory to a raw binary file
append value -- Append the value of an expression to a raw binary file

Type "help append" followed by append subcommand name for full documentation.
Type "apropos word" to search for commands related to "word".
Command name abbreviations are allowed if unambiguous.

(gdb) h append binary 
Append target code/data to a raw binary file.

List of append binary subcommands:

append binary memory -- Append contents of memory to a raw binary file
append binary value -- Append the value of an expression to a raw binary file

Type "help append binary" followed by append binary subcommand name for full documentation.
Type "apropos word" to search for commands related to "word".
Command name abbreviations are allowed if unambiguous.

(gdb) h append binary value 
Append the value of an expression to a raw binary file.
Arguments are FILE EXPRESSION.  Writes the value of EXPRESSION
to the specified FILE in raw target ordered bytes.

用户已知命令名,直接键入“help [command]”也可,tab可命令补全


gdb 中的命令主要分为以下几类:工作环境相关命令、设置断点与恢复命令、源代码查看命令、查看运行数据相关命令及修改运行参数命令

1.工作环境相关命令
gdb 中不仅可以调试所运行的程序,而且还可以对程序相关的工作环境进行相应的设定,甚至还可以使用shell中的命令进行相关的操作,其功能极其强大

set args    运行时的参数指定运行时参数,如set args 2
show args    查看设置好的运行参数
Path dir    设定程序的运行路径
show paths    查看程序的运行路径
set environment var [=value]    设置环境变量
show environment [var]    查看环境变量
cd dir    进入dir目录,相当于shell中的cd命令
Pwd    显示当前工作目录
shell command    运行shell的command命令


2.设置断点与恢复命令
gdb    中设置断点与恢复的常见命令

Info b    查看所设断点
break [文件名:]行号或函数名 <条件表达式>    设置断点
tbreak [文件名:]行号或函数名 <条件表达式>    设置临时断点,到达后被自动删除
delete    [断点号]     删除指定断点,其断点号为“info b”中的第一栏。若缺省断点号则删除所有断点
disable    [断点号]     停止指定断点,使用“info b”仍能查看此断点。同delete一样,若缺省断点号则停止所有断点
enable [断点号]    激活指定断点,即激活被disable停止的断点
condition [断点号] <条件表达式>    修改对应断点的条件
ignore [断点号]<num>    在程序执行中,忽略对应断点num次
Step    单步恢复程序运行,且进入函数调用
Next    单步恢复程序运行,但不进入函数调用
Finish    运行程序,直到当前函数完成返回
C    继续执行函数,直到函数结束或遇到新的断点


gdb 中设置断点有多种方式:其一是按行设置断点;另外还可以设置函数断点和条件断点。

1) 函数断点。
gdb 中按函数设置断点只需把函数名列在命令“b”之后
(gdb) b sum
Breakpoint 4 at 0x80483f2: file gdbt.c, line 11.
(gdb) info b
Num     Type           Disp Enb Address    What
4       breakpoint     keep y   0x080483f2 in sum at gdbt.c:11


2)条件断点。
gdb 中设置条件断点的格式为:b 行数或函数名if 表达式
(gdb) b 12 if i==2
Breakpoint 5 at 0x8048402: file gdbt.c, line 12.
(gdb) info b
Num     Type           Disp Enb Address    What
4       breakpoint     keep y   0x080483f2 in sum at gdbt.c:11
5       breakpoint     keep y   0x08048402 in sum at gdbt.c:12
stop only if i==2


3.gdb 中源码查看相关命令

在 gdb 中可以查看源码以方便其他操作

list <行号>|<函数名>    查看指定位置代码
file [文件名]    加载指定文件
forward-search    正则表达式源代码的前向搜索
reverse-search    正则表达式源代码的后向搜索
dir DIR    将路径DIR添加到源文件搜索的路径的开头
show directories    显示源文件的当前搜索路径
info line    显示加载到gdb内存中的代码


4.gdb 中查看运行数据相关命令
gdb 中查看运行数据是指当程序处于“运行”或“暂停”状态时,可以查看的变量及表达式的信息

print    表达式|变量查看程序运行时对应表达式和变量的值
x <n/f/u>    查看内存变量内容。其中n为整数表示显示内存的长度,f表示显示的格式,u表示从当前地址往后请求显示的字节数
display    表达式设定在单步运行或其他情况中,自动显示的对应表达式的内容
backtrace    查看当前栈的情况,即可以查到哪些被调用的函数尚未返回


5.gdb 中修改运行参数相关命令
gdb 还可以修改运行时的参数,并使该变量按照用户当前输入的值继续运行。它的设置方法为:在单步执行的过程中,键入命令“set 变量=设定值”


gdb使用时的注意点:
1.在gcc编译选项中一定要加入“-g”。
2.只有在代码处于“运行”或“暂停”状态时才能查看变量值。
3.设置断点后程序在指定行之前停止。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值