go语言的gdb调试方法

1、加载go语言的gdb调试支持文件

gdb里键入:source go/src/runtime/runtime-gdb.py

加载成功后gdb显示:Loading Go Runtime support.

或者设置为自动加载,有两种方法:

1、放入 /etc/gdbinit.d/ 目录下。

2、在 ~./gdbinit 文件中添加,如:

# 保存历史命令
set history filename ~/.gdb_history
set history save on

# 加载go支持
source ~/go1.18/src/runtime/runtime-gdb.py

如果程序涉及cgo,采用gccgo编译更方便gdb调试,gccgo的编译方式:

export PATH=${gccgo版本的go执行体目录}:$PATH
#share
#go build -compiler gccgo -v -o myexe main.go myxx.go
#static
go build -compiler gccgo -gccgoflags -static-libgo -v -o myexe main.go myxx.go

2、编译go程序时打开调试符号和禁止内联

go build -gcflags "-N -l" xx.go

When compiling Go programs, the following points require particular attention:

  1. Using -ldflags "-s" will prevent the standard debugging information from being printed
  2. Using -gcflags "-N -l" will prevent Go from performing some of its automated optimizations -optimizations of aggregate variables, functions, etc. These optimizations can make it very difficult for GDB to do its job, so it’s best to disable them at compile time using these flags.

查看载入的二进制文件:info files

查看载入的源码文件:info sources

查看载入的函数列表:info functions

查看载入的动态库列表:info sharedlibrary

对于go test单测,可以编译为bin再调试:

CGO_ENABLED=1 CGO_CXXFLAGS=-g CGO_CFLAGS=-g go test -c xxx_test.go `ls *go | grep -v main.go | grep -v xxx_test.go` -o test

./test -test.v -test.timeout=20m -test.run Testxxx

gdb -p `pidof test`

3、为golang新增的命令和函数

新增的命令会出现在 help info 里。

新增的函数会出现在 help function 里。

比如使用新增的cap函数:

p $cap(slicea)

4、查看协程和线程

info goroutines

info threads

在某个协程上执行gdb命令,比如查看2号协程的栈帧:

goroutine 2 bt

切换当前线程:

thread {线程号}

5、查看变量

slice:

len:p $len(slicea)

cap:p $cap(slicea)

array:p slicea.array[0]

搜索变量包名:

info variables varname

全局变量:

p pkgname.varname

p 'path1/path2/pkgname.varname'

也可以通过bin文件查看:

nm -D bin_file

局部变量:

info local

p var

动态环境变量:

p 'syscall.envs'

p 'syscall.envs'.array[0]

静态环境变量:

show env

6、go用户程序入口断点

b main.main

7、其他常用断点

lock:

b runtime.futex

channel:

b runtime.chansend

b runtime.chanrecv

调度:

b runtime.schedule
b runtime.save
b runtime.newm
b runtime.newproc
b runtime.osyield
b runtime.pidleput
b runtime.stopm

系统调用:

b syscall.read
b syscall.write
b syscall.Syscall
b syscall.Syscall6
b syscall.RawSyscall
b syscall.RawSyscall6
b runtime.entersyscall
b runtime.exitsyscall
b runtime.Gosched

显示可打断点的文件:

info sources

显示可打断点的函数:

info functions

8、查看运行时

p 'runtime.ncpu'

p 'runtime.gomaxprocs'

p 'runtime.allp'

p 'runtime.allp'.__count

p (*('runtime.allp'.__values[0])).status

p 'runtime.allm'.park

p 'runtime.allgs'

p 'runtime.allgs'.__count

p (*('runtime.allgs'.__values[0])).goid

p (*('runtime.allgs'.__values[0])).atomicstatus

p (*('runtime.allgs'.__values[0])).waitreason

p (*('runtime.allgs'.__values[0])).lockedm

p *'runtime.g'

p 'runtime.g'.atomicstatus

p 'runtime.g'.waitreason

p 'runtime.g'.lockedm

p *'runtime.g'.m

p 'runtime.g'.m.park

p 'runtime.g'.m.blocked

p 'runtime.g'.m.locks

p 'runtime.g'.m.spinning

p 'runtime.g'.m.procid

p 'runtime.g'.m.incgo

p 'runtime.g'.m.ncgocall

p 'runtime.g'.m.ncgo

p 'runtime.g'.m.lockedg

遇到的问题:

1、gdb显示Dwarf Error:

Dwarf Error: wrong version in compilation unit header (is 0, should be 2, 3, or 4)

Python Exception <class 'gdb.error'> Attempt to extract a component of a value that is not a (null).

解决办法:升级gdb到8,如el7升级到gdb8,按如下操作:

yum安装:

yum -y install centos-release-scl

yum-config-manager --enable rhel-server-rhscl-7-rpms

yum -y install devtoolset-7

scl enable devtoolset-7 bash

rpm安装:

rpm包下载地址:https://centos.pkgs.org/7/centos-sclo-rh-x86_64/devtoolset-7-gdb-8.0.1-36.el7.x86_64.rpm.html

yum provides semanage

yum install policycoreutils-python-2.5-34.el7.x86_64

rpm -i scl-utils-20130529-19.el7.x86_64.rpm

rpm -i devtoolset-7-runtime-7.1-4.el7.x86_64.rpm

rpm -i devtoolset-7-gdb-8.0.1-36.el7.x86_64.rpm

mv /bin/gdb /bin/gdb.old

ln -s  /opt/rh/devtoolset-7/root/usr/bin/gdb /bin/gdb

--end--

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值