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 的 _ "空白标识符"不受支持。不支持指针的自动解引用。

相关推荐
源分享2 天前
GDB下载和安装保姆级教程
gdb
modelmd14 天前
翻译 GDB 官方文档
gdb
kidwjb20 天前
一次多进程信号量同步失效的排查实录
gdb·进程通信·信号量
炘爚22 天前
C++11实现线程池:项目实现过程的报错与gdb调试
stl·gdb·shared_ptr
___波子 Pro Max.23 天前
GDB 符号检视三件套:`ptype` / `info variables` / `info functions`
gdb
CC城子1 个月前
嵌入式Linux宕机问题GDB调试(一)
gdb·嵌入式软件
CC城子1 个月前
嵌入式Linux宕机问题GDB调试(二)
linux·gdb
故事还在继续吗1 个月前
常见的导致 coredump 的原因
开发语言·gdb
C咖咖1 个月前
Linux 下使用 GDB 调试 C++ 的全面总结
linux·gdb·调试