envoy 是目前高性能数据平面的基本标准了,虽然有些看着笨重,但是社区牛逼,其次性能也很高,目前大部分公司的mesh基本都是通过envoy构建的,所以学习是很重要的,本人主要是介绍如何debug envoy,本人也是踩坑了大半天!
背景
envoy 是目前高性能数据平面的基本标准了,虽然有些看着笨重,但是社区牛逼,其次性能也很高,目前大部分公司的mesh基本都是通过envoy构建的,所以学习是很重要的,本人主要是介绍如何debug envoy,本人也是踩坑了大半天!
C++的代码最难的就是主流的IDE工具对代码阅读、调试难度比较大,这几本就挡住了大部分人的学习动力,其中clion对于cmake支持度很好,vscode是比较方便和灵活,可以远程直接debug,一般debug c++的流程就是先要编译成一个二进制产物,通过 gdb/lldb 进行debug。envoy 默认在linux上构建是用clang编译的,debug的话最好用lldb!
环境
- 本地开发环境是 Mac
- 远程开发环境是 Linux(Debian10, 8C+16G, 公司有32c+64g的啥时候我申请个,真的是不好意思😬)【如果你本地机器性能高可以不用远程,直接本地起个docker就行了】
- 编译环境是远程的Docker (vscode remote 也在这里运行)
- envoy - v1.26.0 (构建环境是 clang/lldb 14.0.0,clang比gcc构建要快很多….)
- 本地 vscode
注意:
- envoy这种大型项目它对于环境依赖太重了,所以千万别用本地环境去构建,基本行不通! 
- c++ debug对于环境一致性要求很高 
- 我本来想试试 lldbserver/gdbserver 用 clion 进行 remote debug,发现人家产物1.4个G,下载elf太墨迹了,所以还是直接在docker容器内调试算了 
调试流程
修改脚本
- run_envoy_docker.sh
- 配置 http代理,不然拉代码太墨迹了,自己找http/https代理
- 配置docker run 添加参数 --cap-add=SYS_PTRACE --security-opt seccomp=unconfined支持调试
- docker 最好限制下 cpu,防止编译把电脑cpu打满了,直接挂了!
- 修改bazel cache的挂载目录: DEFAULT_ENVOY_DOCKER_BUILD_DIR=${HOME}/.cache/bazel_docker(默认是在/temp 目录下重启电脑就没了)
- build_setup.sh脚本注释掉 (防止把构建产物给删了)
| 12
 
 | #cleanup#trap cleanup EXIT
 
 | 
3.do_ci.sh 注释掉 bazel_binary_build 的一些内容

进入容器
| 1
 | ./ci/run_envoy_docker.sh '/bin/bash'
 | 
构建
执行./ci/do_ci.sh bazel.debug.server_only 即可, 首次构建基本上得两个小时左右,后面增量构建基本上2分钟左右!
| 12
 
 | # 这里可以看到 --config=libc++ 实际上就是clang/usr/local/bin/bazel --output_user_root=/build/tmp/output build --verbose_failures --experimental_generate_json_trace_profile --test_output=errors --repository_cache=/build/repository_cache --experimental_repository_cache_hardlinks --action_env=CLANG_FORMAT --test_tmpdir=/build/tmp --config=libc++ --remote_download_toplevel -c dbg //source/exe:envoy-static
 
 | 

