gdb调试的基本使用
GDB调试
启动程序准备调试
GDB yourpram
或者
先输入GDB
然后输入 file yourpram
然后使用run或者r命令开始程序的执行,也可以使用 run parameter将参数传递给该程序
参数列表
|
命令 |
命令缩写 |
命令说明 |
|
list |
l |
显示多行源代码 |
|
break |
b |
设置断点,程序运行到断点的位置会停下来 |
|
info |
i |
描述程序的状态 |
|
run |
r |
开始运行程序 |
|
display |
disp |
跟踪查看某个变量,每次停下来都显示它的值 |
|
step |
s |
执行下一条语句,如果该语句为函数调用,则进入函数执行其中的第一条语句 |
|
next |
n |
执行下一条语句,如果该语句为函数调用,不会进入函数内部执行(即不会一步步地调试函数内部语句) |
|
|
p |
打印内部变量值 |
|
continue |
c |
继续程序的运行,直到遇到下一个断点 |
|
set var name=v |
设置变量的值 |
|
|
start |
st |
开始执行程序,在main函数的第一条语句前面停下来 |
|
file |
装入需要调试的程序 |
|
|
kill |
k |
终止正在调试的程序 |
|
watch |
监视变量值的变化 |
|
|
backtrace |
bt |
查看函数调用信息(堆栈) |
|
frame |
f |
查看栈帧 f n 切换到编号为n的栈 |
|
quit |
q |
退出GDB环境 |
//e.c
#include <stdio.h>
void debug(char *str)
{
printf("debug info :%s\n",str );
}
main(int argc,char *argv[]){
int i,j;
j=;
for(i=;i<;i++){
j+=;
printf("now a=%d\n", j);
}
}
gcc -g -o e e.c
调试gdb e
或者输入gdb
然后 file e
list 命令用法
list命令显示多行源代码,从上次的位置开始显示,默认情况下,一次显示10行,第一次使用时,从代码起始位置显示
gdb) list
#include <stdio.h>
void debug(char *str)
{
printf("debug info :%s\n",str );
}
main(int argc,char *argv[]){
int i,j;
j=;
for(i=;i<;i++){
j+=;
(gdb)
list n显示已第n行未中心的10行代码
(gdb) list
{
printf("debug info :%s\n",str );
}
main(int argc,char *argv[]){
int i,j;
j=;
for(i=;i<;i++){
j+=;
printf("now a=%d\n", j);
}
(gdb)
list functionname显示以functionname的函数为中心的10行代码
(gdb) list main
#include <stdio.h>
void debug(char *str)
{
printf("debug info :%s\n",str );
}
main(int argc,char *argv[]){
int i,j;
j=;
for(i=;i<;i++){
j+=;
(gdb)
list - 显示刚才打印过的源代码之前的代码
(gdb) list
}
main(int argc,char *argv[]){
int i,j;
j=;
for(i=;i<;i++){
j+=;
printf("now a=%d\n", j);
}
}(gdb) list -
#include <stdio.h>
void debug(char *str)
{
printf("debug info :%s\n",str );
(gdb)
断点命令break
break location:在location位置设置断点,该位置可以为某一行,某函数名或者其它结构的地址
GDB会在执行该位置的代码之前停下来
gdb) list
#include <stdio.h>
void debug(char *str)
{
printf("debug info :%s\n",str );
}
main(int argc,char *argv[]){
int i,j;
j=;
for(i=;i<;i++){
j+=;
(gdb)
printf("now a=%d\n", j);
}
}(gdb) break
Breakpoint at 0x40050a: file e.c, line .
(gdb) r
Starting program: /mnt/hgfs/www/c/gcc/e Breakpoint , main (argc=, argv=0x7fffffffe548) at e.c:
j+=;
(gdb) c
Continuing.
now a= Breakpoint , main (argc=, argv=0x7fffffffe548) at e.c:
j+=;
(gdb) c
Continuing.
now a= Breakpoint , main (argc=, argv=0x7fffffffe548) at e.c:
j+=;
(gdb)
使用delete breakpoints 断点号 删除断点
这里的断点号表示的是第几个断点,刚才执行break 10返回 reakpoint 1 at 0x40050a: file e.c, line 10.
中的1表示该断点的标号,因此使用 delete breakpoints 1表示删除第10行所定义的断点
clear n表示清除第n行的断点,因此clear 10等同于delete breakpoints 1
disable/enable n表示使得编号为n的断点暂时失效或有效
可使用info查看断点相关的信息
info breakpoints
gdb) info breakpoints
No breakpoints or watchpoints.
(gdb) break
Breakpoint at 0x40050a: file e.c, line .
(gdb) break
Breakpoint at 0x400501: file e.c, line .
(gdb) info breakpoints
Num Type Disp Enb Address What
breakpoint keep y 0x000000000040050a in main at e.c:
breakpoint keep y 0x0000000000400501 in main at e.c:
display命令
查看参数的值
(gdb) break
Breakpoint at 0x40050a: file e.c, line .
(gdb) r
Starting program: /mnt/hgfs/www/c/gcc/e Breakpoint , main (argc=, argv=0x7fffffffe548) at e.c:
j+=;
(gdb) display j
: j =
(gdb) c
Continuing.
now a= Breakpoint , main (argc=, argv=0x7fffffffe548) at e.c:
j+=;
: j =
(gdb) display
: j =
(gdb) display i
: i =
(gdb) display j
: j =
(gdb) display j*
: j* =
(gdb) info display
Auto-display expressions now in effect:
Num Enb Expression
: y j*
: y j
: y i
: y j
也可以使用disable,enable,delete,info命令修改及查看其状态,用法与对断点的一样
step及next命令
step可使得程序逐条执行,即执行完一条语句然后在吓一跳语句前停下来,等待用户的命令
一般使用step命令是,可使用display或者watch命令查看变量的变化,从而判断程序行为是否符合要求
当下一条指令为函数时,s进入函数内部,在其第一条语句前停下来
step n,next n 表示连续但不执行n条指令,如果期间遇到断点,则停下来
(gdb) list
#include <stdio.h>
void debug(char *str)
{
printf("debug info :%s\n",str );
} main(int argc,char *argv[]){
int i,j;
j=;
for(i=;i<;i++){
(gdb)
j+=;
printf("now j=%d\n", j);
debug("x=======x");
}
}(gdb)
Line number out of range; e.c has lines.
(gdb) break
Breakpoint at 0x40050a: file e.c, line .
(gdb) r
Starting program: /mnt/hgfs/www/c/gcc/e1 Breakpoint , main (argc=, argv=0x7fffffffe538) at e.c:
j+=;
(gdb) s
printf("now j=%d\n", j);
(gdb) s
__printf (format=0x400648 "now j=%d\n") at printf.c:
{
(gdb) bt
# __printf (format=0x400648 "now j=%d\n") at printf.c:
# 0x0000000000400525 in main (argc=, argv=0x7fffffffe538) at e.c:
(gdb) n
va_start (arg, format);
(gdb) n
done = vfprintf (stdout, format, arg);
(gdb) n
now j=
}
(gdb) bt
# __printf (format=<value optimized out>) at printf.c:
# 0x0000000000400525 in main (argc=, argv=0x7fffffffe538) at e.c:
(gdb) n
main (argc=, argv=0x7fffffffe538) at e.c:
debug("x=======x");
(gdb) n
debug info :x=======x
for(i=;i<;i++){
(gdb) s Breakpoint , main (argc=, argv=0x7fffffffe538) at e.c:
j+=;
(gdb) s
printf("now j=%d\n", j);
(gdb) n
now j=
debug("x=======x");
(gdb) n
debug info :x=======x
for(i=;i<;i++){
(gdb)
watch
watch可设置观察点(watchpoint)。使用观察点可以使得当某表达式的值发生变化时,程序暂停执行。
执行该命令前,必须保证程序已经运行
(gdb) list
#include <stdio.h>
void debug(char *str)
{
printf("debug info :%s\n",str );
} main(int argc,char *argv[]){
int i,j;
j=;
for(i=;i<;i++){
(gdb)
j+=;
printf("now j=%d\n", j);
debug("x=======x");
}
}(gdb)
Line number out of range; e.c has lines.
(gdb) b main
Breakpoint at 0x4004fa: file e.c, line .
(gdb) r
Starting program: /mnt/hgfs/www/c/gcc/e1 Breakpoint , main (argc=, argv=0x7fffffffe538) at e.c:
j=;
(gdb) watch j
Hardware watchpoint : j
(gdb) c
Continuing.
Hardware watchpoint : j Old value =
New value =
main (argc=, argv=0x7fffffffe538) at e.c:
printf("now j=%d\n", j);
(gdb) c
Continuing.
now j=
debug info :x=======x
Hardware watchpoint : j Old value =
New value =
main (argc=, argv=0x7fffffffe538) at e.c:
printf("now j=%d\n", j);
print命令
(gdb) list
#include <stdio.h>
void debug(char *str)
{
printf("debug info :%s\n",str );
} main(int argc,char *argv[]){
int i,j;
j=;
for(i=;i<;i++){
(gdb)
j+=;
printf("now j=%d\n", j);
debug("x=======x");
}
}(gdb)
Line number out of range; e.c has lines.
(gdb) break
Breakpoint at 0x40050e: file e.c, line .
(gdb) r
Starting program: /mnt/hgfs/www/c/gcc/e1 Breakpoint , main (argc=, argv=0x7fffffffe538) at e.c:
printf("now j=%d\n", j);
(gdb) p j
$ =
(gdb) c
Continuing.
now j=
debug info :x=======x Breakpoint , main (argc=, argv=0x7fffffffe538) at e.c:
printf("now j=%d\n", j);
(gdb) p i,j
$ =
(gdb) p j
$ =
(gdb)
set var name=value
set args 可指定运行时参数(当main函数需要参数时 如:set args 10 20 30 40 50)
show args 命令可以查看设置好的运行参数
在程序运行中动态改变变量的值
(gdb) list
#include <stdio.h>
void debug(char *str)
{
printf("debug info :%s\n",str );
} main(int argc,char *argv[]){
int i,j;
j=;
for(i=;i<;i++){
(gdb)
j+=;
printf("now j=%d\n", j);
debug("x=======x");
}
}(gdb)
Line number out of range; e.c has lines.
(gdb) break main
Breakpoint at 0x4004fa: file e.c, line .
(gdb) r
Starting program: /mnt/hgfs/www/c/gcc/e1 Breakpoint , main (argc=, argv=0x7fffffffe538) at e.c:
j=;
(gdb) watch i
Hardware watchpoint : i
(gdb) watch j
Hardware watchpoint : j
(gdb) c
Continuing.
Hardware watchpoint : j Old value =
New value =
main (argc=, argv=0x7fffffffe538) at e.c:
printf("now j=%d\n", j);
(gdb) c
Continuing.
now j=
debug info :x=======x
Hardware watchpoint : i Old value =
New value =
0x0000000000400533 in main (argc=, argv=0x7fffffffe538) at e.c:
for(i=;i<;i++){
(gdb) c
Continuing.
Hardware watchpoint : j Old value =
New value =
main (argc=, argv=0x7fffffffe538) at e.c:
printf("now j=%d\n", j);
(gdb) c
Continuing.
now j=
debug info :x=======x
Hardware watchpoint : i Old value =
New value =
0x0000000000400533 in main (argc=, argv=0x7fffffffe538) at e.c:
for(i=;i<;i++){
(gdb) c
Continuing.
Hardware watchpoint : j Old value =
New value =
main (argc=, argv=0x7fffffffe538) at e.c:
printf("now j=%d\n", j);
(gdb) c
Continuing.
now j=
debug info :x=======x
Hardware watchpoint : i Old value =
New value =
0x0000000000400533 in main (argc=, argv=0x7fffffffe538) at e.c:
for(i=;i<;i++){
(gdb) c
Continuing.
Hardware watchpoint : j Old value =
New value =
main (argc=, argv=0x7fffffffe538) at e.c:
printf("now j=%d\n", j);
(gdb) c
Continuing.
now j=
debug info :x=======x
Hardware watchpoint : i Old value =
New value =
0x0000000000400533 in main (argc=, argv=0x7fffffffe538) at e.c:
for(i=;i<;i++){
(gdb) set var i=
(gdb) c
Continuing.
Hardware watchpoint : j Old value =
New value =
main (argc=, argv=0x7fffffffe538) at e.c:
printf("now j=%d\n", j);
(gdb) c
Continuing.
now j=
debug info :x=======x
Hardware watchpoint : i Old value =
New value =
0x0000000000400533 in main (argc=, argv=0x7fffffffe538) at e.c:
for(i=;i<;i++){
(gdb) c
Continuing.
Hardware watchpoint : j Old value =
New value =
main (argc=, argv=0x7fffffffe538) at e.c:
printf("now j=%d\n", j);
(gdb) c
Continuing.
now j=
debug info :x=======x
Hardware watchpoint : i Old value =
New value =
0x0000000000400533 in main (argc=, argv=0x7fffffffe538) at e.c:
for(i=;i<;i++){
(gdb) c
Continuing. Watchpoint deleted because the program has left the block in
which its expression is valid. Watchpoint deleted because the program has left the block in
which its expression is valid.
__libc_start_main (main=0x4004eb <main>, argc=, ubp_av=0x7fffffffe538, init=<value optimized out>, fini=<value optimized out>, rtld_fini=<value optimized out>,
stack_end=0x7fffffffe528) at libc-start.c:
exit (result);
(gdb) c
Continuing. Program exited with code .
函数调用相关的
backtrace
可使用frame 查看堆栈中某一帧的信息
(gdb) list
#include <stdio.h>
void debug(char *str)
{
printf("debug info :%s\n",str );
} main(int argc,char *argv[]){
int i,j;
j=;
for(i=;i<;i++){
(gdb)
j+=;
printf("now j=%d\n", j);
debug("x=======x");
}
}(gdb)
Line number out of range; e.c has lines.
(gdb) b
Breakpoint at 0x400525: file e.c, line .
(gdb) r
Starting program: /mnt/hgfs/www/c/gcc/e1
now j= Breakpoint , main (argc=, argv=0x7fffffffe538) at e.c:
debug("x=======x");
(gdb) s
debug (str=0x400652 "x=======x") at e.c:
printf("debug info :%s\n",str );
(gdb) bt
# debug (str=0x400652 "x=======x") at e.c:
# 0x000000000040052f in main (argc=, argv=0x7fffffffe538) at e.c:
(gdb) s
__printf (format=0x400638 "debug info :%s\n") at printf.c:
{
(gdb) bt
# __printf (format=0x400638 "debug info :%s\n") at printf.c:
# 0x00000000004004e9 in debug (str=0x400652 "x=======x") at e.c:
# 0x000000000040052f in main (argc=, argv=0x7fffffffe538) at e.c:
(gdb) s
va_start (arg, format);
(gdb) bt
# __printf (format=0x400638 "debug info :%s\n") at printf.c:
# 0x00000000004004e9 in debug (str=0x400652 "x=======x") at e.c:
# 0x000000000040052f in main (argc=, argv=0x7fffffffe538) at e.c:
(gdb) s
done = vfprintf (stdout, format, arg);
(gdb) s
_IO_vfprintf_internal (s=0x333a58f040, format=0x400638 "debug info :%s\n", ap=0x7fffffffe330) at vfprintf.c:
int save_errno = errno;
(gdb) bt
# _IO_vfprintf_internal (s=0x333a58f040, format=0x400638 "debug info :%s\n", ap=0x7fffffffe330) at vfprintf.c:
# 0x000000333a24effa in __printf (format=<value optimized out>) at printf.c:
# 0x00000000004004e9 in debug (str=0x400652 "x=======x") at e.c:
# 0x000000000040052f in main (argc=, argv=0x7fffffffe538) at e.c:
(gdb) c
Continuing.
debug info :x=======x
now j= Breakpoint , main (argc=, argv=0x7fffffffe538) at e.c:
debug("x=======x");
(gdb) bt
# main (argc=, argv=0x7fffffffe538) at e.c:
GDB段错误调试
所谓段错误就是对内存的非法访问
采用GDB调试段错误有2种方法
1.在GDB中运行目标程序,当发生段错误时,GDB中运行的程序会自动停下来
2.直接运行目标程序,使其在发生段错误时产生内存转储(core dump)文件,GDB对该文件进行调试
abort.c
#include <stdio.h>
#include <stdlib.h> void recurse(void)
{
static int i;
if( ++i == )
abort();
else
recurse();
}
int main(int argc,char ** argv){
recurse();
}
gcc -g -o abort abort.c
使用gdb调试
Line number out of range; abort.c has lines.
(gdb) r
Starting program: /mnt/hgfs/www/c/gcc/abort Program received signal SIGABRT, Aborted.
0x000000333a232495 in raise (sig=) at ../nptl/sysdeps/unix/sysv/linux/raise.c:
return INLINE_SYSCALL (tgkill, , pid, selftid, sig);
(gdb) bt
# 0x000000333a232495 in raise (sig=) at ../nptl/sysdeps/unix/sysv/linux/raise.c:
# 0x000000333a233c75 in abort () at abort.c:
# 0x00000000004004e7 in recurse () at abort.c:
# 0x00000000004004ec in recurse () at abort.c:
# 0x00000000004004ec in recurse () at abort.c:
# 0x0000000000400502 in main (argc=, argv=0x7fffffffe528) at abort.c:
显示在recurse函数调用了3次后调用了abort函数,产生段错误
使用内存转储文件
ulimit -a
[root@centos1 gcc]# ulimit -a
core file size (blocks, -c)
data seg size (kbytes, -d) unlimited
scheduling priority (-e)
file size (blocks, -f) unlimited
pending signals (-i)
max locked memory (kbytes, -l)
max memory size (kbytes, -m) unlimited
open files (-n)
pipe size ( bytes, -p)
POSIX message queues (bytes, -q)
real-time priority (-r)
stack size (kbytes, -s)
cpu time (seconds, -t) unlimited
max user processes (-u)
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
core file size 此时是0
ulimit -c unlimited 设置为不受限制
执行 ./abort 产生内存转储文件
ls 可看到一个名为core且以进程号为后缀的文件
core.6289
gdb abort core.6289
bt
方法同上一个gdb调试
gdb调试的基本使用的更多相关文章
- GDB调试命令小结
1.启动调试 前置条件:编译生成执行码时带上 -g,如果使用Makefile,通过给CFLAGS指定-g选项,否则调试时没有符号信息.gdb program //最常用的用gdb启动程序,开始调试的方 ...
- GDB调试汇编堆栈过程分析
GDB调试汇编堆栈过程分析 分析过程 这是我的C源文件:click here 使用gcc - g example.c -o example -m32指令在64位的机器上产生32位汇编,然后使用gdb ...
- gdb调试器的使用
想要使用gdb调试程序的话,首先需要gcc -g main.c -o test 然后运行gdb test对程序进行调试 l (小写的l,是list的首字母),用以列出程序 回车 是运行上一个命令 ...
- 20145212——GDB调试汇编堆栈过程分析
GDB调试汇编堆栈过程分析 测试代码 #include <stdio.h> short val = 1; int vv = 2; int g(int xxx) { return xxx + ...
- gdb调试PHP扩展错误
有时候,使用PHP的第三方扩展之后,可能会发生一些错误,这个时候,可能就需要更底层的方式追踪调试程序发生错误的地方和原因,熟悉linux下C编程的肯定不陌生gdb 首先,使用ulimit -c命令,查 ...
- gdb调试汇编堆栈过程的学习
gdb调试汇编堆栈过程的学习 以下为C源文件 使用gcc - g code.c -o code -m32指令在64位的机器上产生32位汇编,然后使用gdb example指令进入gdb调试器: 进入之 ...
- gdb调试
·代码(实验楼中的代码,改了部分数值)命名为test.c int g(int x) { return x + 7; } int f(int x) { return g(x); } int main(v ...
- 20145223《信息安全系统设计基础》 GDB调试汇编堆栈过程分析
20145223<信息安全系统设计基础> GDB调试汇编堆栈过程分析 分析的c语言源码 生成汇编代码--命令:gcc -g example.c -o example -m32 进入gdb调 ...
- GDB调试汇编堆栈
GDB调试汇编堆栈 分析过程 C语言源代码 int g(int x) { return x+6; } int f(int x) { return g(x+1); } int main(void) { ...
- 赵文豪 GDB调试汇编堆栈过程分析
GDB调试汇编堆栈过程分析 使用gcc - g example.c -o example -m32指令在64位的机器上产生32位汇编,然后使用gdb example指令进入gdb调试器: 使用gdb调 ...
随机推荐
- Python模块 - paramiko
paramiko模块提供了ssh及sft进行远程登录服务器执行命令和上传下载文件的功能.这是一个第三方的软件包,使用之前需要安装. 1 基于用户名和密码的 sshclient 方式登录 # 建立一个s ...
- Vue框架之双向绑定事件
Vue框架之双向绑定事件 首先介绍下Vue框架的语法 vue通过 {{temp}} 来渲染变量 {{count+100}} # 求和 v-text # 为标签插入text文本 v-html # 为标签 ...
- pythonllk
字符编码 数据类型 函数 装饰器 内置函数 迭代器 生成器 异常 反射 模块 类 对象 类的进阶 socket 进程线程 httphtmlcssJavaScriptjquery MysqlMysq ...
- 2018 6年iOS开发常用的三方库
开发一般APP必备三方库,省力秘籍!!!本篇文章会经常更新最新常用的三方. 1.网络请求库 AFNetworking https://github.com/AFNetworking/AFNetwork ...
- ArUco----一个微型现实增强库的介绍及视觉应用(一)
ArUco----一个微型现实增强库的介绍及视觉应用(一) 一.ArUco简介 ArUco是一个开源的微型的现实增强库,目前好像已经集成在OpenCV3.0以上的版本内了,它除了用于现实增强,还很用于 ...
- 在VS2017中安装OpenGL
由于VS2017支持直接下载有关openGL的库文件,因此给我们带来了很多方便之处,不需要单独下载了. 1.打开VS2017,并新建一个C++控制台项目 2.然后点击 项目-管理Nuget程序包, 点 ...
- JS面向对象使用面向对象进行开发
面向对象基础一之初体验使用面向对象进行开发 对 JS 中的面向对象的基础进行讲述, 初体验使用面向对象进行开发 主要内容是 面向对象的概念及特性 用面向对象的方式解决简单的标签创建实例 一些基础的 ...
- java Thread 接口学习
对于程序员来说 Thread应该都不会陌生,具体的接口调用不是本篇的重点.Thread的基本概念及接口的使用:java多线程 下面将更多的从底层实现角度讲一下Thread. Thread的声明如下: ...
- win10安装Ubuntu14.04双系统
1 制作镜像 UltralISO刻录镜像到U盘,下载地址:http://pan.baidu.com/s/1o7JpthS 2压缩空间给Ubuntu安装 使用windows自带的压缩(磁盘管理) 3安装 ...
- 1.UTF8字符集csv文件在oracle下乱码问题处理
1.问题描述 在excel中生成了一个UTF-8编码格式的csv文件准备导入数据库,在notpad++下打开显示正常,编码集为UTF-8,通过pl/sql dev导入oracle是出现乱码,此时初步推 ...