GDB 摘要

GDB摘要

  • [GDB 摘要](#GDB 摘要)
    • [GDB 调试基本流程](#GDB 调试基本流程)
    • 实战示例
    • [调试案例:完整 C 语言程序调试过程](#调试案例:完整 C 语言程序调试过程)
      • [1. 准备调试程序](#1. 准备调试程序)
      • [2. 编译带调试信息](#2. 编译带调试信息)
      • [3. 启动 GDB 并运行程序](#3. 启动 GDB 并运行程序)
      • [4. 设置断点并重新运行](#4. 设置断点并重新运行)
      • [5. 单步执行并查看变量](#5. 单步执行并查看变量)
      • [6. 进入函数调试](#6. 进入函数调试)
      • [7. 跟踪递归调用过程](#7. 跟踪递归调用过程)
      • [8. 发现问题](#8. 发现问题)
      • [9. 定位并修复问题](#9. 定位并修复问题)
      • [10. 验证修复](#10. 验证修复)
      • [11. 完整调试命令总结](#11. 完整调试命令总结)
      • [12. 调试技巧](#12. 调试技巧)
      • [13. GDB 常见问题与排查](#13. GDB 常见问题与排查)
      • [14. GDB 命令速查表](#14. GDB 命令速查表)
    • C、C++
    • D
    • Go

GDB 摘要

像 GDB 这样的调试器的目的是让你在另一个程序执行时查看其"内部"的运行情况,或者在该程序崩溃时查看它当时正在做什么。

GDB 可以做四种主要的事情(以及支持这些事情的其他事情)来帮助你当场捕获错误:

  1. 启动你的程序,并指定任何可能影响其行为的因素。
  2. 让你的程序在指定条件下停止。
  3. 当你的程序停止时,检查发生了什么。
  4. 更改程序中的内容,这样你就可以尝试纠正一个错误的影响,并继续了解另一个错误。

你可以使用 GDB 来调试用 C 和 C++ 编写的程序。更多信息,请参阅"支持的语言"章节。更多信息,请参阅 C 和 C++ 部分。

对 D 语言的支持是部分的。有关 D 语言的信息,请参阅 D 部分。

对 Modula-2 语言的支持是部分的。有关 Modula-2 语言的信息,请参阅 Modula-2 部分。

对 OpenCL C 语言的支持是部分的。有关 OpenCL C 语言的信息,请参阅 OpenCL C 部分。

目前,调试使用集合、子范围、文件变量或嵌套函数的 Pascal 程序不起作用。GDB 不支持使用 Pascal 语法输入表达式、打印值或类似功能。

GDB 可用于调试用 Fortran 编写的程序,不过可能需要在引用某些变量时加上尾随下划线。

GDB 可用于调试用 Objective-C 编写的程序,使用 Apple/NeXT 或 GNU Objective-C 运行时均可。# 支持的语言

GDB 支持 C、C++、D、Go、Objective-C、Fortran、OpenCL C、Pascal、Rust、汇编、Modula-2 和 Ada。

GDB 调试基本流程

以下是 GDB 调试的基本流程图,展示了从启动程序到结束调试的完整过程:
#mermaid-svg-klrNsUmFpAUKWyo7{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-klrNsUmFpAUKWyo7 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-klrNsUmFpAUKWyo7 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-klrNsUmFpAUKWyo7 .error-icon{fill:#552222;}#mermaid-svg-klrNsUmFpAUKWyo7 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-klrNsUmFpAUKWyo7 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-klrNsUmFpAUKWyo7 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-klrNsUmFpAUKWyo7 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-klrNsUmFpAUKWyo7 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-klrNsUmFpAUKWyo7 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-klrNsUmFpAUKWyo7 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-klrNsUmFpAUKWyo7 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-klrNsUmFpAUKWyo7 .marker.cross{stroke:#333333;}#mermaid-svg-klrNsUmFpAUKWyo7 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-klrNsUmFpAUKWyo7 p{margin:0;}#mermaid-svg-klrNsUmFpAUKWyo7 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-klrNsUmFpAUKWyo7 .cluster-label text{fill:#333;}#mermaid-svg-klrNsUmFpAUKWyo7 .cluster-label span{color:#333;}#mermaid-svg-klrNsUmFpAUKWyo7 .cluster-label span p{background-color:transparent;}#mermaid-svg-klrNsUmFpAUKWyo7 .label text,#mermaid-svg-klrNsUmFpAUKWyo7 span{fill:#333;color:#333;}#mermaid-svg-klrNsUmFpAUKWyo7 .node rect,#mermaid-svg-klrNsUmFpAUKWyo7 .node circle,#mermaid-svg-klrNsUmFpAUKWyo7 .node ellipse,#mermaid-svg-klrNsUmFpAUKWyo7 .node polygon,#mermaid-svg-klrNsUmFpAUKWyo7 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-klrNsUmFpAUKWyo7 .rough-node .label text,#mermaid-svg-klrNsUmFpAUKWyo7 .node .label text,#mermaid-svg-klrNsUmFpAUKWyo7 .image-shape .label,#mermaid-svg-klrNsUmFpAUKWyo7 .icon-shape .label{text-anchor:middle;}#mermaid-svg-klrNsUmFpAUKWyo7 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-klrNsUmFpAUKWyo7 .rough-node .label,#mermaid-svg-klrNsUmFpAUKWyo7 .node .label,#mermaid-svg-klrNsUmFpAUKWyo7 .image-shape .label,#mermaid-svg-klrNsUmFpAUKWyo7 .icon-shape .label{text-align:center;}#mermaid-svg-klrNsUmFpAUKWyo7 .node.clickable{cursor:pointer;}#mermaid-svg-klrNsUmFpAUKWyo7 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-klrNsUmFpAUKWyo7 .arrowheadPath{fill:#333333;}#mermaid-svg-klrNsUmFpAUKWyo7 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-klrNsUmFpAUKWyo7 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-klrNsUmFpAUKWyo7 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-klrNsUmFpAUKWyo7 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-klrNsUmFpAUKWyo7 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-klrNsUmFpAUKWyo7 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-klrNsUmFpAUKWyo7 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-klrNsUmFpAUKWyo7 .cluster text{fill:#333;}#mermaid-svg-klrNsUmFpAUKWyo7 .cluster span{color:#333;}#mermaid-svg-klrNsUmFpAUKWyo7 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-klrNsUmFpAUKWyo7 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-klrNsUmFpAUKWyo7 rect.text{fill:none;stroke-width:0;}#mermaid-svg-klrNsUmFpAUKWyo7 .icon-shape,#mermaid-svg-klrNsUmFpAUKWyo7 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-klrNsUmFpAUKWyo7 .icon-shape p,#mermaid-svg-klrNsUmFpAUKWyo7 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-klrNsUmFpAUKWyo7 .icon-shape .label rect,#mermaid-svg-klrNsUmFpAUKWyo7 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-klrNsUmFpAUKWyo7 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-klrNsUmFpAUKWyo7 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-klrNsUmFpAUKWyo7 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是

单步执行
继续执行
修改变量
启动程序 (run)
设置断点 (break)
运行/暂停 (run/continue)
程序是否遇到断点?
检查变量/调用栈 (print/backtrace)
程序继续执行
调试操作选择
单步跟踪 (step/next)
继续运行 (continue)
修改变量值 (set)
程序结束

这个流程图展示了 GDB 调试的核心循环:

  1. 启动程序 :使用 run 命令开始执行
  2. 设置断点 :使用 break 在关键位置设置暂停点
  3. 运行控制:程序运行并在断点处暂停
  4. 状态检查:暂停时检查变量值、调用栈等信息
  5. 执行控制:选择单步执行或继续运行
  6. 循环或结束:根据需要重复调试或让程序结束

实战示例

调试案例:完整 C 语言程序调试过程

本节将通过一个实际的 C 语言程序调试案例,详细展示从编译带调试信息、启动 GDB、设置断点、单步执行、查看变量到定位问题的完整调试流程。

1. 准备调试程序

首先,我们创建一个有问题的 C 程序 debug_demo.c

c 复制代码
#include <stdio.h>
#include <stdlib.h>

int factorial(int n) {
    if (n <= 1) {
        return 1;
    }
    return n * factorial(n - 1);  // 递归计算阶乘
}

int main() {
    int num = 5;
    int result = 0;
    
    printf("计算 %d 的阶乘...\n", num);
    
    // 这里有一个逻辑错误:应该调用 factorial(num)
    result = factorial(num - 1);
    
    printf("结果: %d\n", result);
    
    // 验证结果
    if (result == 120) {
        printf("✓ 结果正确!\n");
    } else {
        printf("✗ 结果错误,期望 120,实际得到 %d\n", result);
    }
    
    return 0;
}

2. 编译带调试信息

使用 -g 选项编译程序,生成包含调试信息的可执行文件:

bash 复制代码
gcc -g -o debug_demo debug_demo.c

3. 启动 GDB 并运行程序

bash 复制代码
gdb ./debug_demo

进入 GDB 后,运行程序:

复制代码
(gdb) run
Starting program: /home/user/debug_demo 
计算 5 的阶乘...
结果: 24
✗ 结果错误,期望 120,实际得到 24
[Inferior 1 (process 12345) exited normally]

程序运行完成,但结果错误(5的阶乘应该是120,实际得到24)。

4. 设置断点并重新运行

我们在 main 函数和 factorial 函数设置断点:

复制代码
(gdb) break main
Breakpoint 1 at 0x5555555551a9: file debug_demo.c, line 12.

(gdb) break factorial
Breakpoint 2 at 0x555555555169: file debug_demo.c, line 4.

(gdb) run
Starting program: /home/user/debug_demo 

Breakpoint 1, main () at debug_demo.c:12
12      int main() {

5. 单步执行并查看变量

使用 next 命令逐行执行:

复制代码
(gdb) next
13          int num = 5;
(gdb) next
14          int result = 0;
(gdb) next
16          printf("计算 %d 的阶乘...\n", num);
(gdb) next
计算 5 的阶乘...
19          result = factorial(num - 1);

在调用 factorial 之前,查看变量值:

复制代码
(gdb) print num
$1 = 5
(gdb) print num - 1
$2 = 4

6. 进入函数调试

执行 step 命令进入 factorial 函数:

复制代码
(gdb) step
factorial (n=4) at debug_demo.c:4
4       int factorial(int n) {

查看调用栈:

复制代码
(gdb) backtrace
#0  factorial (n=4) at debug_demo.c:4
#1  0x00005555555551e0 in main () at debug_demo.c:19

7. 跟踪递归调用过程

继续单步执行,观察递归过程:

复制代码
(gdb) next
5           if (n <= 1) {
(gdb) print n
$3 = 4
(gdb) next
8           return n * factorial(n - 1);

再次进入递归调用:

复制代码
(gdb) step
factorial (n=3) at debug_demo.c:4
4       int factorial(int n) {
(gdb) continue
Continuing.

Breakpoint 2, factorial (n=3) at debug_demo.c:4
4       int factorial(int n) {

8. 发现问题

让我们快速执行到函数返回,查看最终结果:

复制代码
(gdb) finish
Run till exit from #0  factorial (n=3) at debug_demo.c:4
0x00005555555551c5 in factorial (n=4) at debug_demo.c:8
Value returned is $4 = 6

继续执行直到 main 函数中的 factorial 调用完成:

复制代码
(gdb) finish
Run till exit from #0  factorial (n=4) at debug_demo.c:8
0x00005555555551e0 in main () at debug_demo.c:19
Value returned is $5 = 24

9. 定位并修复问题

现在我们可以看到问题所在:factorial(4) 返回 24,而我们需要的是 factorial(5)。查看第19行代码:

复制代码
(gdb) list 19
14          int result = 0;
15          
16          printf("计算 %d 的阶乘...\n", num);
17          
18          // 这里有一个逻辑错误:应该调用 factorial(num)
19          result = factorial(num - 1);
20          
21          printf("结果: %d\n", result);

问题很明显:第19行错误地调用了 factorial(num - 1) 而不是 factorial(num)

10. 验证修复

我们可以直接修改变量值来验证:

复制代码
(gdb) set result = factorial(num)
(gdb) print result
$6 = 120

或者修改代码后重新编译:

c 复制代码
// 修复第19行
result = factorial(num);  // 正确:计算 num 的阶乘

11. 完整调试命令总结

本次调试使用的主要 GDB 命令序列:

复制代码
# 启动和基本设置
gdb ./debug_demo
break main
break factorial
run

# 单步执行和查看
next
step
print variable
backtrace

# 控制执行流
continue
finish

# 修改变量和验证
set variable = value

12. 调试技巧

  1. 使用 layout src:在 GDB 中显示源代码窗口

  2. 使用 watch :设置观察点,当变量值改变时暂停

    复制代码
    (gdb) watch result
  3. 使用 info breakpoints:查看所有断点状态

  4. 使用 commands:为断点设置自动执行的命令序列

  5. 使用 recordreverse :支持反向调试(需要编译时加 -record

通过这个完整的调试案例,你可以看到 GDB 如何帮助我们发现和定位代码中的逻辑错误。实际调试中,结合断点、单步执行、变量查看和调用栈分析,可以高效地解决复杂的程序问题。

以下是 GDB 中最常用的几个命令,每个命令都附有简短注释说明其作用:

bash 复制代码
# 1. 设置断点 - 在指定函数或行号处暂停程序执行
(gdb) break main          # 在 main 函数入口处设置断点
(gdb) break 42            # 在当前文件的第 42 行设置断点
(gdb) break file.c:15     # 在 file.c 文件的第 15 行设置断点

# 2. 运行程序 - 启动被调试的程序
(gdb) run                 # 从头开始运行程序
(gdb) run arg1 arg2       # 带参数运行程序

# 3. 查看变量值 - 显示变量的当前值
(gdb) print variable      # 打印变量的值
(gdb) print *pointer      # 打印指针指向的值
(gdb) print array[0]      # 打印数组元素

# 4. 单步执行 - 逐行执行代码
(gdb) next                # 执行下一行代码(跳过函数调用)
(gdb) step                # 执行下一行代码(进入函数调用)

# 5. 继续执行 - 从当前断点继续运行
(gdb) continue            # 继续执行直到下一个断点或程序结束
(gdb) c                   # continue 的简写形式

# 6. 查看调用栈 - 显示函数调用链
(gdb) backtrace           # 显示当前调用栈
(gdb) bt                  # backtrace 的简写形式
(gdb) frame 2             # 切换到调用栈的第 2 帧

# 7. 查看源代码 - 显示当前或指定位置的源代码
(gdb) list                # 显示当前行附近的源代码
(gdb) list 20,30          # 显示第 20-30 行的源代码
(gdb) list function       # 显示指定函数的源代码

这些命令涵盖了 GDB 调试的基本流程:设置断点 → 运行程序 → 查看变量 → 单步跟踪 → 继续执行。掌握这些命令后,你就可以开始有效地使用 GDB 进行程序调试了。

13. GDB 常见问题与排查

在实际使用 GDB 调试时,可能会遇到一些常见问题。下表列出了几个典型问题及其排查方法:

问题现象 可能原因 解决方案
程序运行后立即退出,无断点暂停 1. 编译时未添加 -g 调试信息 2. 断点设置位置不正确(如设置在了程序退出后) 3. 程序本身执行过快,在断点触发前已结束 1. 重新编译并确保添加 -g 选项:gcc -g -o program program.c 2. 使用 info breakpoints 检查断点状态,确保断点有效 3. 在 main 函数入口处设置断点:(gdb) break main
print 命令显示变量值为 <optimized out> 1. 编译时使用了优化选项(如 -O1, -O2, -O3) 2. 变量被编译器优化掉,未在调试信息中保留 1. 重新编译时禁用优化:gcc -g -O0 -o program program.c 2. 使用 -Og 选项(优化但不影响调试) 3. 尝试在变量作用域内查看,或使用 info locals 查看局部变量
单步执行时跳过了预期代码行 1. 编译器优化导致代码重排 2. 行号信息不准确 3. 正在执行的是编译器生成的代码(如内联函数) 1. 使用 stepi(单步指令)代替 step,逐条指令执行 2. 使用 disassemble 查看当前函数的汇编代码 3. 设置断点时使用函数名而非行号:(gdb) break function_name
断点无法触发或显示为「待定」 1. 共享库未加载 2. 断点设置在尚未加载的代码段 3. 程序是多进程/多线程架构 1. 使用 start 命令启动程序并停在 main 函数 2. 使用 set breakpoint pending on 允许设置待定断点 3. 对于动态库,使用 break filename:function 格式
程序崩溃时无堆栈信息 1. 核心转储未启用或大小限制为 0 2. 程序被信号终止但未生成核心文件 1. 设置核心文件大小无限制:ulimit -c unlimited 2. 运行程序时捕获信号:(gdb) catch signal 3. 使用 generate-core-file 命令手动生成核心文件

遇到其他问题时,可以尝试以下通用排查步骤:

  1. 使用 info registers 查看寄存器状态
  2. 使用 x/10i $pc 查看当前指令
  3. 使用 thread apply all bt 查看所有线程的调用栈
  4. 检查程序是否链接了调试版本库

14. GDB 命令速查表

下表整理了 GDB 常用命令,方便快速查阅:

程序运行控制
命令 简写 功能描述 示例
run r 启动程序执行 (gdb) run
start - 启动程序并停在 main 函数入口 (gdb) start
continue c 继续执行直到下一个断点 (gdb) c
step s 单步执行,进入函数调用 (gdb) s
next n 单步执行,跳过函数调用 (gdb) n
stepi si 单步执行一条机器指令 (gdb) si
nexti ni 单步执行一条机器指令,不进入函数 (gdb) ni
finish fin 执行完当前函数并返回 (gdb) finish
until u 运行到指定行号或函数结束 (gdb) until 45
kill k 终止正在运行的程序 (gdb) kill
quit q 退出 GDB (gdb) quit
断点管理
命令 简写 功能描述 示例
break b 设置断点 (gdb) b main (gdb) b 23 (gdb) b file.c:45
break if b if 设置条件断点 (gdb) b 30 if i==5
tbreak tb 设置临时断点(触发一次后删除) (gdb) tb foo
watch - 设置观察点(变量被修改时暂停) (gdb) watch var
rwatch - 设置读观察点(变量被读取时暂停) (gdb) rwatch var
awatch - 设置读写观察点 (gdb) awatch var
info breakpoints i b 显示所有断点信息 (gdb) i b
delete d 删除断点 (gdb) d 1 (gdb) d(删除所有)
disable dis 禁用断点 (gdb) dis 1-3
enable en 启用断点 (gdb) en 2
clear - 清除指定位置的断点 (gdb) clear main (gdb) clear 45
栈帧与变量查看
命令 简写 功能描述 示例
backtrace bt 显示调用栈 (gdb) bt (gdb) bt full(显示局部变量)
frame f 选择栈帧 (gdb) f 2
up - 向上移动栈帧 (gdb) up
down - 向下移动栈帧 (gdb) down
info frame i f 显示当前栈帧信息 (gdb) i f
info locals i locals 显示当前帧的局部变量 (gdb) i locals
info args i args 显示当前帧的函数参数 (gdb) i args
print p 打印表达式值 (gdb) p x (gdb) p *ptr (gdb) p array[5]
display disp 每次程序暂停时自动显示表达式 (gdb) display i
info display i disp 显示所有自动显示表达式 (gdb) i disp
undisplay undisp 取消自动显示 (gdb) undisp 1
whatis what 显示变量或表达式的类型 (gdb) whatis var
ptype - 显示类型的详细定义 (gdb) ptype struct Node
内存与寄存器
命令 简写 功能描述 示例
x - 检查内存内容 (gdb) x/10x &array(16进制) (gdb) x/20c str(字符) (gdb) x/8i func(指令)
info registers i r 显示所有寄存器值 (gdb) i r
info register i reg 显示指定寄存器值 (gdb) i reg eax
set - 设置变量或寄存器值 (gdb) set var i=10 (gdb) set $eax=0
examine x x 命令,检查内存 (gdb) examine/4wx 0x8048000
多线程调试
命令 简写 功能描述 示例
info threads i threads 显示所有线程信息 (gdb) i threads
thread t 切换到指定线程 (gdb) t 2
thread apply t apply 对所有或指定线程执行命令 (gdb) t apply all bt (gdb) t apply 1-3 p var
set scheduler-locking - 设置线程调度锁定 (gdb) set scheduler-locking on
其他实用命令
命令 简写 功能描述 示例
list l 显示源代码 (gdb) l (gdb) l 20,30 (gdb) l main
disassemble disas 反汇编当前函数或指定地址 (gdb) disas (gdb) disas main
shell sh 执行 shell 命令 (gdb) shell ls -l
set logging on - 开启日志记录 (gdb) set logging on
show - 显示 GDB 设置 (gdb) show language (gdb) show args
help h 显示命令帮助 (gdb) help break

C、C++

由于 C 和 C++ 密切相关,因此 GDB 的许多特性适用于这两种语言。只要是这种情况,我们就会一起讨论这些语言。

C++ 调试工具由 C++ 编译器和 GDB 共同实现。因此,要有效地调试你的 C++ 代码,你必须使用受支持的 C++ 编译器来编译你的 C++ 程序,例如 GNU g++,或者惠普 ANSI C++ 编译器(aCC)。

  • C 和 C++ 运算符
  • C 和 C++ 常量
  • C++ 表达式
  • C 和 C++ 默认值
  • C 和 C++ 类型和范围检查
  • GDB 和 C++
  • GDB C++ 的特性
  • 十进制浮点格式

D

GDB 可用于调试用 D 语言编写并使用 GDC、LDC 或 DMD 编译器编译的程序。目前 GDB 仅支持一项 D 语言特定特性 ------ 动态数组。

Go

GDB 可用于调试用 Go 编写并使用以下编译器编译的程序:gccgo 或 6g 编译器(6g 是 Go 1.4 之前的编译器)。

以下是 Go 特定功能和限制的总结:

当前 Go 包

在指定全局变量和函数时,不需要指定当前包的名称。

例如,给定程序:

go 复制代码
package main
var myglob = "Shall we?"
func main() {
  // ...
}

当在 main 函数内部停止时,以下两种方式都可行:

复制代码
(gdb) p myglob
(gdb) p main.myglob

内置 Go 类型

string 类型被 GDB 识别并作为字符串打印。

内置 Go 函数

GDB 表达式解析器识别 unsafe.Sizeof 函数并在内部处理它。

Go 表达式的限制

除了 &^ 之外,所有 Go 运算符都受支持。Go 的 _ "空白标识符"不受支持。不支持指针的自动解引用。

相关推荐
ttkwzyttk1 天前
GDB观察点与捕获点使用
gdb
ttkwzyttk6 天前
GDB函数调用栈管理
gdb
ttkwzyttk7 天前
GDB调试变量、内存与寄存器查看与修改
gdb
ttkwzyttk8 天前
GDB调试简介与调试配置
gdb
源分享22 天前
GDB下载和安装保姆级教程
gdb
modelmd1 个月前
翻译 GDB 官方文档
gdb
kidwjb1 个月前
一次多进程信号量同步失效的排查实录
gdb·进程通信·信号量
炘爚1 个月前
C++11实现线程池:项目实现过程的报错与gdb调试
stl·gdb·shared_ptr
___波子 Pro Max.1 个月前
GDB 符号检视三件套:`ptype` / `info variables` / `info functions`
gdb