1. golang服务编译避坑

  • 现象:dlv 调试,p打印变量时无法正常打印,报错:Command failed: could not find symbol value for 变量
  • 解决方法:一定要加-gcflags "-N -l"参数(避面编译器内联和优化)
    go build -gflags “-N -l” -o main main.go

2. 生产环境go服务崩溃panic时自动生成core与调试

GO提供环境变量GOTRACEBACK,控制在panic时的行为。
2.1 增加系统变量 GOTRACEBACK(设置值为crash)
  • GOTRACEBACK=none 只输出panic异常信息

  • GOTRACEBACK=single 只输出被认为引发panic异常的那个goroutine的相关信息

  • GOTRACEBACK=all 输出所有goroutines的相关信息,除去与go runtime相关的stack frames.

  • GOTRACEBACK=system 输出所有goroutines的相关信息,包括与go runtime相关的stack frames,从而得知哪些goroutine是go runtime启动运行的

  • GOTRACEBACK=crash 与system的唯一区别是crash会生成coredump文件

2.2 设置系统参数ulimit

  • 第一步:在命令行执行ulimit -c,查看结果
  • 第二步:检查第一步命令执行结果,如果是unlimited,则到此结束,如果为0,则看第三步;
  • 第三步:执行ulimit -c unlimited,完成

2.3 设置core文件名和路径

2.3.1 查看当前core dump文件路径:

  • 方法1:
    cat /proc/sys/kernel/core_pattern
  • 方法2:
    /sbin/sysctl kernel.core_pattern

2.3.2 修改当前core dump文件路径:

方法1:临时修改:
修改/proc/sys/kernel/core_pattern文件,但/proc目录本身是动态加载的,每次系统重启都会重新加载,因此这种方法只能作为临时修改。
例:echo ‘/var/log/%e.core.%p’ > /proc/sys/kernel/core_pattern

方法2:永久修改:使用sysctl -w name=value命令。
例:/sbin/sysctl -w kernel.core_pattern=/var/log/%e.core.%p

为了更详尽的记录core dump当时的系统状态,可通过以下参数来丰富core文件的命名:
%% 单个%字符
%p 所dump进程的进程ID
%u 所dump进程的实际用户ID
%g 所dump进程的实际组ID
%s 导致本次core dump的信号
%t core dump的时间 (由1970年1月1日计起的秒数)
%h 主机名
%e 程序文件名

至此,可以成功生成core文件。

3. 调试core dump文件文件

  • 命令 dlv core main(服务名) main.core.123(core文件名)
    dlv命令此处不再赘述。