最后更新:2026-10-13
Bazel 与 LLDB 联合调试¶
今天在调试时发现通过bazel编译出来的文件在mac上没法调试了,竟然全是汇编代码。
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x0000000100000fd0 hello_world`main
hello_world`main:
-> 0x100000fd0 <+0>: pushq %rbp
0x100000fd1 <+1>: movq %rsp, %rbp
0x100000fd4 <+4>: subq $0x60, %rsp
0x100000fd8 <+8>: movl $0x0, -0x4(%rbp)
(lldb) quit
如何解决呢?
默认是standalone,我们需要disable,这里采用local,这意味着输出将与其依赖项链接,而不是采用默认的standalone策略。
这样的话可以看到代码了。
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x0000000100000fdf hello_world`main at hello_world.cc:14:21
11
12 int main() {
13 // Create a thread pool
-> 14 auto threadPool = GetCpuThreadPool();
15 if (!threadPool) {
原理说明¶
为什么会这样?Bazel 默认的 standalone spawn 策略会在**沙箱**里跑编译动作,macOS 上的沙箱实现(sandbox-exec)会让 debug info 的路径、dSYM 生成出现偏差,最终二进制里符号表是残缺的,LLDB 只能给你看汇编。
切换成:
意思是编译动作直接在本机执行、不进沙箱,符号信息完整保留,断点就能正确落到源码行了。建议直接写进项目的 .bazelrc,一劳永逸:
(1)调试时用 bazel build -c dbg //... 或 bazel run -c dbg,确保带 -O0 -g;
(2)Linux 上默认沙箱一般不影响调试符号,这个问题主要出现在 macOS;
(3)如果还看不到源码,检查一下 dSYM:dsymutil ./hello_world && lldb ./hello_world。
这样 Bazel + LLDB 就能愉快地配合了。踩过别的坑欢迎留言区补充~
相关主题¶
- Bazel 构建 C++ 项目 | C++那些事
- CMake 入门与实战 | C++那些事
- Conan C++ 包管理入门 | C++那些事
- C++ Insights 编译期观察 | C++那些事
- C++ Jupyter Notebook 交互 | C++那些事
- C++ string 转 int | C++那些事
- C++ dbg-macro 调试宏 | C++那些事
- GCC 编译选项详解 | C++那些事
- GDB 调试 C++ 程序 | C++那些事
- GDB Python 扩展调试 | C++那些事