使用vscode|使用vscode Container开发调试envoy

由于我最近在研究 envoy 这个项目,这是个cpp的项目,对于我这种cpp新人来说还是比较有压力的,感觉处处都是坑,开个引导文章记录一下。
如果要研究 envoy 项目源码,那肯定是需要代码跳转的,但是如果用 clion 打开,那么你会发现 envoy 是用bazel 构建的,没有CMakeLists.txt无法跳转,bazel-cmakelists 这个工具也已经几年都没迭代了,根本用不了。所以按照官方推荐的使用 vscode 来进行构建开发。
在 envoy 这个项目里面,由于运行环境是基于ubuntu的docker环境跑的,所以提供了vscode container 这种模式给我们开发者进行开发调试。
看了一下 envoy 的开发文档,感觉貌似使用起来是很简单的,但是有些地方踩坑也让我浪费了不少时间。
开发环境的构建 创建 dev container环境
【使用vscode|使用vscode Container开发调试envoy】首先,我们需要在我们的机器上安装好 docker desktop,然后用vscode打开我们的envoy项目,打开 envoy/.devcontainer/devcontainer.json 文件,这个时候 vscode 会弹出如下提示:
使用vscode|使用vscode Container开发调试envoy
文章图片

然后我们点击 Reopen in Container 即可加载构建 vscode Container 开发环境。但是有些小伙伴说,不小心把这个提示关了,怎么手动打开呢?
在mac里我们可以按下:command+shift+p,然后输入 reopen:
使用vscode|使用vscode Container开发调试envoy
文章图片

生成相应的依赖文件
然后进入到容器内部之后,需要 Refresh Compilation Database ,也就是运行 tools/vscode/refresh_compdb.sh脚本,这个脚本会帮我们生成代码完成的所有依赖项,例如 protobuf 生成的代码、外部依赖项。
但是直接运行的话,会报错:
使用vscode|使用vscode Container开发调试envoy
文章图片

然后我去看官方文档VSCode Remote - Containers,文档里面和我说一般需要把devcontainer.json 的里面的 remoteUser 设置为 root, 然后我又重新构建了几次,都是直接卡死,原因不明。
然后我跑到宿主机给 vscode 这个用户加权限,结果是找不到这个用户。后面我幡然醒悟,这个权限命令应该在容器内部执行才可以:

# 这个命令需要在容器内部执行 sudo chown -R vscode /workspaces

然后再运行 tools/vscode/refresh_compdb.sh脚本 ,ok了,没有报错。然后检查生成的 complie_commands.json文件也没有问题。
使用vscode|使用vscode Container开发调试envoy
文章图片

我们再检查一下代码可以正常跳转,并且没有报错了。
开发环境进行envoy调试 当然,除了让我们的开发环境的代码能够跳转其实还不够,最好是可以进行代码的调试,下面我们就看看怎么调试 envoy。
配置一个demo yaml
在代码的 config 下面其实有很多 yaml 模板,可以随便拿一个出来放到envoy根目录下面,我这里也给一个 yaml 例子:
admin: access_log_path: /tmp/admin_access.log address: socket_address: protocol: TCP address: 0.0.0.0 port_value: 9901 static_resources: listeners: - name: listener_0 address: socket_address: protocol: TCP address: 0.0.0.0 port_value: 10001 filter_chains: - filters: - name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager scheme_header_transformation: scheme_to_overwrite: https stat_prefix: ingress_http route_config: name: local_route virtual_hosts: - name: local_service domains: ["*"] routes: - match: prefix: "/" route: host_rewrite_literal: www.envoyproxy.io cluster: service_envoyproxy_io http_filters: - name: envoy.filters.http.router clusters: - name: service_envoyproxy_io connect_timeout: 30s type: LOGICAL_DNS # Comment out the following line to test on v6 networks dns_lookup_family: V4_ONLY lb_policy: ROUND_ROBIN load_assignment: cluster_name: service_envoyproxy_io endpoints: - lb_endpoints: - endpoint: address: socket_address: address: www.envoyproxy.io port_value: 443 transport_socket: name: envoy.transport_sockets.tls typed_config: "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext sni: www.envoyproxy.io

生成 vscode 调试文件
在根目录下运行下面命令:
tools/vscode/generate_debug_config.py //source/exe:envoy-static --args "-c envoy.yaml"

上面 --args 参数里面填的就是我们上面的 yaml 文件,这个编译等待的过程是十分漫长的,我 8C16G 的机器差不多花了我1个小时才弄好。
运行好之后,可以看到帮我们生成好了 launch.json 文件:
使用vscode|使用vscode Container开发调试envoy
文章图片

调试
然后我们按 F5 发现可以进入到我们的 mian 函数的断点中,没有什么问题:
使用vscode|使用vscode Container开发调试envoy
文章图片

到此为止,我们的 envoy 开发调试为一体的集成环境就打造好了,小伙伴们可以快乐的阅读源码了。
使用vscode|使用vscode Container开发调试envoy
文章图片

    推荐阅读