16.2 调试-fmt包、delve工具、gdb工具

1. fmt包

fmt包的Printf函数可将调试信息按照所期望的格式打印出来。

  • fmt.Printf("String is: %v\n", s)
  • 不同于Println,Printf函数不会默认在行尾添加换行符。

fmt包的Printf函数可在同一行打印多个数据。

  • fmt.Printf("s is %v, t is %v\n", s, t)

%v格式化标记表示特定类型的默认格式。

  • fmt.Printf("%v\n", cat) // 例如cat是结构体,v%会在cat作业两端添加{ },并将cat的字段和值打印在{ }之间,eg.{Cat Black}
  • 对于结构体类型的变量可使用如下前缀:
    • + - 输出字段名,如:fmt.Printf("%+v\n", cat) // {name:Cat color:Black} //注意字段间没有逗号,与#不同
    • # - 输出类型名+字段名,如:fmt.Printf("%#v\n", cat) // main.animal{name:"Cat", color:"Black"}
// 使用fmt调试代码
// fmt包的Printf函数可将调试信息按照所期望的格式打印出来
package main

import "fmt"

func main() {
    s := "Hello World!"

    fmt.Printf("String is: %v\n", s)	// String is: Hello World! 
}
// 使用fmt包打印多个变量
// fmt包的Printf函数可在同一行打印多个数据
package main

import "fmt"

func main() {
    s := "Hello World!"
    t := "Goodbye Cruel World!"

    fmt.Printf("s is %v, t is %v\n", s, t)
}
// 打印输出:
s is Hello World!, t is Goodbye Cruel World! 
// 打印结构体变量
// %v格式化标记表示特定类型的默认格式,对于结构体类型的变量可使用如下前缀:
// + - 输出字段名
// # - 输出类型名+字段名
package main

import "fmt"

type animal struct {
    name  string
    color string
}
func main() {
    cat := animal{
        name:  "Cat",
        color: "Black",
    }

    fmt.Printf("%v\n", cat)
    fmt.Printf("%+v\n", cat)
    fmt.Printf("%#v\n", cat)
}
// 打印输出:
{Cat Black}
{name:Cat color:Black}//注意字段间没有逗号,与#不同
main.animal{name:"Cat", color:"Black"} 

2. delve工具

Go语言并不自带官方调试工具,但很多开源社区都提供了Go语言调试器,delve就是其中之一,它为Go语言项目提供了丰富的调试环境。

  • 执行如下命令,安装delve调试器:
    • go get github.com/derekparker/delve/cmd/dlv
  • 执行如下命令,启动delve调试器:
    • dlv debug main.go

delve包含许多内置调试命令,例如:

  • 设置断点
    • (dlv) break echo当程序运行至我们设置的断点时,程序会停止运行并打印代码的上下文清单,可以看到在断点处有一个箭头。我们可以根据自己的调试需求,在该处执行相应的命令并获取某些数据值。
  • 运行程序 (dlv) continue
  • 打印变量 (dlv) print s
// 使用delve调试代码
// 执行如下命令,安装delve调试器:
// go get github.com/derekparker/delve/cmd/dlv 
// 执行如下命令,启动delve调试器:dlv debug main.go 
package main
import "fmt"
func echo(s string) {
    fmt.Println(s)
}

func main() {
    s := "Hello World!"
    t := "Goodbye Cruel World!"
    echo(s)
    echo(t)
}
// 打印输出:
PS G:\GoWorkspace\src\debug\delve> dlv debug main.go 
Type 'help' for list of commands.
(dlv) break echo	// 我们自己输入的内容,表示在echo函数设置断点
					// (dlv)是运行dlv debug进入dlv后,命令行的一个提示符
Breakpoint 1 set at 0x4a7b1f for main.echo() G:\GoWorkspace\src src/debug/delve/main.go:16
(dlv) continue		// 我们自己输入的内容,表示开始运行程序
> main.echo() G:\GoWorkspace\src\debug/delve/main.go:16 (hits goroutine(1):1 total:1) (PC: 0x4a7b1f)
    11: //
    12: package main
    13: import "fmt"
    14:
=>  15: func echo(s string) {	// 箭头提示程序中断的位置
    16:         fmt.Println(s)
    17: }
    18:
    19: func main() {
    20:         s := "Hello World!"
    21:         t := "Goodbye Cruel World!"
(dlv) print s	// 执行至断点,程序运行终端,我们输入print s来查看当前的s值
"Hello World!" 

3. gdb工具

UNIX环境下著名的GNU调试器gdb也可以用于Go语言项目的调试,但必须先将Go语言程序编译为二进制形式的可执行文件

  • 执行如下命令,编译生成可执行文件:
    • go build main.go
  • 执行如下命令,启动gdb调试器:
    • gdb main

gdb包含许多内置调试命令,例如:

  • 设置断点 (gdb) break main.echo
  • 运行程序(gdb) run
  • 打印变量(gdb) print s
// 使用gdb调试代码
// 执行如下命令,编译生成可执行文件:go build main.go 
// 执行如下命令,启动gdb调试器:gdb main
package main
import "fmt"
func echo(s string) {
    fmt.Println(s)
}
func main() {
    s := "Hello World!"
    t := "Goodbye Cruel World!"
    echo(s)
    echo(t)
}
// 打印输出:
$ go build main.go // 编译为二进制文件
$ gdb main	// 启动gdb,进入调试
GNU gdb (Ubuntu 8.1-0ubuntu3) 8.1.0.20180409-git
...
(gdb) list	// 提示符(gdb)后输入list可以显示代码的清单(是根据二进制文件显示
			// 的)
1	// 执行如下命令,编译生成可执行文件:
2	// go build main.go 
3	// 执行如下命令,启动gdb调试器:
4	// gdb main
5	
6	package main
7	import "fmt"
8
9	func echo(s string) {
10	    fmt.Println(s)

(gdb) break main.echo  // 在main.echo函数处设置断点
Breakpoint 1 at 0x482070: file ~/GoWorkSpace/src/debug/gdb/main.go, line 9.
(gdb) run	// 设置完断点,运行程序
...
9	func echo(s string) {	// 执行到断点,程序终止
(gdb) print s	// 我们输入命令,打印s的值
$1 = 0x4b2f89 "Hello World!"

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值