Golang 使用GDB调试

http://golang.org/doc/gdb

注意

  1. 传递参数-ldflags "-s",忽略debug的打印信息
  2. 传递-gcflags "-N -l" 参数,这样可以忽略Go内部做的一些优化
  3. -传递参数 -ldflags "-w" ,会删除DWARF调试信息

GDB 常用命令

  1. list <=> l [num] # 显示多少行源代码
  2. break <=> b num # 指定行数设置断点
  3. delete <=> d num # 删除断点
  4. backtrace <=> bt # 代码执行过程
    • goroutine 1 bt # 协程执行过程
  5. info # 显示信息
    • info goroutines # 当前程序的goroutine列表,*号开头表示正在执行
    • info locals # 当前变量的值
    • info breakpoints # 断点列表
  6. print <=> p # 打印信息
  7. whatis # 变量类型
  8. next <=> n # 跳转到下一步
  9. continue <=>c [num] # 跳过多少次断点
  10. set variable # 改变运行过程中的变量值: set variable key=value
  11. run # 运行程序

操作命令参考

go build -gcflags "-N -l" -ldflags "-s" gdbfile.go

gdb gdbfile

错误

找不到加载的文件!?
解决1:

打包时加上 -ldflags=-compressdwarf=false 参数即可
即: go build -gcflags "-N -l" -ldflags=-compressdwarf=false gdb/main.go
然后通过命令 gdb main 即可调试

错误

找不到源文件

产生原因:

我是在Windows系统开发的代码,编译好之后,再上传到Linux环境进行GDB调试的,这时候就会报错如上了

注意其实在设置断点的时候,也提示了断点设置在哪个源码文件里面了

解决:

开发与调试最好同一个环境下

与调试相关的几个标准函数库

runtime.BreakPoint() # 触发调试器断点
runtime/debug.PrintStack() # 输出调用栈
log pkg # 替代 print 来显示调试信息

设置断点

$ b <函数名>

这里面的函数名是指:链接符号,而不是平常看到的语言文法层面使用的符号

在Golang语言中,一般的函数原型如下:

package Package
func Method(arg1 ArgType1, arg2 argType2...)(...)
func (v ClassType) Method(arg...)(...)
func (v *ClassType) Method(arg...)(...)

基于以上的函数原型,其“符号链接”规则如下

  1. Package ,可以是多层,如:`github.com/astaxie/beego/logs`
  2. ClassType , 可以是指针也可以不是
  3. Method

可能的“符号链接”就如下:

  1. Package.Method
  2. Package.ClassType.Method

例子:

在 qbox.us/mockfs 模块中,有如下几个
函数:
    func New(cfg Config) *MockFS
    func (fs *MockFS) Mkdir(dir string) (code int, err error)
    func (fs MockFS) Foo(bar Bar)
它们的链接符号分别为:
    qbox.us/mockfs.New
    qbox.us/mockfs.*MockFS·Mkdir
    qbox.us/mockfs.MockFS·Foo