gdb 命令_16. 如何使用 GDB 调试 Go 程序?-程序员宅基地

技术标签: gdb打印指针内容  gdb调试命令  gdb 命令  gdb如何调试头文件  gdb 进入函数  gdb 查看结构体地址内容  

b0500914619272f680661fc8040a728f.png

大家好,我是明哥。

由于某些不可抗力,之前该专栏的所有内容都被删除了。因此之后的一段时间内,我会重新发布这些文章,先给已经看过的关注者提个醒。


本文原文:http://golang.iswbm.com

Github:http://github.com/iswbm/GolangCodingTime

做为新手,熟练掌握一个好的调试工具,对于我们学习语言或者排查问题的时候,非常有帮助。

你如果使用 VS Code 或者 Goland ,可以直接上手,我就不再写这方面的文章了。

其实相比有用户界面的 IDE 调试工具,我更喜欢简单直接的命令行调试,原因有三点:

  1. 速度快,个人感觉在 Windows 下速度巨慢
  1. 依赖少,在 Linux 服务器上 也能轻松调试
  1. 指令简单,我习惯只使用快捷键就能操作

如果你有和我一样的感受和习惯,可以看下今天的文章,介绍的是 GDB 调试工具。

1. 下载安装 Go

在 Linux 上进行调试,那咱所以得先安装 Go ,由于第一节里只讲了 Windows 的下载安装,并没有讲到在 Linux 上如何安装。所以这里要先讲一下,已经安装过了可以直接跳过。

