30

go程序调试

 4 years ago
source link: https://www.tuicool.com/articles/aQzaqmB
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

调试程序是程序猿的一项必备技能,有多种手段来调试程序,如打印控制台输出,查看日志,以及设置断点,使用debug做单步跟踪进去调试。这篇文章主要从go使用debug为题进行展开。

GDB

介绍

GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具。 在mac上安装,会有认证方面的问题,查了一些资料,没能解决,就放弃了。使用vagrant搭建了一个go的环境并安装了gdb工具,在需要使用gdb时,通常是将代码通过vagrant目录映射到linux虚拟主机中,然后进行GDB调试。这种用的也不是很多,一般主要使用GDB提供的x命令,查看下内存的值。

debug目标

  1. 设置断点
  2. 查看变量值的输出
  3. 查看变量内存地址
  4. 查看变量内存值
  5. 修改变量的值

基于以上四点,我们通过程序来展示gdb的基本用法

gdb用法

示例程序:

package main

import (
    "fmt"
    "os"
)

func main() {
    fmt.Println("go debug.....")
    // 命令参数使用
    var argc = len(os.Args)
    var argv = append([]string{}, os.Args...)
    fmt.Printf("argc:%d\n", argc)
    fmt.Printf("argv:%v\n", argv)

    // 查看变量内存地址及值
    var aa = 1
    var bb = -1

    fmt.Println(aa)
    fmt.Println(bb)
}
  1. 编译程序
go build -gcflags="-N -l" demo.go // -N -l用于关闭编译器的内联优化
  1. 启动gdb
gdb demo
  1. 设置断点break
(gdb) b main.main
Breakpoint 1 at 0x488e60: file /home/vagrant/godemo/demo01/demo.go, line 8.
(gdb) info b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x0000000000488e60 in main.main at /home/vagrant/godemo/demo01/demo.go:8
(gdb)

启动程序run

(gdb) run arg1 agr2
Starting program: /home/vagrant/godemo/demo01/demo arg1 agr2
[New LWP 5976]
[New LWP 5977]
[New LWP 5978]

Thread 1 "demo" hit Breakpoint 1, main.main () at /home/vagrant/godemo/demo01/demo.go:8
8    func main() {
(gdb)

查看代码

(gdb) l
4        "fmt"
5        "os"
6    )
7
8    func main() {
9        fmt.Println("go debug.....")
10        // 命令参数使用
11        var argc = len(os.Args)
12        var argv = append([]string{}, os.Args...)
13        fmt.Printf("argc:%d\n", argc)
(gdb)
14        fmt.Printf("argv:%v\n", argv)
15
16        // 查看变量内存地址及值
17        var aa = 1
18        var bb = -1
19
20        fmt.Println(aa)
21        fmt.Println(bb)
22    }
(gdb)

单步执行next

(gdb) n
go debug.....
11        var argc = len(os.Args)
(gdb) n
12        var argv = append([]string{}, os.Args...)
(gdb) n
13        fmt.Printf("argc:%d\n", argc)
(gdb) n
argc:3
14        fmt.Printf("argv:%v\n", argv)
(gdb) n
argv:[/home/vagrant/godemo/demo01/demo arg1 agr2]

打印命令p

打印格式

x 按十六进制格式显示变量。

d 按十进制格式显示变量。

u 按十六进制格式显示无符号整型。

o 按八进制格式显示变量。

t 按二进制格式显示变量。

a 按十六进制格式显示变量。

c 按字符格式显示变量。

f 按浮点数格式显示变量。

17        var aa = 1
(gdb) n
18        var bb = -1
(gdb) p aa
$1 = 1
(gdb) p &aa
$2 = (int *) 0xc00007ce40
(gdb) p/x aa
$3 = 0x1

查看内存值命令x

x/<n/f/u> <addr>

n、f、u是可选的参数。

n 是一个正整数,表示显示内存的长度

f 表示显示的格式,参见上面

u 表示字节数,GDB默认是4个bytes。

b表示单字节

h表示双字节

w表示四字节

g表示八字节

<addr>表示一个内存地址

(gdb) p &aa
$2 = (int *) 0xc00007ce40
(gdb) x/1dg 0xc00007ce40
0xc00007ce40:    1
(gdb)

设置值命令

(gdb) set aa = 2
(gdb) p aa
$4 = 2
(gdb)

程序调用栈bt

显示goroutines

info goroutines // 显示当前执行的goroutine列表,如下代码所示,带*的表示当前执行的

查看变量类型

whatis

这里只列出出来了一些基本的用法,gdb很强大,还有很多命令,可以深入程序执行的底层,通过以上几个命令,可以完成一个程序的基本调试。

delve

delve是专为go语言打造的debug工具,现在的一些IDE工具的debug功能就是基于这个实现的。

启动debug服务

dlv debug demo.go

其它的命令同gdb大体相同,初级的调试,高级的使用功能,还未深入研究,另外它还可以attach到一个运行的程序进行debug。

IDE工具

如果不习惯使用命令行,可以使用集成开发工具goland,这个带有图形化界面操作的debug工具,操作起来比较方便。

喜欢请关注“云端漫记", 持续为你更新

bVbwas2?w=430&h=430


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK