实例:使用 gdb 查看进程内存中的数据结构
代码示例
首先,创建一个简单的链表程序 linked_list.c,以演示如何使用 gdb 查看内存中的数据结构。
#include <stdio.h>
#include <stdlib.h>
// 定义链表节点结构体
typedef struct Node {
int data;
struct Node* next;
} Node;
// 添加新节点到链表的尾部
void append(Node** head_ref, int new_data) {
Node* new_node = (Node*)malloc(sizeof(Node));
Node* last = *head_ref;
new_node->data = new_data;
new_node->next = NULL;
// 如果链表为空,新节点成为头节点
if (*head_ref == NULL) {
*head_ref = new_node;
return;
}
// 否则,遍历到链表的末尾,并添加新节点
while (last->next != NULL) {
last = last->next;
}
last->next = new_node;
}
// 打印链表的所有节点
void print_list(Node* node) {
while (node != NULL) {
printf("%d -> ", node->data);
node = node->next;
}
printf("NULL\n");
}
int main() {
Node* head = NULL;
append(&head, 1);
append(&head, 2);
append(&head, 3);
print_list(head);
// 等待用户输入,以便在 gdb 中调试
getchar();
return 0;
}
编译程序
使用 -g 标志编译程序,以便生成调试信息:
bash
gcc -g -o linked_list linked_list.c
使用 gdb 进行调试
-
启动
gdb:bashgdb ./linked_list -
设置断点:在
main函数的入口处设置断点:gdb(gdb) break main -
运行程序:开始运行程序,直到程序暂停在
main函数的入口处:gdb(gdb) run -
逐行执行:当断点命中时,逐行执行程序代码,直到到达定义
head变量的位置:gdb(gdb) n # 逐行执行,直至到达定义 'head' 变量的位置 -
打印
head变量:在正确的上下文中打印head变量的值:gdb(gdb) p head这将输出
head变量的地址,例如:gdb$1 = (Node *) 0x5555555592a0 -
检查链表节点:打印链表的节点数据。假设
head是链表的头节点,可以打印它及其后续节点的内容:gdb(gdb) p *head # 打印 head 节点的数据 (gdb) p *(head->next) # 打印下一个节点的数据 (gdb) p *(head->next->next) # 打印下下一个节点的数据输出示例:
gdb$2 = {data = 1, next = 0x5555555592c0} $3 = {data = 2, next = 0x5555555592e0} $4 = {data = 3, next = 0x0}
总结
- 编译程序:确保使用
-g标志编译程序。 - 启动
gdb:使用gdb附加到程序。 - 设置断点:在
main函数的入口处设置断点。 - 运行程序:运行程序并在断点处停止。
- 逐行执行:逐行执行程序,直至访问
head变量。 - 打印和检查变量:打印
head和链表节点的数据。
通过以上步骤,你可以在 gdb 中成功查看和调试进程内存中的数据结构。

浙公网安备 33010602011771号