Debug Container All-In-One: 调试 C# 后端崩溃的利器

Posted on 2026-07-26 12:12  ahfuzhang  阅读(10)  评论(0)    收藏  举报

作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢!


背景

近两周被 AOT 编译的 C# 后端的各种诡异崩溃问题折磨。
后端程序直接 dotnet run xx.csproj 就很正常。
编译为 AOT 模式的单一二进制运行,就总是出现段错误崩溃或者抓不住的异常。

且,本地环境很难复现;而资源紧张的云上环境几乎必现。
且,云上的环境没有足够的调试工具,抓到崩溃现场比较麻烦。

为此,我把很多常见调试工具集成到一个镜像中,并以此镜像为后端服务程序运行的基础镜像,便可以轻松抓到崩溃现场。

下面把这个工具分享出来。

位置

使用方法

以下是部署为 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 管理界面

image

当被调试的程序发生崩溃时,如果启动时使用了 -with.gdb 参数,则 web ui 中会记录下崩溃的历史。
点击其中的链接,会看到堆栈、寄存器等崩溃时候的信息。

其他

Debug Container 还包含一下能力:

  • 内置 vs code: 可以通过浏览器访问 IDE
  • 可以通过 csharp debuger 查看堆栈信息
  • 可以实时采集火焰图
  • 可以通过内置的 coverage 工具看到实时的代码覆盖率