linux gdb调试 案例说明

目录

1. 源文件

2. 编译

3.GDB 调试 ​

 4. 常用调试指令总结


1. 源文件

test.cpp

#include <iostream>

int main(int argc,char**argv)
{
    int itest = 100;
    const char *str = "this is a test";
    
    std::cout << "itest is " << itest << " str is " << str << std::endl;
    std::cout << "param is " << std::endl;
    for ( int i = 0; i < argc;i++)
    {
        std::cout << argv[i] << std::endl;
    }    
    std::cout << "hello world \n";
    return 0;
}

Makefile

EXE:=section1
EXECUTABLE:= $(EXE)

LIBDIR:=
LIBS:=
INCLUDES:=.
SRCDIR:=

CC:=g++
#CFLAGS:= -g -Wall -o0
CPPFLAGS:= -g
CPPFLAGS+= $(addprefix -I,$(INCLUDES))
CPPFLAGS+= -I.
CPPFLAGS+= -MMD

RM-F:= rm -f

SRCS:= $(wildcard *.cpp) $(wildcard $(addsuffix /*.cpp,$(SRCDIR)))
OBJS:= $(patsubst %.cpp,%.o,$(SRCS))
DEPS:= $(patsubst %.o,%.d,$(OBJS))
MISSING_DEPS:= $(filter-out $(wildcard $(DEPS)),$(DEPS))

.PHONY : all deps objs clean
all:$(EXECUTABLE)
deps:$(DEPS)

objs:$(OBJS)
clean:
    @$(RM-F) *.o
    @$(RM-F) *.d
    @$(RM-F) $(EXE)

ifneq ($(MISSING_DEPS),)
$(MISSING_DEPS):
    @$(RM-F) $(patsubst %.d,%.o,$@)
endif
-include $(DEPS)
$(EXECUTABLE) : $(OBJS)
    $(CC) -o $(EXECUTABLE) $(OBJS) $(addprefix -L,$(LIBDIR)) $(addprefix -l,$(LIBS))
 

2. 编译

注意 在 makefile中一定加入 -g 编译标志符,用于生成调试信息。

3.GDB 调试 

 4. 常用调试指令总结

quit:

退出 gdb

list: 缩写l 

列出周围的源程序 或列出函数源程序

命令控制程序的运行 

run(缩写r)

运行程序

break(缩写b)

打断点

next(缩写n)

下一步

print(缩写p)

显示具体内容

  • x 按十六进制格式显示变量。
  • d 按十进制格式显示变量。
  • u 按十六进制格式显示无符号整型。
  • o 按八进制格式显示变量。
  • t 按二进制格式显示变量。
  • a 按十六进制格式显示变量。
  • c 按字符格式显示变量。
  • f 按浮点数格式显示变量。

set args

可指定运行时参数,如:set args 10 20 ;

show args

命令可以查看设置好的运行参数。

path <dir>

可设定程序的运行路径;

set environment varname [=value]

用于设置环境变量,如set env USER=agm;

show environment [varname]

则用于查看环境变量。

 

gdb中也可以使用重定向控制程序输出,如

run > tmpfile;

step <count>
单步跟踪,如果有函数调用,则进入该函数(进入函数的前提是,此函数被编译有debug信息)。step后面不加count表示一条条地执行,加表示执行后面的count条指令,然后再停住。

next <count>
单步跟踪,如果有函数调用,它不会进入该函数。同样地,next后面不加count表示一条条地执行,加表示执行后面的count条指令,然后再停住
 

 watch命令

 观察某个表达式(变量也是一种表达式)的值是否有变化了,如果有变化,马上停住程序

 r如下 i变化后,程序打印信息并挺住

 examine命令(缩写为x)

 查看内存地址中的值 x/<n/f/u> <addr>

n 是一个正整数,表示显示内存的长度,也就是说从当前地址向后显示几个地址的内容;f 表示显示的格式,如果地址所指的是字符串,那么格式可以是s,如果地址是指令地址,那么格式可以是i;u 表示从当前地址往后请求的字节数,如果不指定的话,GDB默认是4字节。u参数可以被一些字符代替:b表示单字节,h表示双字节,w表示四字节,g表示八字节。当我们指定了字节长度后,GDB会从指定的内存地址开始,读写指定字节,并把其当作一个值取出来。n、f、u这3个参数可以一起使用,例如命令“x/3uh 0x54320”表示从内存地址0x54320开始以双字节为1个单位(h)、16进制方式(u)显示3个单位(3)的内存。

set命令

修改寄存器,修改内存 

set {unsigned int}0x800100101=0x0

jump命令

jump <linespec> 

修改程序的执行顺序,从而让程序随意跳跃

signal命令

signal <signal>

产生一个信号量给被调试的程序, 如 "ctrl+c" 信号

return命令

return <expression>

使用return命令强制函数忽略还没有执行的语句并返回

call命令

 call <expr> 

强制调用某函数

info命令

查看寄存器、断点、观察点和信号等信息

 info registers (查看除了浮点寄存器以外的寄存器)

info all-registers (查看所有寄存器,包括浮点寄存器)

info registers <regname ...> (查看所指定的寄存器)

info break 列出当前所设置的所有观察点

 

info watchpoints 查看有哪些信号正在被GDB检测,

info signals info handle 也可以使用info line命令来查看源代码在内存中的地址。

info threads可以看多线程。

info line后面可以跟行号、函数名、文件名:行号、文件名:函数名等多种形式

 set scheduler-locking off|on|step 命令

off 不锁定任何线程,也就是所有线程都执行,这是默认值。
on 只有当前被调试程序会执行。
step 在单步的时候,除了next过一个函数的情况以外,只有当前线程会执行。

与多线程调试相关的命令还包括:

thread ID切换当前调试的线程为指定ID的线程。
break thread_test.c:123 thread all 在所有线程中相应的行上设置断点
thread apply ID1 ID2 command 让一个或者多个线程执行GDB命令command。
thread apply all command让所有被调试线程执行GDB命令command。


disassemble 命令

用于反汇编,它可被用来查看当前执行时的源代码的机器码,其实际上只是把目前内存中的指令dump出来

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值