最后自己把 cache 文件压缩一下,备份一份,防止手残给删了。。。。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 
 | envoybuild@a66c8f90a687:/source$ ls -al bazel-bin/source/exe/total 1381592
 drwxrwxrwx 4 envoybuild envoybuild       4096 Aug 19 15:05 .
 drwxrwxrwx 6 envoybuild envoybuild       4096 Aug 19 13:18 ..
 -r-xr-xr-x 1 envoybuild envoybuild      56844 Aug 19 13:18 envoy_common_lib.cppmap
 -r-xr-xr-x 1 envoybuild envoybuild       2096 Aug 19 13:18 envoy_main_common_lib.cppmap
 -r-xr-xr-x 1 envoybuild envoybuild       1954 Aug 19 13:18 envoy_main_entry_lib.cppmap
 -r-xr-xr-x 1 envoybuild envoybuild 1413995968 Aug 19 15:05 envoy-static
 -r-xr-xr-x 1 envoybuild envoybuild     632368 Aug 19 10:40 envoy-static-2.params
 drwxrwxr-x 3 envoybuild envoybuild       4096 Aug 19 15:03 envoy-static.runfiles
 -r-xr-xr-x 1 envoybuild envoybuild        141 Aug 19 10:41 envoy-static.runfiles_manifest
 -r-xr-xr-x 1 envoybuild envoybuild       3546 Aug 19 13:18 main_common_lib.cppmap
 drwxrwxr-x 8 envoybuild envoybuild       4096 Aug 19 15:04 _objs
 -r-xr-xr-x 1 envoybuild envoybuild       1501 Aug 19 14:36 platform_header_lib.cppmap
 -r-xr-xr-x 1 envoybuild envoybuild       1613 Aug 19 13:18 platform_impl_lib.cppmap
 -r-xr-xr-x 1 envoybuild envoybuild       1803 Aug 19 14:36 platform_impl_lib_linux.cppmap
 -r-xr-xr-x 1 envoybuild envoybuild       2275 Aug 19 13:18 process_wide_lib.cppmap
 -r-xr-xr-x 1 envoybuild envoybuild       1264 Aug 19 13:18 scm_impl_lib.cppmap
 -r-xr-xr-x 1 envoybuild envoybuild       1863 Aug 19 13:18 terminate_handler_lib.cppmap
 
 | 
调试
envoy 核心用的libevent,所以大量回掉代码,阅读调试比较困难!
- 支持调试本地代码

- 支持调试依赖代码

- 本地下载 vscode 插件
- Remote - SSH 可以连接远程虚拟机
- Dev Containers 连接连接服务器内的docker容器
- 远程连接后下载vscode插件 CodeLLDB 
- 配置 - /.vscode/launch.json文件中配置
 
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 
 | {"version": "0.2.0",
 "configurations": [
 {
 "type": "lldb",
 "request": "launch",
 "name": "Launch",
 "program": "/source/bazel-bin/source/exe/envoy-static",
 "args": [],
 "cwd": "/source",
 "sourceMap":{
 "/proc/self/cwd": "/source",
 "/proc/self/cwd/external": "/build/tmp/output/b570b5ccd0454dc9af9f65ab1833764d/execroot/envoy/external",
 }
 }
 ]
 }
 
 | 
- 挂载点是,自行查看自己的挂载点 bazel-source 目录就是bazel的构建目录
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 
 | envoybuild@82990b41dce5:/source$ ls -altotal 464
 drwxr-xr-x 29 envoybuild envoybuild  4096 Aug 19 10:08 .
 drwxr-xr-x  1 root       root        4096 Aug 19 10:23 ..
 drwxr-xr-x  9 envoybuild envoybuild  4096 Aug 19 05:23 api
 -rw-r--r--  1 envoybuild envoybuild     6 Aug 19 05:23 API_VERSION.txt
 drwxr-xr-x  3 envoybuild envoybuild  4096 Aug 19 05:23 .azure-pipelines
 -rw-r--r--  1 envoybuild envoybuild  2298 Aug 19 05:23 BACKPORTS.md
 drwxr-xr-x  8 envoybuild envoybuild  4096 Aug 19 05:23 bazel
 lrwxrwxrwx  1 envoybuild envoybuild    86 Aug 19 06:08 bazel-bin -> /build/tmp/output/b570b5ccd0454dc9af9f65ab1833764d/execroot/envoy/bazel-out/k8-dbg/bin
 drwxr-xr-x  2 envoybuild envoybuild  4096 Aug 19 05:23 .bazelci
 -rw-r--r--  1 envoybuild envoybuild   152 Aug 19 05:23 .bazelignore
 lrwxrwxrwx  1 envoybuild envoybuild    75 Aug 19 06:08 bazel-out -> /build/tmp/output/b570b5ccd0454dc9af9f65ab1833764d/execroot/envoy/bazel-out
 -rw-r--r--  1 envoybuild envoybuild 19921 Aug 19 05:23 .bazelrc
 lrwxrwxrwx  1 envoybuild envoybuild    65 Aug 19 06:08 bazel-source -> /build/tmp/output/b570b5ccd0454dc9af9f65ab1833764d/execroot/envoy
 lrwxrwxrwx  1 envoybuild envoybuild    91 Aug 19 06:08 bazel-testlogs -> /build/tmp/output/b570b5ccd0454dc9af9f65ab1833764d/execroot/envoy/bazel-out/k8-dbg/testlogs
 -rw-r--r--  1 envoybuild envoybuild     6 Aug 19 05:23 .bazelversion
 -rw-r--r--  1 envoybuild envoybuild  1454 Aug 19 05:23 BUILD
 
 | 
