美文网首页
gdb cheatsheet

gdb cheatsheet

作者: 廖少少 | 来源:发表于2021-08-16 17:53 被阅读0次

    GDB

    gdb调试中直接输入回车是重复上一步命令

    start:临时断点打在main函数处,等候进一步指令

    r(run):从main函数处开始运行程序,直至程序结束/出错/到达断点

    shell ls / !ls:在gdb中执行shell命令

    set prompt (xxxx) :修改命令提示符前缀,默认是(gdb),多gdb调试时用来区分

    $gdb -args ./a.out a b c / (gdb) set args a b c:指定程序的命令行参数,下次调用run时就会使用a b c参数,也可以(gdb) run a b c / (gdb) start a b c

    set logging on:将gdb调试的历史保存到日志中;set logging file xx.file:指定gdb调试日志名字,默认是gdb.txt;set logging overwrite on:覆盖之前的gdb调试日志,默认是追加写gdb调试日志

    函数

    info functions:列出可执行文件的所有函数名称

    info functions regex:指定函数,使用正则表达式匹配

    step(缩写为s):可以进入函数(函数必须有调试信息)

    next(缩写为n):不进入函数,gdb会等函数执行完,再显示下一行要执行的程序代码

    set step-mode on:设置步进模式,进入没有调试信息的函数

    finish:执行完当前函数,并且打印返回值

    return (expression):当前函数不会继续执行,而是直接返回,可以指定返回值

    call/print:直接调用函数执行

    i frame:输出当前函数堆栈帧的地址,指令寄存器的值,局部变量地址及值等信息

    i registers:输出当前寄存器中的值

    disassemble fun:输出函数的汇编代码

    f(frame) n:选择函数堆栈帧,n为层数,

    f(frame) addr:选择函数堆栈帧,其中addr是堆栈地址

    up n / down n:向上或向下选择函数堆栈帧,n为层数

    up-silently n / down-silently n:与上面指令的区别在于,切换堆栈帧后,不会打印信息

    断点

    b Foo::foo / b (anonymous namespace):命名空间/匿名空间打断点

    b *address:当调试汇编程序,或者没有调试信息的程序时,在程序地址上打断点

    b:在当前代码行打上断点

    info b:输出当前所有断点,它们各自的bnum以及所在的相对路径文件与行号

    disable <bnum>:关闭编号为bnum的断点;enable <bnum>:打开编号为bnum的断点;delete <bnum>:删除编号为bnum的断点

    b 6:当前文件第6行打断点

    b file.c:6:gdb会对所有匹配的文件(file.c)的第6行设置断点

    b a/file.c:6:通过指定(部分)路径,来区分相同的文件名

    b a/file.c:6 if i==100:设置条件断点

    condition <bnum> (<condition>):把bnum断点的条件修改为condition

    ignore <bnum> count:接下来count次编号为bnum的断点触发都不会让程序中断

    tb(tbreak) a/file.c:6:设置临时断点,断点只会生效一次,然后就会删除

    rbreak regexp:在所有匹配regexp的函数名都设置断点,regexp与grep相同

    在程序入口处打断点:当调试没有调试信息的程序时,直接运行start命令是没有效果的,如果不知道main在何处,那么可以在程序入口处打断点,两种方法:

    
    # 方法一:从elf文件处获得程序入口(entry point)
    
    $ strip a.out
    
    $ readelf -h a.out
    
    ELF Header:
    
      Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
    
      ...
    
      Entry point address:               0x400440
    
      ...
    
    # 方法二:info files
    
    $ gdb a.out 
    
    (gdb) info files
    
    # -------------------------------------------------------- #
    
    (gdb) b *0x400440
    
    

    观察点

    watch(wa) a:当变量a的值发生变化,程序暂停

    watch (data type)address:当类型为data type、地址为address的内存发生变化,程序暂停

    info disable enable delete用法与断点类似

    set can-use-hw-watchpoints:禁止硬件观察点,如果系统支持硬件观察点,设置观察点会有输出Hardware watchpoint num: expr,需要注意软件观察点会让程序很慢

    watch expr thread threadnum:设置观察点只针对线程编号为threadnum的线程生效(只对硬件观察点生效

    rwatch(rw) a:当读取变量a时,程序就会暂停住(只对硬件观察点生效

    awatch(aw) a:当发生读取变量a或改变变量a值的行为,程序就会暂停住(只对硬件观察点生效

    catchpoint

    简介:use catchpoints to cause the debugger to stop for certain kinds of program events, such as C++ exceptions or the loading of a shared library

    catch fork:程序在调用fork系统调用时暂停

    tcatch fork:程序只在第一次调用fork时暂停

    catch syscall [name | number]:为指定的系统调用设定catchpoint,系统调用和编号的映射参考具体的xml文件,如果不指定具体的系统调用,则会为所有的系统调用设置catchpoint

    打印

    set print elements number-of-elements:打印大数组的元素时缺省最多200个,该命令可以修改该限制

    p array[index]@num:打印数组中任意连续元素的值

    set print array-indexes on:设置打印数组时同时打印索引下标

    bt full:打印函数堆栈各自的局部变量

    bt full n:从内向外打印n个栈帧的局部变量

    bt full -n:从外向内打印n个栈帧的局部变量

    info locals:打印当前函数局部变量的值

    p 'stataic-1.c'::var:打印指定文件的静态变量的值

    whatis he:打印变量he的类型

    ptype he:打印变量he的类型的详细信息

    info variable ^he$:查看定义变量he的文件,^he$是正则完全匹配he,如果不完全匹配,可能会匹配到很多变量

    x/s:打印ASCII字符串

    x/nfu addr:以f格式打印从addr开始的n个长度单元为u的内存值。n:输出单元的个数。f:是输出格式。比如x是以16进制形式输出,o是以8进制形式输出。u:标明一个单元的长度。b是一个byte,h是两个byte(halfword),w是四个byte(word),g是八个byte(giant word)。

    l(list) [line_num / func_name]:打印源代码以及行号,可以指定行号与函数名

    l -/+:指定打印源代码向前或向后打印

    l 1,10:指定打印源代码范围

    set print pretty on:设置打印的美化,每行只会显示结构体的一名成员,默认打印结构体是很紧凑的

    set print object on:设置打印按照派生对象的类型,设置后会修改p/whatis/ptype的输出结果

    p func_in_frame2::b:直接打印调用栈帧中的变量值,不需要先切换到对应栈帧再打印变量值

    多进程/线程

    $ gdb programe -p / --pid:调试已经运行的进程

    attach pid:gdb启动后,调用该命令调试已经运行的进程

    detach:退出当前正在调试的进程

    set follow-fork-mode child:设置调试子进程,父进程退出后程序会自动调试子进程

    set detach-on-fork off:gdb默认只会跟踪父进程,子进程不受控制,该命令可以同时调试父子进程

    info inferiors:查看进程状态,显示*的是当前正在调试的进程

    info threads [threadnum]:查看所有线程信息,LWP是lightweight process(轻量级进程)

    set schedule-multiple on:gdb默认不能同时运行父子进程,该命令可以同时执行父子进程

    thread <ID> 切换调试的线程为指定ID的线程。

    break file.c:100 thread all 在file.c文件第100行处为所有经过这里的线程设置断点。

    set scheduler-locking on:调试一个线程时,让其他线程暂停(默认是off,即不暂停,除了on/off,还有step模式:用step命令调试线程时,其他线程不会执行,但是用其他命令(如next)调试线程时,其他线程也许会执行

    add-inferior [ -copies n ] [ -exec executable ]:在gdb会话中调试另一个可执行文件,可同时调试多个可执行文件

    为调试进程产生core dump文件

    generate-core-file / gcore:为当前调试的进程产生core dump文件,default name is 'core.<process_id>'

    $ gdb path/to/the/executable path/to/the/coredump:加载core dump文件

    file <excutive file>:读取可执行文件的符号表信息

    core <core file>:指定core dump文件位置

    汇编

    disassemble <func name>:显示函数的汇编指令

    set disassembly-flavor intel:将汇编改为intel格式,gdb默认是AT&T,该命令只能用于intel x86处理器上

    b *func:将断点设置在汇编指令层次函数的开头,如果仅用b func不会把断点设在汇编指令层次函数的开头

    disassemble /m fun:将函数内所有代码与汇编指令映射起来

    disassemble 0x4004e9, 0x40050c:只查看某条语句对应的汇编代码

    i line 13:Line 13 of "foo.c" starts at address 0x4004e9 <main+37> and ends at 0x40050c <main+72>.

    display /ni $pc:当程序停止时,该指令可以显示将要执行的n行汇编指令

    i registers:查看寄存器的值,不包含浮点寄存器与向量寄存器

    i all-registers:查看所有寄存器的值

    disassemble /r:用16进制显示程序的原始机器码

    改变程序的执行

    set main::p1="Jil":更改字符串的值,一定要注意内存越界的问题

    set {char [4] } 0x80477a4 = "Ace":更改指定内存地址的字符串的值,更改字符串的值,一定要注意内存越界的问题

    set var variable=expr:设置变量的值

    set {type}address=expr:给存储地址在address、变量类型为type的变量赋值

    set var $eax = 8:eax寄存器存储着函数的返回值,也可以通过这种方式修改函数的返回值

    set var $pc=0x08050949:pc寄存器存储着接下来要执行的指令,可以通过这种方式更改程序的执行流程

    info line 7:Line 7 of "a.c" starts at address 0x8050949 <main+40> and ends at 0x805094e <main+45>.

    jump [line_num]:调到第line_num行,该指令只改变pc的值,所以可能会出现不同的结果

    command <break_num>(然后输入多行命令最后以end行结尾):为断点break_num设置指令组合,当程序运行到断点处,会自动执行command 1的指令组合,然后继续执行

    set write on:允许gdb修改二进制文件

    set variable (short)0x400651=0x0ceb:修改二进制代码,注意大小端和指令长度

    信号

    info signals/handle:查看gdb如何处理进程收到的信号

    handle SIGHUP nostop:设置当SIGHUP信号发生时,gdb不暂停程序,handle signal stop/nostop

    handle SIGHUP noprint:设置当SIGHUP信号发生时,gdb不打印信号信息,handle signal print/noprint

    handle SIGHUP nopass:设置当SIGHUP信号发生时,gdb不把信号丢给程序处理,handle signal pass(noignore)/nopass(ignore)

    signal SIGHUP:gdb会直接将信号发送给程序处理,而且程序会继续运行

    与在shell中使用kill发送信号给程序的区别是:kill发送信号,gdb会决定是否把信号发送给进程,而signal指令是直接发送信号

    signal 0:程序重新运行,但不会收到SIGHUP信号

    源文件

    directory [path]:设置查找源文件的路径,有时gdb不能准确地定位到源文件的位置(比如文件被移走了,等等)

    $gdb a.out -d /search/code/some:在gdb启动时指定搜索源文件的路径

    set substitute-path [from] [to]:查看源代码时,用新的目录代替旧的目录

    info source:显示当前源文件名

    info sources:显示加载的symbols涉及的源文件

    图形界面

    $ gdb --tui / (gdb) (ctrl+X+A):进入图形化调试界面

    layout asm:进入图形化界面后,该命令显示汇编代码窗口

    layout split:进入图形化洁面后,该命令同时显示源代码和汇编代码

    layout regs:显示通用寄存器窗口

    winheight <win_name> [+ | -] count:调整窗口大小,winheight缩写为winwin_name可以是srccmdasmregs。count是变化值

    Ctrl + L:刷新窗口

    命令的缩写

    b -> break
    c -> continue
    d -> delete
    f -> frame
    i -> info
    j -> jump
    l -> list
    n -> next
    p -> print
    r -> run
    s -> step
    u -> until
    
    aw -> awatch
    bt -> backtrace
    dir -> directory
    disas -> disassemble
    fin -> finish
    ig -> ignore
    ni -> nexti
    rw -> rwatch
    si -> stepi
    tb -> tbreak
    wa -> watch
    win -> winheight
    

    另外,如果直接按回车键,会重复执行上一次的命令。

    相关文章

      网友评论

          本文标题:gdb cheatsheet

          本文链接:https://www.haomeiwen.com/subject/vqcvbltx.html