最終更新:2026-10-12
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 なので、これを無効化する必要があります。ここでは 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 スポーン戦略は**サンドボックス**内でコンパイルアクションを実行します。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++那些事