- 调试官方demo https://www.envoyproxy.io/docs/envoy/latest/start/quick-start/run-envoy
| 1
 | wget https://www.envoyproxy.io/docs/envoy/latest/_downloads/92dcb9714fb6bc288d042029b34c0de4/envoy-demo.yaml
 | 
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 
 | {"version": "0.2.0",
 "configurations": [
 {
 "type": "lldb",
 "request": "launch",
 "name": "Launch",
 "program": "/source/bazel-bin/source/exe/envoy-static",
 "args": [
 "-c",
 "/source/envoy-demo.yaml"
 ],
 "cwd": "/source",
 "sourceMap":{
 "/proc/self/cwd": "/source",
 "/proc/self/cwd/external": "/build/tmp/output/b570b5ccd0454dc9af9f65ab1833764d/execroot/envoy/external",
 }
 }
 ]
 }
 
 | 
- 调试, 浏览器可以打开 http://localhost:10000/(vscode yyds 支持转发端口)
bazel 基本用法
- 这里我用的clang,不太喜欢用gcc, bazel的话直接下载 https://github.com/bazelbuild/bazelisk ,他可以自动下载对应的bazel版本,根据项目里的.bazelversion
| 12
 3
 4
 5
 
 | ~ which clang++/usr/lib/llvm-13/bin/clang++
 
 ~ which bazel # https://github.com/bazelbuild/bazelisk/releases
 /home/fanhaodong.516/go/bin/bazel
 
 | 
- 脚本
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 
 | .PHONY: fastbuild optbuild debug clean
 all: fastbuild
 
 fastbuild: # 快速构建
 bazel build --config clang //:main
 
 optbuild: # 优化构建
 bazel build --config clang -c opt //:main
 bazel build --config clang -c opt //:main.dwp
 ls -al bazel-bin/
 
 clean: # 清理bazel此项目的构建缓存
 bazel clean
 
 debug: # debug构建, --subcommands 可以查看构建参数,非常有用排查问题。  make debug 2>&1 | tee out.log
 rm -rf bazel-bin
 bazel build --config clang -c dbg  //:main --subcommands
 bazel build --config clang -c dbg  //:main.dwp --subcommands
 ls -al bazel-bin/
 
 | 
- .bazelrc文件配置构建参数
| 12
 3
 4
 5
 6
 
 | build --cxxopt=-std=c++14 --host_cxxopt=-std=c++14build:linux --features=per_object_debug_info
 build:linux --fission=dbg,opt
 
 build:clang --config=linux
 build:clang --action_env=CC=clang --action_env=CXX=clang++
 
 | 
