linux 上使用gdb

使用 GDB 在 Linux 上进行 Debug

在 Linux 上使用 GDB 进行调试,主要分为以下几个步骤:

  1. 编译程序:

编译程序时需要加上 -g 选项,生成调试信息。例如:

gcc -g myprogram.c -o myprogram
  1. 启动 GDB:

可以使用以下两种方式启动 GDB:

  • 直接调试程序:
gdb myprogram
  • 调试已运行的程序:
gdb -p <pid>

其中 是要调试的程序的进程 ID。

  1. 设置断点:

在程序启动前,可以使用 break 命令设置断点。例如:

  • 在 main 函数入口处设置断点:
(gdb) break main
  • 在 myfunction 函数的第 10 行设置断点:
(gdb) break myfunction:10
  • 在某个地址处设置断点:
(gdb) break *0x400500
  1. 运行程序:

使用 run 命令运行程序,程序会在断点处停止。

  1. 单步调试:

程序停止后,可以使用以下命令进行单步调试:

  • next (或 n): 执行下一行代码,不进入函数内部。
  • step (或 s): 执行下一行代码,如果遇到函数调用则进入函数内部。
  • continue (或 c): 继续执行程序,直到遇到下一个断点或程序结束。
  • finish (或 fin): 执行完当前函数并返回。
  1. 查看变量和内存:

可以使用以下命令查看变量和内存:

  • print (或 p): 打印变量的值。例如:print i
  • display (或 disp): 每次程序停止时都打印指定的变量值。例如:display i
  • x/<n/f/u>
    : 以指定格式查看内存内容。
    • n: 显示的单元个数
    • f: 显示格式 (x 十六进制, d 十进制, u 无符号十进制, c 字符, s 字符串)
    • u: 单元大小 (b 字节, h 半字, w 字, g 八字节)
  1. 其他常用命令:
  • info breakpoints: 查看所有断点信息。
  • delete <breakpoint_number>: 删除指定编号的断点。
  • disable <breakpoint_number>: 禁用指定编号的断点。
  • enable <breakpoint_number>: 启用指定编号的断点。
  • backtrace (或 bt): 显示程序崩溃时的调用栈。
  • info locals: 显示当前栈帧的局部变量。
  • info registers: 显示寄存器的值。
  • quit (或 q): 退出 GDB。

示例:

gcc -g myprogram.c -o myprogram
gdb myprogram
(gdb) break main
(gdb) run
(gdb) next
(gdb) print i
(gdb) continue
(gdb) quit

总结:

以上是使用 GDB 在 Linux 上进行 Debug 的基本步骤和常用命令。GDB 还有很多其他的功能,可以通过 help 命令查看帮助文档。

希望以上内容能够帮助入门 GDB 调试。

GDB 设置断点详解

在 GDB 中,断点是调试过程中非常重要的工具,它允许在程序执行到特定位置时暂停,以便检查程序状态、变量值等信息。

  1. 设置断点的方式:

GDB 提供了多种设置断点的方式,以下列举几种常用的方法:

  • 按行号设置断点:
(gdb) break <line_number>
(gdb) b <line_number>

例如,在 main.c 文件的第 10 行设置断点:

(gdb) break main.c:10
  • 按函数名设置断点:
(gdb) break <function_name>
(gdb) b <function_name>

例如,在 my_function 函数入口处设置断点:

(gdb) break my_function
  • 按条件设置断点:
(gdb) break <line_number> if <condition>
(gdb) b <line_number> if <condition>

例如,在 main.c 文件的第 10 行设置断点,条件是变量 i 的值等于 10:

(gdb) break main.c:10 if i == 10
  • 按地址设置断点:
(gdb) break *<address>
(gdb) b *<address>

例如,在地址 0x400500 处设置断点:

(gdb) break *0x400500
  1. 查看断点信息:

使用 info breakpoints (或 i b) 命令可以查看所有已设置的断点信息,包括断点编号、类型、位置、条件等。

  1. 管理断点:
  • 删除断点:
(gdb) delete <breakpoint_number>
(gdb) d <breakpoint_number>

例如,删除编号为 1 的断点:

(gdb) delete 1
  • 禁用断点:
(gdb) disable <breakpoint_number>

禁用断点后,程序执行到该断点位置时不会停止。

  • 启用断点:
(gdb) enable <breakpoint_number>

启用断点后,程序执行到该断点位置时会停止。

  1. 其他断点相关命令:
  • clear: 清除当前行或指定位置的断点。
  • tbreak: 设置临时断点,程序在该断点停止一次后会自动删除。
  • rbreak : 在所有匹配正则表达式的函数入口处设置断点。
  • catch : 设置捕捉点,当指定事件发生时程序会停止,例如 catch throw 捕捉 C++ 异常抛出事件。

示例:

