コンテンツにスキップ

最終更新: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 戦略ではなく、依存関係とリンクされることを意味します。

build --spawn_strategy=local

これでコードが見えるようになりました。

* 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 はアセンブリしか見せられません。

次のように切り替えます:

build --spawn_strategy=local

これは、コンパイルアクションがサンドボックスに入らずローカルマシンで直接実行されることを意味します。シンボル情報は完全に保持され、ブレークポイントが正しくソース行に落ちるようになります。プロジェクトの .bazelrc に直接書き込んで一労永逸にすることをおすすめします:

build --spawn_strategy=local
build --compilation_mode=dbg   # 调试构建记得带 -c dbg

(1)デバッグ時は bazel build -c dbg //... または bazel run -c dbg を使い、必ず -O0 -g を付ける;

(2)Linux ではデフォルトのサンドボックスは通常デバッグシンボルに影響しません。この問題は主に macOS で起こります;

(3)それでもソースが見えない場合は dSYM を確認してください:dsymutil ./hello_world && lldb ./hello_world。

これで Bazel + LLDB は快適に協力できます。他の罠を踏んだ方はコメント欄での補足をお願いします〜

関連トピック

コメント