1、触发docker生成coredump文件
使用gcore -p pid -o dumpfile
常规情况下因为go语言不会生出coredump文件。gcore是gdb包中自带的工具
2、通过信号触发dockerd和containerd自己的dump stack功能
kill -s USR1 $(pidof dockerd)
上述命令可以将docker stack打印到docke的日志中。
docker打印的stack比较难看,必须通过格式梳理
3、gdb调试docker
1)对于docker-engine调试,因为编译时候使用了-ldflag “-w -s” ,其中-w的意思是生成最终的elf文件时候,无需dwarf调试信息,-s的意思剔除符号表。如果go build时刻加入了-ldflag “-w”,那么go编译出来的文件就无法用gdb调试。所以需要在docker-engine源码中有如下操作:
step1、docker-engine/Makefile里添加DOCKER_ENVS 添加-e DOCKER_DEBUG
step2、在docker-engine/hack/make.sh里检查有如下行:
if [ -z DOCER_DEBUG ]; then
LDFLAG="-w"
fi
2)在gdb attach到golang进程时刻,gdb都会提示要求加载runtime.py运行如下命令后,可以进行gdb golang调试了:
Source /usr/lib/golang/src/runtime/runtime-gdb.py
3)gdb可以对进程组进行调试,但是它默认不会attach到子进程中,所以如果需要对子进程进行调试可以通过如下方式:
set follow-fork-mode child //开启子进程调试
set detach-on-fork off //开启子进程调试时刻,也可以切换到主进程中
info inferiors可以看到当前的进程组中进程的情况,通过inferior id号可以像切换线程一样切换到进程组中进程。
4、dlv工具调试docker
dlv是当前比较好用的golang调试工具,相比较gdb,它可以看到goroutine,这就是巨大的优势。但是较gdb它却不能进行子进程调试,所以两个调试工具结合起来最好。
5、修改docker的配置文件daemon.json后重新加载docker
kill -SIGHUP $(pidof dockerd)
网友评论