(gdb) break main
(gdb) run
Breakpoint 1, main () at main.c:10
10    int i = 0;
(gdb) print i
1 = 0
(gdb) continue
Continuing.
Breakpoint 1, main () at main.c:12
12    i++;
(gdb) print i
2 = 1
(gdb) disable 1
(gdb) continue
Continuing.
[Inferior 1 (process 18773) exited normally]

总结:

GDB 提供了丰富的断点设置和管理功能,熟练掌握这些功能可以帮助更高效地进行程序调试。

希望以上内容能够帮助更好地理解 GDB 断点设置。

在 GDB 中查看代码

GDB 提供了多种方式来查看程序代码,方便在调试过程中理解程序逻辑和定位问题。

  1. list 命令:

list 命令 (或 l) 是最常用的查看代码命令,它可以显示当前执行位置附近的代码。

  • 显示当前执行位置附近的代码:
(gdb) list
  • 显示指定行号附近的代码:
(gdb) list <line_number>
  • 显示指定函数的代码:
(gdb) list <function_name>
  • 显示指定文件中的代码:
(gdb) list <filename>:<line_number>
  • 继续显示后续代码:
(gdb) list

每次执行 list 命令都会显示后续的代码行。

  • 显示之前的代码:
(gdb) list -
  1. set listsize 命令:

可以使用 set listsize 命令设置每次 list 命令显示的代码行数。例如,设置每次显示 20 行代码:

(gdb) set listsize 20
  1. search 命令:

search 命令 (或 /) 可以在当前文件中搜索指定的字符串。例如,搜索字符串 “error”:

(gdb) search error
  1. forward-search 命令 和 reverse-search 命令:

forward-search 命令 (或 /) 和 reverse-search 命令 (或 ?) 分别向前和向后搜索指定的正则表达式。

  1. dir 命令:

dir 命令可以将源文件目录添加到 GDB 的搜索路径中,方便查看其他文件中的代码。例如,添加 /home/user/myproject/src 目录到搜索路径:

(gdb) dir /home/user/myproject/src
  1. info sources 命令:

info sources 命令可以显示 GDB 当前加载的源文件列表。

  1. frame 命令:

frame 命令可以切换到不同的栈帧,并显示对应栈帧的代码。例如,切换到栈帧 0:

(gdb) frame 0

示例:

(gdb) break main
(gdb) run
Breakpoint 1, main () at main.c:10
10    int i = 0;
(gdb) list
8    #include <stdio.h>
9
10    int main() {
11      int i = 0;
12      i++;
13      printf("i = %d\n", i);
14      return 0;
15    }
(gdb) list 15
10    int main() {
11      int i = 0;
12      i++;
13      printf("i = %d\n", i);
14      return 0;
15    }
(gdb)

实战:调试包含 3 个 cpp 文件的应用程序

创建一个简单的示例程序,包含以下三个文件:

main.cpp:

#include <iostream>
#include "calculator.h"

int main() {
  Calculator calc;
  int result = calc.add(5, 3);
  std::cout << "Result: " << result << std::endl;
  return 0;
}

calculator.h:

#ifndef CALCULATOR_H
#define CALCULATOR_H

class Calculator {
public:
  int add(int a, int b);
  int subtract(int a, int b);
};

#endif

calculator.cpp:

#include "calculator.h"

int Calculator::add(int a, int b) {
  return a + b;
}

int Calculator::subtract(int a, int b) {
  return a - b;
}

编译程序:

使用 -g 选项编译程序,生成调试信息:

g++ -g main.cpp calculator.cpp -o myapp

使用 GDB 调试:

  1. 启动 GDB:
gdb myapp
  1. 设置断点:

在 Calculator::add 函数入口处设置断点:

(gdb) break calculator.cpp:3
Breakpoint 1 at 0x...: file calculator.cpp, line 3.
  1. 运行程序:
(gdb) run
Starting program: /path/to/myapp


Breakpoint 1, Calculator::add (this=0x..., a=5, b=3) at calculator.cpp:3
3    return a + b;

程序会在断点处停止。

  1. 查看代码:

使用 list 命令查看当前代码:

(gdb) list
1    #include "calculator.h"
2
3    int Calculator::add(int a, int b) {
4      return a + b;
5    }
6
7    int Calculator::subtract(int a, int b) {
8      return a - b;
9    }
  1. 查看变量值:

使用 print 命令查看变量 a 和 b 的值:

(gdb) print a
1 = 5
(gdb) print b
2 = 3
  1. 单步执行:

使用 next 命令单步执行下一条语句:

(gdb) next
4      return a + b;
  1. 继续执行:

使用 continue 命令继续执行程序,直到下一个断点或程序结束:

(gdb) continue
Continuing.
Result: 8
[Inferior 1 (process 1234) exited normally]

其他常用命令:

  • step: 单步执行,进入函数内部。
  • backtrace: 查看函数调用栈。
  • info breakpoints: 查看已设置的断点。
  • delete: 删除断点。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值