- .bazelversion配置bazel版本
- CodeLLDB 配置 lldb脚本 .vscode/launch.json文件
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 
 | {"version": "0.2.0",
 "configurations": [
 {
 "type": "lldb", // 下同
 "request": "custom",
 "name": "Custom launch",
 "targetCreateCommands": [
 "target create /home/fanhaodong.516/go/src/github.com/anthony-dong/bazel_simple/bazel-bin/main",
 "setting append target.source-map /proc/self/cwd /home/fanhaodong.516/go/src/github.com/anthony-dong/bazel_simple",
 "setting append target.source-map /proc/self/cwd/external /home/fanhaodong.516/.cache/bazel/_bazel_fanhaodong.516/a3fbbe1bc80076bc1aaa5a9834db2f5d/execroot/bazel_simple/external"
 ],
 "processCreateCommands": [
 "settings set target.run-args 1 '2 3' '4 5'",
 "process launch"
 ]
 },
 {
 "type": "lldb",
 "request": "launch",
 "name": "Launch",
 "program": "/home/fanhaodong.516/go/src/github.com/anthony-dong/bazel_simple/bazel-bin/main", // 执行文件路径
 "args": [ // 配置执行文件启动参数
 "ls",
 "-al"
 ],
 "cwd": "/home/fanhaodong.516/go/src/github.com/anthony-dong/bazel_simple", // 代码路径
 "sourceMap": {
 "/proc/self/cwd": "/home/fanhaodong.516/go/src/github.com/anthony-dong/bazel_simple", // 文件map,第一个必须(bazel在linux下构建 PWD=/proc/self/cwd,强制的)
 "/proc/self/cwd/external": "/home/fanhaodong.516/.cache/bazel/_bazel_fanhaodong.516/a3fbbe1bc80076bc1aaa5a9834db2f5d/execroot/bazel_simple/external", // 次要配置,看看你需不需要debug依赖,可以配置多个
 }
 }
 ]
 }
 
 | 
bazel - fission模式
这个比较坑,需要深入了解下,不然debug的话会是噩梦,可以自己写个小项目试试!
- bazel 构建模式:https://bazel.build/docs/user-manual#compilation-mode , 默认是fastbuild
- bazel 调试模式:https://bazel.build/docs/user-manual#strip
| 12
 
 | # 还可以手动再精简 。。。strip bazel-bin/main -o ./main
 
 | 
- fission 模式 https://bazel.build/docs/user-manual#fission
| 12
 3
 4
 5
 
 | # --features=per_object_debug_info 可选可不选了现在 (我的版本是 6.x)# fission 支持 dbg,opt,fastbuild,yes(all),no(none)
 # 只有开启了 fission 才能够支持 bazel build //:xxx.dwp
 build:linux --features=per_object_debug_info
 build:linux --fission=dbg,opt
 
 | 
- 构建文件
| 12
 3
 
 | bazel build --config clang -c dbg  //:main# 没开启 fission 这个执行了也没啥用... //:xxx.dwp 只在开启fission下生效
 bazel build --config clang -c dbg  //:main.dwp
 
 | 
- 未开启 fission (dbg) 构建
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 
 | drwxr-xr-x 5 fanhaodong.516 fanhaodong.516    4096 Aug 19 22:56 .drwxr-xr-x 4 fanhaodong.516 fanhaodong.516    4096 Aug 19 22:56 ..
 drwxrwxrwx 4 fanhaodong.516 fanhaodong.516    4096 Aug 19 22:56 external
 -r-xr-xr-x 1 fanhaodong.516 fanhaodong.516 1274544 Aug 19 22:56 main
 -r-xr-xr-x 1 fanhaodong.516 fanhaodong.516    3513 Aug 19 22:56 main-2.params
 -r-xr-xr-x 1 fanhaodong.516 fanhaodong.516     674 Aug 19 22:56 main.cppmap
 -r-xr-xr-x 1 fanhaodong.516 fanhaodong.516       0 Aug 19 22:56 main.dwp
 drwxr-xr-x 3 fanhaodong.516 fanhaodong.516    4096 Aug 19 22:56 main.runfiles
 -r-xr-xr-x 1 fanhaodong.516 fanhaodong.516     162 Aug 19 22:56 main.runfiles_manifest
 drwxr-xr-x 3 fanhaodong.516 fanhaodong.516    4096 Aug 19 22:56 _objs
 
 | 
