gdb断点未触发需检查是否编译带-g;core dump缺失通常因ulimit -c 0或core_pattern配置异常;调试vector时避免直接print v[100],应先确认size再用迭代器访问。

gdb 断点没触发?检查编译时是否带 -g
不加 -g,gdb 就看不到变量名、行号、函数名,断点只能打在地址上,实际等于“盲调”。哪怕只用 g++ main.cpp -o app 编译,gdb 里 break main 都可能失败或跳转错行。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 编译命令必须包含
-g,推荐加-O0关闭优化(尤其涉及内联、循环展开时,-O2下变量可能被优化掉) - 确认符号存在:
file app输出应含 “with debug_info”,readelf -S app | grep debug应列出多个.debug_*段 - 如果用 CMake,确保
set(CMAKE_BUILD_TYPE Debug)或手动传-DCMAKE_BUILD_TYPE=Debug
core dump 找不到?先看 ulimit -c 和 /proc/sys/kernel/core_pattern
程序段错误后没生成 core 文件,大概率不是代码问题,而是系统限制。Linux 默认可能设 ulimit -c 0,直接禁掉 core dump;或者 core_pattern 被重定向到 /dev/null 或某个不可写路径。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 临时放开:运行前执行
ulimit -c unlimited(注意是当前 shell 有效) - 查当前 pattern:
cat /proc/sys/kernel/core_pattern,常见值如core(当前目录)、core.%e.%p(带进程名和 pid) - 若 pattern 是管道(如
|/usr/share/apport/apport %p %s %c %d %P),core 不会落地为文件,需改回普通路径或关掉 apport
std::vector 迭代器失效?别在 gdb 里用 print v[100] 直接访问
gdb 的表达式求值器(特别是老版本)对 STL 容器支持有限。print v[100] 看似方便,但可能触发越界访问、引发二次 crash,或返回完全错误的值——因为 gdb 并不真正走 operator[] 的边界检查逻辑,而是按内存布局硬读。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 优先用
print v.size()和print v.capacity()确认范围,再用print *(v.begin() + 100)(前提是 100 - 启用 pretty printer:确认
~/.gdbinit加载了 Python 自带的 libstdc++ printers(GDB 7.7+ 默认启用,但某些嵌入式工具链可能缺失) - 对复杂结构体成员,避免
print obj.member.submember连写,分步print &obj.member查地址更稳
多线程卡死?info threads 和 thread apply all bt 必须一起用
单看主线程堆栈往往看不出问题。一个线程在 pthread_mutex_lock 卡住,另一个在 malloc 里等锁,第三个刚触发 SIGSEGV——不全量看,容易误判为“主线程崩溃”。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 停住后第一件事:
info threads看所有线程状态(R运行中、S睡眠、T已暂停),标出 ID - 挨个查堆栈:
thread apply all bt(简写taa bt),重点找futex_wait、__lll_lock_wait、sem_wait这类阻塞点 - 若某线程停在
nanosleep或epoll_wait,未必是问题,但若多个线程都卡在锁相关函数,基本就是死锁或资源争用
线程调度和信号处理的细节藏得很深,比如 sigwait 和 signal 混用、pthread_cancel 配置不当,都可能导致 gdb 看到的线程状态和实际行为错位——这时候得结合 /proc/PID/status 里的 State 和 voluntary_ctxt_switches 辅助判断。










