作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢!
背景
近两周被 AOT 编译的 C# 后端的各种诡异崩溃问题折磨。
后端程序直接 dotnet run xx.csproj 就很正常。
编译为 AOT 模式的单一二进制运行,就总是出现段错误崩溃或者抓不住的异常。
且,本地环境很难复现;而资源紧张的云上环境几乎必现。
且,云上的环境没有足够的调试工具,抓到崩溃现场比较麻烦。
为此,我把很多常见调试工具集成到一个镜像中,并以此镜像为后端服务程序运行的基础镜像,便可以轻松抓到崩溃现场。
下面把这个工具分享出来。
位置
- Github: https://github.com/ahfuzhang/CSharpDbgContainer
- Docker Hub: https://hub.docker.com/repository/docker/ahfuzhang/csharp-dbg-all-in-one/general
- 下载镜像:
- dotnet 10 sdk:
docker pull ahfuzhang/csharp-dbg-all-in-one:dotnet10 - dotnet 8 sdk:
docker pull ahfuzhang/csharp-dbg-all-in-one:dotnet8
- dotnet 10 sdk:
使用方法
以下是部署为 Deployment 的细节:
apiVersion: apps/v1
kind: Deployment
metadata:
name: csharp-backend
namespace: dev
labels:
app: csharp-backend
spec:
replicas: 1
selector:
matchLabels:
app: csharp-backend
template:
metadata:
labels:
app: csharp-backend
spec:
containers:
- name: csharp-backend
image: ahfuzhang/csharp-dbg-all-in-one:dotnet10
imagePullPolicy: Always
workingDir: /src/build/Release/linux/amd64/
volumeMounts:
- mountPath: /src/
name: src
readOnly: true
ports:
- containerPort: 8070
name: adminport
protocol: TCP
- containerPort: 8071
name: http1
protocol: TCP
- containerPort: 8072
name: http2
protocol: TCP
command:
- /usr/bin/DebugAdmin
- -admin.port=8070
- -log.stdout.output
- -coredump.unlimited
- -auto.restart
- -with.gdb
- -log.push.url= http://vlogs.logging.svc.cluster.local:9428/insert/jsonline?_time_field=_time ,Timestamp&_msg_field=Properties.Message,message&_stream_fields=kubernetes.pod_namespace,kubernetes.container_name,kubernetes.pod_name&ignore_fields=&decolorize_fields=&AccountID=0&ProjectID=0&debug=false&extra_fields=
- --
- ./csharp_backend
- -config.file=./csharp_backend.yaml
- -log.level=debug
- -log.flush.interval.ms=1000
- -log.buffer.size=4kb
- -log.global.tags=kubernetes.pod_namespace=dev&kubernetes.container_name=csharp-server&kubernetes.pod_name=$(POD_NAME)
- -http1.port=8071
- -http2.port=8072
- -cores=8
- -max.concurent.request.per.core=100000
- -metric.interval.ms=5000
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: HOST_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
resources:
limits:
cpu: 8
memory: 8Gi
requests:
cpu: 8
memory: 8Gi
terminationGracePeriodSeconds: 30
volumes:
- name: src
emptyDir: {}
管理程序
启动后端的时候,先启动管理程序,再由管理程序来启动后端
- 启动路径:
- /usr/bin/DebugAdmin
- 管理端口:可以通过浏览器访问这个端口
- -admin.port=8070
- 日志选项:
- -log.stdout.output: 使用这个选项时,把服务器的 stdout 的内容,再次输出到 DebugAdmin 的 stdout
- -log.push.url=http:// 如果后端部署了 VictoriaLogs,镜像中会启动 vector,然后采集日志,发送到 VictoriaLogs
-auto.restart: 如果被调试的进程崩溃,自动重新拉起-with.gdb: 使用 gdb 来启动被调试的进程--: 分隔符,分隔符之后,是需要调试的程序的命令行,及其参数
admin 管理界面

当被调试的程序发生崩溃时,如果启动时使用了 -with.gdb 参数,则 web ui 中会记录下崩溃的历史。
点击其中的链接,会看到堆栈、寄存器等崩溃时候的信息。
其他
Debug Container 还包含一下能力:
- 内置 vs code: 可以通过浏览器访问 IDE
- 可以通过 csharp debuger 查看堆栈信息
- 可以实时采集火焰图
- 可以通过内置的 coverage 工具看到实时的代码覆盖率
- see: CSharp 后端服务器如何做到:一边发请求一边看代码覆盖率, https://www.cnblogs.com/ahfuzhang/p/20474477

浙公网安备 33010602011771号