使用VSCode作为Chromium的调试前端

本文约 1300 字,阅读需 3 分钟。

之前试过VSCode作为C++工程的开发工具,但如果工程过于庞大,每次打开都会卡死在索引阶段。 总的来说,NeoVim+Clangd是我认为通用性、性能、开发体验综合最好的选择。

但有一个问题,怎么调试?

无论代码是本地还是在服务器(我是放在服务器,毕竟本地的CPU和硬盘资源都更宝贵),由于IDE打开这种规模的工程都很容易卡死,所以看起来只能用LLDB的命令行了?

体验如下图:

pic

总结:

  1. 卡顿是不存在的,毕竟不会像IDE那样把Indexing作为打开工程进行Debug的强行环节
  2. 难用是真的难用,有些场景我是力推Terminal的,但Debug是真的不行,具体表现如下:
    1. 设置断点之类的操作非常麻烦,不如GUI点选来的直观和方便。另外,如果文件被编辑了,还要手动更新断点(如果是指定行),GUI基本会自动修改。
    2. Step In / Step Out / Next 之类的操作不直观,只能看前后几行代码,GUI可以看更多的上下文。
    3. 查看变量不方便,原子类型、类变量、数组变量等,查看语法不一样
    4. 屏幕利用率低,Call Stack、Variable List、代码等不能很好的协同显示。

于是,想着能不能把VSCode作为一个单纯的Debugger呢?实践如下:

首先把VSCode相关的C/C++插件禁用,不然打开Chromium时工程这些插件就会开始作妖,导致VSCode闪退。

再写下launch.json,如下:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Debug LatinPunctuation",
            "type": "lldb",
            "request": "launch",
            "program": "${workspaceFolder}/src/out/Default/blink_platform_unittests",
            "args": ["--", "--gtest_filter=TextBreakIteratorTest.LatinPunctuation"],
            "cwd": "${workspaceFolder}/src"
        }
    ]
}

注:Chromium的构建是在命令行单独完成的。这里直接运行产物,并指定要调试的单测,如果不指定,这个文件有几千个单测,Debug效率太低。

运行之后报错:

Console is in 'commands' mode, prefix expressions with '?'.
Could not resolve any locations for breakpoint at /data/research/chromium/src/third_party/blink/renderer/platform/text/text_break_iterator_test.cc:128, but found a valid location at ../../third_party/blink/renderer/platform/text/text_break_iterator_test.cc:128
Launching: /data/research/chromium/src/out/Default/blink_platform_unittests -- --gtest_filter=TextBreakIteratorTest.LatinPunctuation
Launched process 589677
Process exited with code 0.

这个问题可以参考:

直观来说,就是ninja构建是从out/Default发起的,src在生成符号阶段相对构建路径就是../..,添加sourceMap就可以了。

"sourceMap": { "../..":"/data/research/chromium/src" }

这个问题,用lldb命令行的时候,也可以复现,如下(如果只写文件名,则会自动解析成可用的路径):

(lldb) breakpoint set --file text_break_iterator_test.cc --line 128
Breakpoint 3: where = blink_platform_unittests`blink::TextBreakIteratorTest_LatinPunctuation_Test::TestBody() + 171 at text_break_iterator_test.cc:128:51, address = 0x00005555577769fb
(lldb) breakpoint set --file /data/research/chromium/src/third_party/blink/renderer/platform/text/text_break_iterator_test.cc --line 128
Breakpoint 4: no locations (pending).
WARNING:  Unable to resolve breakpoint to any actual locations.
(lldb) breakpoint set --file ../../third_party/blink/renderer/platform/text/text_break_iterator_test.cc --line 128
Breakpoint 5: where = blink_platform_unittests`blink::TextBreakIteratorTest_LatinPunctuation_Test::TestBody() + 171 at text_break_iterator_test.cc:128:51, address = 0x00005555577769fb

最终效果如下,比命令行LLDB效率高多了:

pic

总结:

  • 对于工具来说,要在使用体验功能强大之间选择一个平衡
  • 大型项目的构建/编辑/调试是不太适合用IDE解决的,毕竟规模和复杂度在那里,还有兼容性的考虑
  • 构建是基础:
    • 生成的compile_command.json用于编辑器的索引基础
    • 生成的Debug Symbol用于调试
  • CLion有个功能,能单独运行某个测试用例,我觉得非常好用,因为一般开发的时候,都只关心某几个测试,其他的完全没必要运行,其底层其实就是基于gtest_filter实现的,这里的launch.json也做到了同样的功能。
  • 可以看到,要想拥有一个功能足够,且体验较好的开发环境,离不开对底层原理的必要理解
总阅读量次。