首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >面试官:Gdb 如何调试core文件

面试官:Gdb 如何调试core文件

作者头像
早起的鸟儿有虫吃
发布2025-12-24 18:11:48
发布2025-12-24 18:11:48
2340
举报

腾讯一面:生产环境如何使用gdb调试Release发行版本的程序?

这篇文章写不行,重写一次。

一句话描述:

  • 用gdb作用证明问题出现在哪里,哪个流程环境出现问题了。
  • 想要解决这个问题,需要业务是否了解。如果非自己模块问题,直接刷给别人。
  • 单纯靠gdb无法解决问题

问:如果使用gdb解决core问题

下面是我的回答

假如产生core下面是我解决步骤

第一步:确定哪个服务产生core

假如 一台服务器上20个服务,

我怎么清楚那个服务出现问题

必须明确清楚。

进入 /var/log/core 或者 /var/crash 目录

file <core文件名>

代码语言:javascript
复制
hello: ELF 64-bit LSB executable, x86-64, , stripped

关键字段not stripped 包含调试符号和调试信息。

关键字段stripped表示符号表和调试信息已被移除

第二步:确定是否加载调试符号

一般生产Release版本都无调试符号,需要加载

直接找管理员 寻找rpm debug按照包 直接安装,

这个事情让管理员执行,你时间宝贵 外派别人执行。 你只负责定位问题,但是明确告诉管理员 cpu类型

lscpu

lscpu | grep 'Model name' Model name: Intel(R) Xeon(R) Platinum 8255C CPU @ 2.50GHz

Model name: Hygon C86 7285

名称

在海光CPU系统中的典型值或特征

解释说明

架构 (Architecture)

x86_64

这表明海光CPU采用x86_64指令集,兼容主流的64位操作系统和软件

厂商 ID (Vendor ID)

HygonGenuine

这是识别海光处理器最直接的标志

CPU 系列 (CPU family)

具体数值(如24)

海光CPU特定的家族编号。

型号 (Model) / 型号名称

具体数值 / Hygon C86 XXX

指明CPU的具体型号,例如Hygon C86 7185或7285等

疑问 没有调试符号怎么办?

查看所有线程 (gdb) info threads Id Target Id Frame 1 Thread 0x7ffff7fdb740 (LWP 1234) "main" 0x00007ffff7fab4f3 in __libc_start_main () 2 Thread 0x7ffff7fda700 (LWP 1235) "worker" 0x00007ffff7fc1e2d in nanosleep ()

切换到线程2并查看寄存器 (gdb) thread 2 (gdb) info registers

一次性查看所有线程的寄存器状态 (gdb) thread apply all info registers

Thread 1 (Thread 0x7ffff7fdb740 (LWP 1234)): rax 0x0 0 rbx 0x7fffffffe0a8 140737488347304 ...

Thread 2 (Thread 0x7ffff7fda700 (LWP 1235)): rax 0xfffffffffffffdfc -516 rbx 0x7ffff7fda700 140737353928448 ...

问题来了:只有寄存器 怎么和变量结合起来?什么请看使用寄存器呢

隐藏知识:对cpu 而言 每个变量存储寄存器上,寄存器存储变量地址

变量名本质是程序员给某块内存或寄存器起的易记名字

info args

打印函数参数

info locals

打印当前栈帧的局部变量

print variable_name

打印变量值

为什么反汇编(无调试信息)

disassemble → 分析变量对应的寄存器 → 通过寄存器获取值

举例:

通过反汇编分析变量-寄存器关系

  1. 反汇编当前函数 (gdb) disassemble /m main Dump of assembler code for function main:
  2. 从汇编中解读变量位置:
代码语言:javascript
复制
# 分析上面的反汇编输出:
# - 变量 a: 存储在 [rbp-4],加载到 edx 寄存器
# - 变量 b: 存储在 [rbp-8],加载到 eax 寄存器  
# - 变量 c: 计算结果存储在 eax,然后保存到 [rbp-12]

# 2. 查看当前寄存器值
(gdb) info registers rbp eax edx
rbp            0x7fffffffe0e0      0x7fffffffe0e0
eax            0x1e                30
edx            0xa                 10

# 3. 通过寄存器获取变量值
(gdb) print $eax
$1 = 30
(gdb) print $edx
$2 = 10

# 4. 通过内存地址查看变量
(gdb) x/wd $rbp-4    # 查看变量 a (4字节整数)
0x7fffffffe0dc: 10
(gdb) x/wd $rbp-8    # 查看变量 b
0x7fffffffe0d8: 20
(gdb) x/wd $rbp-12   # 查看变量 c
0x7fffffffe0d4: 30

上面操作太复杂了 相关插件

gdb.gdbinit

代码语言:javascript
复制
# 保存到 ~/.gdbinit
define simple
  info registers
  info locals  
  info args
  where
end

# 使用
(gdb) simple

第三步:确定为什么core

前面说过 通过core 不能解决问题,

只能发现问题, 必须拿出足够证据证明 为什么core

gdb bt 基本查看core的位置。

请一定相信 当前位置core位置,不考虑多线程是否其他堆栈上。

其实没有那么容易

空指针:

疑问:gdb print 变量 只查看简单变量,遇到复杂的 查看stl 链表,红黑树 复杂结构?

GDB如何优化显示c++ STL数据结构的值 gdb配置打印STL容器脚本pretty printer 参考https://zhuanlan.zhihu.com/p/662099267

引用技术断言错误

请相信 gdb core 位置一定正确的,但是如何解决 需要业务十分了解

总结

  1. gdb 通过堆栈信息确定core位置 和core相关参数,这个快速确定方向,
  2. 剩余全部对业务理解

本文重点:变量---地址--寄存器 是隐藏基本知识

为什么这么说 如果gdb 产生10G文件 被禁止后

怎么产生一个文件 记录这些信息呢

Core文件本质上是程序崩溃瞬间的完整内存镜像,包含:

  • 所有变量值及其内存地址
  • CPU寄存器状态
  • 堆栈信息
  • 内存映射关系
  • 动态链接库信息

历史文章:

序号

知识地图

题目

1

网络

判断一个端口是否可用

2

网络

epoll不支持文件IO,kqueue怎么做到的

3

并发

Redis 单线程为什这么快

4

数据结构

什么是跳表(Skip List)

5

数据库

如何把一个文件系统目录树存储到数据库

6

并发

从一道面试题谈linux下fork的运行机制

7

并发

close-on-exec机制

8

数据结构

LRU缓存

9

分布式

什是线性一致性

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-11-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 后端开发成长指南 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 第一步:确定哪个服务产生core
  • 第二步:确定是否加载调试符号
  • 第三步:确定为什么core
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档