首先在 go 下载页面上(https://golang.org/dl/),查看并复制源码包的的下载地址

ae8fc851400ac1397e2943385ba3c46b.png

登陆 linux 机器 ,使用 wget 下载

$ wget https://dl.google.com/go/go1.14.2.linux-amd64.tar.gz

98307195bc67331df94511e528c42acc.png

将下载的源码包解压到 /usr/local 目录下,并设置环境变量

[root@localhost ~]# tar -C /usr/local -xzf go1.14.2.linux-amd64.tar.gz
[root@localhost ~]# 
[root@localhost ~]# export PATH=$PATH:/usr/local/go/bin
[root@localhost ~]# which go
/usr/local/go/bin/go
[root@localhost ~]# 
[root@localhost ~]# go version
go version go1.14.2 linux/amd64
[root@localhost ~]# 

2. 开始进行调试

调试使用的是 GDB (好像要求版本 7.1 + ),使用前,请先确保你的机器上已经安装 GDB

[root@localhost code]# which gdb
/usr/bin/gdb

准备就绪后,先在目录下写一个测试文件

package main

import "fmt"

func main(){
  msg := "hello, world"
  fmt.Println(msg)
}

然后执行 如下命令进行编译,里面有好多个参数,有疑问的可以自行搜索引擎

# 关闭内联优化,方便调试
$ go build -gcflags "-N -l" demo.go

# 发布版本删除调试符号
go build -ldflags “-s -w”

最后使用 GDB 命令进入调试界面

# 如果你喜欢这种界面的话,用这条命令
$ gdb -tui demo

# 如果你跟我一样不喜欢不习惯用界面,就使用这个命令
$ gdb demo

完整操作如下:

f8c4e958c7af24e6dcda21c694823576.png

进入 GDB 调试界面后,并不是立即可用,你先需要回车,然后再你敲入几行命令,调试窗口就会出现代码。

(gdb) b    main.main   # 在 main 包里的 main 函数 加断点
Breakpoint 1 at    0x4915c0: file /home/wangbm/code/demo.go, line 5.
(gdb) run  # 执行进程
Starting program: /home/wangbm/code/demo 
Breakpoint 1, main.main () at /home/wangbm/code/demo.go:5
(gdb) 

98e435eda04d10fa9fead95aa35cc58c.png

3. 详解调试指令

要熟练使用 GDB ,你得熟悉的掌握它的指令,这里列举一下

  • r:run,执行程序
  • n:next,下一步,不进入函数
  • s:step,下一步,会进入函数
  • b:breakponit,设置断点
  • l:list,查看源码
  • c:continue,继续执行到下一断点
  • bt:backtrace,查看当前调用栈
  • p:print,打印查看变量
  • q:quit,退出 GDB
  • whatis:查看对象类型
  • info breakpoints:查看所有的断点
  • info locals:查看局部变量
  • info args:查看函数的参数值及要返回的变量值
  • info frame:堆栈帧信息
  • info goroutines:查看 goroutines 信息。在使用前 ,需要注意先执行 source /usr/local/go/src/runtime/runtime-gdb.py
  • goroutine 1 bt:查看指定序号的 goroutine 调用堆栈
  • 回车:重复执行上一次操作

其中有几个指令的使用比较灵活

比如 l - list,查看代码

# 查看指定行数上下5行
(gdb) l 8

# 查看指定范围的行数
(gdb) l 5:8

# 查看指定文件的行数上下5行
l demo.go:8

# 可以查看函数,记得加包名
l main.main

把上面的 l 换成 b ,大多数也同样适用

# 在指定行打断点
(gdb) b 8


# 在指定指定文件的行打断点
b demo.go:8

# 在指定函数打断点,记得加包名
b main.main

还有 p - print,打印变量

# 查看变量
(gdb) p var

# 查看对象长度或容量
(gdb) p $len(var)
(gdb) p $cap(var)

# 查看对象的动态类型
(gdb) p $dtype(var)
(gdb) iface var

# 举例如下
(gdb) p i
$4 = {str = "cbb"}
(gdb) whatis i
type = regexp.input
(gdb) p $dtype(i)
$26 = (struct regexp.inputBytes *) 0xf8400b4930
(gdb) iface i
regexp.input: struct regexp.inputBytes *

以上就是关于 GDB 的使用方法,非常简单,可以自己手动敲下体验一下。

参考文章

  • go 官方对于 gdb 的使用说明
  • Mac 调试 golang 程序

好了,今天的文章就到这里了。

若今天的分享对你有帮助,不如点个赞,支持一下?

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_39662432/article/details/109967823

智能推荐

python 语言变量命名规则的是_Python变量命名规则-程序员宅基地

模块名:小写字母,单词之间用_分割ad_stats.py包名:和模块名一样类名:单词首字母大写AdStatsConfigUtil全局变量名(类变量,在java中相当于static变量):大写字母,单词之间用_分割NUMBERCOLOR_WRITE普通变量:小写字母,单词之间用_分割this_is_a_var实例变量:以_开头,其他和普通变量一样_price_instance_var私有实例变量(外..._python语言变量命名规则的是(1分

Cglib源码分析 invoke和invokeSuper的差别(转)-程序员宅基地

原文https://blog.csdn.net/makecontral/article/details/79593732Cglib的实例本文重在源码的分析,Cglib的使用不再复述。//被代理类public class InfoDemo { public void welcome (String person){ System.out.pr...

五种常见的linux系统有哪些,常见的Linux操作系统有哪些-程序员宅基地

Linux操作系统诞生于1991 年的10 月5 日。Linux存在着许多不同的Linux版本,但它们都使用了Linux内核。以下是学习啦小编为你精心整理的Linux操作系统的种类,希望你喜欢。Linux操作系统的种类1、veket系统veket系统目前包括veket-x86平台系统和随身系统,还有上网本系统,分别对应veket-8系统、veket-7系统和veket-5系统。经过测试,veket..._以下哪个不是以linux为核心的操作系统软件包?

NYOJ---240题小明的调查统计(二)-程序员宅基地

这个问题其实很长时间之前就可以解决了,但是不想做。以前各种WA,在心里留下了阴影。我就打算等到自己的实力提升到一定境界之后轻而易举的解决它,那样就可以建立强大的自信。嘿嘿······这个题跟杭电的那道海选女主角很相似。但是不同的是这道题需要多加一层判断。对成绩进行排名,需要考虑到并列名次。解题思路:定义结构体,用结构体储存班级,学号,成绩,名次。然后用sort排序。不过需要在最开始的地方写

ZZULIOJ:1114: 逆序_zzulioj逆序数排序_计科土狗的博客-程序员宅基地

输入n(1<=n<=10)和n个整数,逆序输出这n个整数。_zzulioj逆序数排序

随便推点

IO------->第一天,标准IO-程序员宅基地

标准IO:标准IO是由ANSIC(ANSI美国国家标准协会及国际标准化组织(ISO))标准定义 跨平台,既可以运行在windows下,也可以运行在Linux下 标准IO通过缓冲机制减少系统调用,实现更高的效率. 文件流,标准IO用结构体类型(FILE)来存放文件的相关信息,标准IO所有操作围绕FILE来进行系统调用关于系统调用记住两点:(1).有操作系统的情况下,应用程序要访问硬件不允许直接访问,必须通过操作系统提供的系统调用接口来完成.(2).不同的操作系统提供的系统调用函

Python开启线程,函数中开线程_elsx套入函数时会出现线程-程序员宅基地

Python开启线程,函数中开线程 逻辑处理上分成了多个模块,为了提高效率,前一个模块处理完调用后一个模块操作时使用多线程 我这里遇到的情形是前面取数据后面存到mysql,发现单线程效率很低,改为取数据后开线程存到mysql 开启线程之后性能提升一倍,同时用信号量做线程同步,控制数据库同时连接数 这里只是简单的一个demo,主要是开线程的处理方式,在自己类里面的函数中开启线程,并用自己类的成_elsx套入函数时会出现线程

pycharm解决“‘pip‘ 不是内部或外部命令,也不是可运行的程序或批处理文件“的问题_pycharm中pip不是内部命令-程序员宅基地

发现 pycharm 用pip时出现'pip' 不是内部或外部命令,也不是可运行的程序或批处理文件直接上方法:找到安装python的自己的位置 比如我的是 ' D:\PYTHON2\python\Scripts'然后添加环境变量 可以在左下角的 放大镜直接搜 环境变量 也可以一步一步点过去 路径如下:此电脑- >属性- >高级系统设置- >高级- >环境变量- >系统环境变量编辑- > 路径/path- >修改或者新加,path中新加..._pycharm中pip不是内部命令

AQTime + Delphi-程序员宅基地

一,Delphi项目设置For AQTime(Delphi 2007 for Win32 application for AQtime)Open your project in CodeGear Delphi 2007 for Win32.Sele..._delphi 自带aqtime

Git全局代理设置_git 端口号配置-程序员宅基地

git设置代理一般我们使用git进行上传或者下载时会很慢,连接错误,设置好代理以后就会很快,如果用如下命令需要每次都设置代理,很麻烦git config --global https.proxy http://127.0.0.1:10808git config --global http.proxy 'socks5://127.0.0.1:10809'怎么进行一个全局设置呢?vi ~./gitconfig# 在文件中编辑如下内容,其中xxxx是端口号[https] proxy_git 端口号配置

如何用WINX实现可滚动的窗口(ScrollWindow)-程序员宅基地

如何用WINX实现可滚动的窗口(ScrollWindow)许式伟 (版权声明)2007-1-29用Windows SDK实现过可滚动的窗口(ScrollWindow)的读者都知道,实现一个ScrollWindow真不是一件容易的事情。你得响应好多好多的滚动条消息,还要处理鼠标滚轮。现在,你用WINX则只需要3步完成: 让你的类从ScrollWindow 实现一个名为DoPaint的