使用Bazel在MacOS上构建的C++代码调试无法正常工作

4
我已经在使用Bazel构建系统的Visual Studio Code中开始了一个C++项目。但是,当使用Bazel构建二进制文件时,IDE中的调试功能无法正常工作。
当使用clang++ -g main.cpp -o sample构建应用程序时,我可以进行调试。
我的设置: 操作系统:MacOS,Bazel版本:release 0.17.2-homebrew,VS Code版本:1.27.2
这是由于Bazel编译的方式引起的。是否有任何解决方法使调试工作?
以下是一个最小化的示例。只需在编辑器中设置断点,运行调试,并观察断点未被命中:
├── .vscode
│   ├── launch.json
│   └── tasks.json
├── BUILD
├── WORKSPACE
├── main.cpp
└── sample.code-workspace

.vscode/launch.json

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(lldb) Launch",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceRoot}/bazel-bin/sample",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "externalConsole": false,
            "MIMode": "lldb",
            "preLaunchTask": "bazel build",
        }
    ]
}

.vscode/tasks.json

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "bazel build",
            "type": "shell",
            "command": "bazel",
            "args": [
                "build",
                "--compilation_mode=dbg",
                "sample"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            }
        }
    ]
}

BUILD

cc_binary(
    name = "sample",
    srcs = ["main.cpp"],
    visibility = ["//main:__pkg__"],
)

main.cpp

#include <iostream>

int main() {
    std::cout << "tests" << std::endl;
    return 0;
}

sample.code-workspace

{
    "folders": [ {"path": "."} ],
    "settings": {}
}

更新 1

尝试使用 lldb 调试 bazel 构建的可执行文件和手动构建的可执行文件:

bazel 构建的二进制文件 bazel build --compilation_mode=dbg sample

lldb bazel-bin/sample
(lldb) breakpoint set -n main
Breakpoint 1: 13 locations.
(lldb) r
Process 24391 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    frame #0: 0x00000001000021b0 sample`main
sample`main:
->  0x1000021b0 <+0>: pushq  %rbp
    0x1000021b1 <+1>: movq   %rsp, %rbp
    0x1000021b4 <+4>: subq   $0x20, %rsp
    0x1000021b8 <+8>: movq   0xe51(%rip), %rdi         ; (void *)0x00007fff9c93a660: std::__1::cout
Target 0: (sample) stopped.

手动构建二进制文件 clang++ -g main.cpp -o sample

lldb sample
(lldb) breakpoint set -n main
Breakpoint 1: where = sample`main + 29 at main.cpp:4, address = 0x0000000100000f9d
(lldb) r
Process 24410 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    frame #0: 0x0000000100000f9d sample`main at main.cpp:4
   1    #include <iostream>
   2    
   3    int main() {
-> 4        std::cout << "tests" << std::endl;
   5        return 0;
   6    }
Target 0: (sample) stopped.

在可执行文件中查找“调试笔记”(感谢此答案)后

nm -pa bazel-bin/sample | grep OSO
000000005bb7c96b - 03 0001   OSO /private/var/tmp/_bazel_teivaz/1e731ee5ae5a3ce6177976984318ec76/bazel-sandbox/1688134534644271312/execroot/__main__/bazel-out/darwin-dbg/bin/_objs/sample/main.o

我发现这些路径指向Bazel用于构建的沙箱环境。而且这个路径已经不可访问了。
这可能是由于Bazel的已知问题#5545引起的。

更新2

将Bazel更新到0.17.2版本(其中问题#5545已经解决),但仍存在此问题。


更新3

最终发现是Bazel的问题。我在这里创建了一个问题#6327


@Mark 我已经将纯Bazel命令添加到更新部分。 - Teivaz
所以实际问题是你没有调试符号?你说它“不起作用”,但在我看来,你似乎能够成功附加,尽管没有符号。 - Brad Allred
定义“不工作”对我来说完全不清楚。您没有提供任何错误信息。 - Brad Allred
@BradAllred 我认为在IDE中调试至少要命中断点才算是有效的工作。但这里并非如此。我进行了一些研究,并将其作为帖子的更新添加了进去——虽然可以附加调试器,但调试符号未正确映射到源代码,因此出现了问题。 - Teivaz
一个快速的提示:
  1. workspaceRoot 已被弃用,推荐使用 workspaceFolder
  2. 我使用 bazel 版本 4.0.0 进行了测试,似乎不再需要 --sandbox_debug=true 标志才能进行调试。
- sdevikar
显示剩余3条评论
3个回答

3
如果其他人也遇到了这个问题,以下方法对我有效(2022年3月):
.bazelrc文件:
build:debug -c dbg
build:debug --features=oso_prefix_is_pwd

然后使用以下命令进行构建:

bazel build --config debug //project/path:name
“.bazelrc”文件可以放在你的主目录下,也可以放在与bazel的“WORKSPACE”文件相同的目录下。

这真的有很大的区别!以前我无法让调试器停在任何断点,现在可以了。可悲的是,VSCode仍然无法加载源文件,显示错误:“SourceRequest”不受支持 - danielyan86129

2

(推广更新以回答): 看起来是一个已知问题: #6327


0
让GDB找到正确的文件。 < p > < code > .vscode / launch.json
{
    // ...
    "configurations": [
        {
            // ...
            "preLaunchCommands": [
                "directory ${workspaceFolder}" // or absolute path to your workspace
            ],
        }
    ]
}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接