gdb是linux系统自带的调试器,功能十分强大,对于C/C++程序员不会陌生,那么使用gdb如何调试golang程序呢?
1、配置gdb
golang这门语言是2009年才出来,gdb并没有原生支持调试golang,这里需要配置gdb,使它支持golang,关于这里面的原理,我还不是很清楚,应该是gdb本身支持扩展,可以以提供插件的形式扩展支持其他语言,具体怎么样,我也不是很清楚,待后续研究。
言归正传,这样配置:
1、打开gdb初始化配置文件
vim /home/KentZhang/.gdbinit ## 注意,KentZhang是我的家目录,你需要改成你的家目录
2、增加如下的一行
add-auto-load-safe-path /usr/local/go/src/runtime/runtime-gdb.py ## 注意, /usr/local/go是我的golang安装目录
3、然后重启gdb
使用gdb启动一个go程序:
[KentZhang@LOCAL-192-168-97-2 bak]$ gdb demo.exe
GNU gdb (GDB) 7.6.2
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/KentZhang/bak/demo.exe...done.
Loading Go Runtime support.
(gdb)
Loading Go Runtime support 出现这句话,就表示gdb可以支持golang。
2、编译golang
虽然gdb也支持golang了,但是在编译golang仍然需要加一些特殊的参数,否则出现如下的错误:
No symbol in current context
就是程序内的变量,你都无法打印,gdb说找不到。所以编译时,需要加下列的参数:
go build -gcflags=all="-N -l" ## 必须这样编译,才能用gdb打印出变量,第二个是小写的L,不是大写的i
3、打断点
关于打断点,必须使用特定的方式,由于golang是以包为单位管理代码,所有打断点时,要注意包名。
1、包名+函数名
(gdb) b main.main ## main包的main函数
Breakpoint 1 at 0x2131: file main.go, line 14.
(gdb) b framework/rpcclient/reqprocess.suitableMethods ## 注意包的全路径,这种方式要注意
gdb) b hundreds.(*Game).OnUserLogin ## *Game,表示指针的方式实现的,用Game反而打不到断点
Note: breakpoint 1 also set at pc 0x67ce70.
Breakpoint 2 at 0x67ce70: file /home/KentZhang/Hundreds/src/hundreds/game.go, line 57.
2、文件名+行号
(gdb) b main.go:17
Breakpoint 2 at 0x2167: file main.go, line 17.
4、总结
基本上经过三个步骤,就可以像调试C/C++一样调试golang了。
由于gdb不支持协程的调试,所以gdb调试golang有时候显得捉襟见肘。