- 开启 fission (opt) 明显能看出来可执行文件大小降低了不少 1274544 -> 396626
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 
 | ls -al bazel-bin/total 1676
 drwxr-xr-x 5 fanhaodong.516 fanhaodong.516    4096 Aug 19 23:00 .
 drwxr-xr-x 4 fanhaodong.516 fanhaodong.516    4096 Aug 19 23:00 ..
 drwxr-xr-x 4 fanhaodong.516 fanhaodong.516    4096 Aug 19 23:00 external
 -r-xr-xr-x 1 fanhaodong.516 fanhaodong.516  396626 Aug 19 23:00 main
 -r-xr-xr-x 1 fanhaodong.516 fanhaodong.516    3411 Aug 19 23:00 main-2.params
 -r-xr-xr-x 1 fanhaodong.516 fanhaodong.516     674 Aug 19 23:00 main.cppmap
 -r-xr-xr-x 1 fanhaodong.516 fanhaodong.516 1285592 Aug 19 23:00 main.dwp
 drwxr-xr-x 3 fanhaodong.516 fanhaodong.516    4096 Aug 19 23:00 main.runfiles
 -r-xr-xr-x 1 fanhaodong.516 fanhaodong.516     162 Aug 19 23:00 main.runfiles_manifest
 drwxr-xr-x 3 fanhaodong.516 fanhaodong.516    4096 Aug 19 23:00 _objs
 
 | 
- 开启fission (dbg) 1274544 -> 834808
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 
 | total 1808drwxr-xr-x 5 fanhaodong.516 fanhaodong.516   4096 Aug 19 23:00 .
 drwxr-xr-x 4 fanhaodong.516 fanhaodong.516   4096 Aug 19 23:00 ..
 drwxr-xr-x 4 fanhaodong.516 fanhaodong.516   4096 Aug 19 23:00 external
 -r-xr-xr-x 1 fanhaodong.516 fanhaodong.516 834808 Aug 19 23:00 main
 -r-xr-xr-x 1 fanhaodong.516 fanhaodong.516   3529 Aug 19 23:00 main-2.params
 -r-xr-xr-x 1 fanhaodong.516 fanhaodong.516    674 Aug 19 23:00 main.cppmap
 -r-xr-xr-x 1 fanhaodong.516 fanhaodong.516 980664 Aug 19 23:00 main.dwp
 drwxr-xr-x 3 fanhaodong.516 fanhaodong.516   4096 Aug 19 23:00 main.runfiles
 -r-xr-xr-x 1 fanhaodong.516 fanhaodong.516    162 Aug 19 23:00 main.runfiles_manifest
 drwxr-xr-x 3 fanhaodong.516 fanhaodong.516   4096 Aug 19 23:00 _objs
 
 | 
- 总结 最好别开,支持度不太好,所以看到 --fission 参数或者bazelrc文件中配置了,请立马注释掉关闭了!!!
bazel - .bazelrc
一旦修改这个文件就得重新构建
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 
 | # 配置c++版本build --cxxopt=-std=c++14 --host_cxxopt=-std=c++14
 
 # 配置 build 的构建参数(当config为linux时)
 # 可以看上面解释
 build:linux --features=per_object_debug_info
 # build:linux --fission=dbg,opt
 build:linux --fission=no
 
 # --config=linux 继承配置linux的,可以配置多个 --config 。
 build:clang --config=linux
 
 # config=clang时 cc/gcc 为 clang / clang++
 # --action_env 主要clang 构建时传递的env参数
 build:clang --action_env=CC=clang --action_env=CXX=clang++
 # 可配可不配吧,假如clang路径下有ld.lld既不需要配置
 # build:clang --linkopt=-fuse-ld=lld
 
 # config=gcc的构建
 build:gcc --action_env=CC=gcc --action_env=CXX=g++
 
 | 
参考