# GDB-debugging **Repository Path**: helin1/gdb-debugging ## Basic Information - **Project Name**: GDB-debugging - **Description**: No description available - **Primary Language**: C++ - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-12-31 - **Last Updated**: 2025-01-13 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # GDB-debugging #### 介绍 此仓库用于记录一些gdb相关的内容 ##### 1.启动与停止GDB调试 启动GDB调试 ```shell gdb program name ``` 退出GDB调试 ```shell quit ``` 也可以输入“q”退出 ##### 2.GDB命令 符号 | 命令 -----|----- b | breakpoint 设置断点 c | continue 让程序继续执行 l | list 展示当前执行的源码 n | next 执行下一行代码,然后停止 p | print 打印变量或者表达式的值 q | quit 退出GDB调试 r | run 从开头执行程序 s | step in 进入执行的函数 x | examine memory 检查内存,并显示指定地址或内存区域的内容 help | 显示所有GDB命令 在GDB环境下,支持命令自动补全 ##### 3.基本的debug ```shell run 12 bob ``` run命令会启动程序,如果程序需要参数,可以像上面的命令一样,在run后输入对应的参数。在GDB下也支持重定向,可以从文件中读取参数然后输入给run命令。如下所示: ```shell run < filename ``` ##### 4.打断点与查看断点 设置断点方式有如下几种: 断点方式 | 解释 --------------------------------|-------------------------------------- break line number | 在line number行处设置断点 break filename.cpp:line number | 在文件filename.cpp的linenumber处设置断点 break function name | 在函数function name处设置断点 break | break没有参数,就在下一行代码处设置断点 break location if condition | 当condition为true时在location处设置断点 info breakpoints | 显示所有的断点 watch expr | 给expr设置一个watchpoint(观察点),当expr的值发生变化的时候停止,有时这种也叫data breakpoint(数据断点) info watchpoints | 显示所有的观察点 ##### 5.continuing and stepping 命令 | 解释 -----------|----------- continue | 可以用简写c代替,表示恢复程序执行,直到下一个断点或者程序完成 step | 可以用简写s代替,表示进入下一行代码中,可能是进入某个函数里 step count | 执行count次step命令 next count | 执行count次next命令 stepi arg | 类似于step命令,但是stepi是执行机器指令级别的,而不是像step一样执行代码级别的,arg参数类型与count,表示执行多少次该命令 nexti arg | 类似于next命令,但是nexti是执行机器指令级别的,而不是像next一样执行代码级别的,arg参数类型与count,表示执行多少次该命令 ##### 6.检查栈 当程序停止时,首先需要知道它在哪里停止以及如何到达那里。 每次程序执行函数调用时,都会生成关于该调用的信息。这些信息包括程序中调用的位置、调用的参数以及被调用函数的局部变量。这些信息保存在一个称为栈帧的数据块中。栈帧分配在称为调用栈的内存区域中。 当你的程序停止时,GDB用于检查栈的命令允许你查看所有这些信息。 GDB会选择其中一个栈帧,许多GDB命令隐式地引用所选的帧。特别是,每当你要求GDB获取程序中变量的值时,该值是在所选帧中找到的。默认情况下,使用当前栈帧。调用栈被划分为连续的部分,称为栈帧,或简称为帧;每个帧是与一次函数调用相关的数据。帧包含传递给函数的参数、函数的局部变量以及函数正在执行的地址。 当你的程序启动时,栈中只有一个帧,即函数main的帧。这被称为初始帧或最外层帧。每次调用函数时,都会创建一个新的帧。每次函数返回时,该函数调用的帧就会被消除。如果一个函数是递归的,那么可能会有多个相同函数的帧。实际执行的函数的帧被称为最内层帧。这是所有仍然存在的栈帧中最近创建的一个。 在你的程序中,栈帧通过它们的地址来标识。一个栈帧由许多字节组成,每个字节都有自己的地址;每种计算机都有一种约定来选择一个字节,其地址作为帧的地址。当在该帧中执行时,通常这个地址保存在一个称为帧指针寄存器的寄存器中。 GDB为所有现有的栈帧分配编号,从最内层帧的零开始,为调用它的帧分配一,依此类推。这些编号在你的程序中实际上并不存在;它们是由GDB分配的,目的是为你提供一种在GDB命令中指定栈帧的方法。 命令 | 解释 -------------|------------- frame arg | frame命令允许你从一个栈帧移动到另一个栈帧,并打印你选择的栈帧。arg可以是帧的地址或栈帧编号。如果没有参数,frame命令会打印当前的栈帧。 select-frame | select-frame命令允许你从一个栈帧移动到另一个栈帧而不打印该帧。这是frame命令的静默版本。 ###### backtrace backtrace是一个总结,显示了你的程序如何到达当前位置。它为每个帧显示一行,从当前执行的帧(帧零)开始,接着是它的调用者(帧一),依此类推。backtrace(或where)命令打印关于调用栈的信息。 命令 | 解释 ---------------|------------- backtrace | 可以用简写bt代替,打印整个栈的backtrace(回溯):每个帧一行,显示栈中的所有帧。你可以随时通过输入系统中断字符(通常是Ctrl-c)来停止backtrace。 backtrace n | 可以用简写bt n代替,与backtrace类似,但只打印最内层的n个帧。 backtrace full | 可以用bt full代替,也可以使用bt full n。打印局部变量的值。n指定要打印的帧数。 ##### 7.检查源码 命令 | 解释 -----------------------------------|-------------------------------------- list linenum/list filename:linenum | 打印linenum附近的代码 list function/list filename:function | 打印函数function周围的代码 list - | 打印刚才打印的行之前的几行 list *address | 指定程序地址address。这指定了包含该地址的源代码行。 默认情况下,list会打印10行代码,如果需要打印更多代码,可是使用*set listsize number-of-lines* ##### 8.检查数据 命令 | 解释 ---------------|------------- print expr/variable | 打印表达式expr/变量variable的值 print /f expr | expr是一个表达式(在源语言中)。默认情况下,expr的值会以适合其数据类型的格式打印;你可以通过指定`/f`来选择不同的格式,其中f是指定格式的字母。 其中,打印格式支持如下几种: ```shell x -- 将值的位视为整数,并以十六进制打印该整数。 d -- 以有符号十进制打印整数。 u -- 以无符号十进制打印整数。 o -- 以八进制打印整数。 t -- 以二进制打印整数。字母`t`代表"two"(二)。 a -- 以地址打印,既以十六进制绝对地址打印,也以距最近前导符号的偏移量打印。你可以使用这种格式来发现未知地址位于哪个函数中。 c -- 将值视为整数并以字符常量打印。这会同时打印数值和其字符表示。对于超出7位ASCII范围的字符,字符表示将替换为八进制转义`\nnn`。如果不使用这种格式,GDB会将char、unsigned char和signed char数据显示为字符常量。向量的单字节成员将显示为整数数据。 f -- 将值的位视为浮点数,并使用典型的浮点数语法打印。 s -- 如果可能,将值视为字符串。使用这种格式,指向单字节数据的指针将显示为以空字符结尾的字符串,单字节数据的数组将显示为定长字符串。其他值将以其自然类型显示。如果不使用这种格式,GDB会将指向char、unsigned char和signed char的指针和数组显示为字符串。向量的单字节成员将显示为整数数组。 r -- 使用`raw`格式打印。默认情况下,GDB会使用特定类型的pretty-printer。`r`格式会绕过任何可能存在的值类型的pretty-printer。 ``` 如果你发现需要频繁打印某个表达式的值(以查看其变化),你可能希望将其添加到自动显示列表中,这样 GDB 每次程序停止时都会打印其值。添加到列表中的每个 表达式都会被赋予一个编号来标识它;要从列表中移除一个表达式,你需要指定该编号。自动显示看起来像这样: ```shell 2: foo = 38 3: bar[5] = (struct hack *) 0x3804 ``` 这种显示会显示项目编号、表达式及其当前值。与使用 x 或 print 手动请求的显示一样,你可以指定你偏好的输出格式;实际上,display 会根据你的格式说明 来决定是使用 print 还是 x ——如果你指定了 i 或 s 格式,或者指定了单位大小,它就会使用 x;否则它会使用 print。 命令 | 解释 ----|---- display expr | 将表达式expr添加到自动显示列表中,这样程序每次在停止的时候都会打印expr的值。 display/fmt expr | 将表达式expr添加到自动显示列表中,并在打印的时候用格式fmt进行打印。 display/fmt addr | 将地址addr添加到自动显示列表中,并在这样程序每次在停止的时候都会打印addr对应的值。