使用gdb调试go项目

原始文档:https://golang.org/doc/gdb,本文以docker的libnetwork库为例,说明如何用gdb调试。


首先安装golang和gdb(版本7.0以上),在FreeBSD上,请用gdb7121。设置GOPATH=$HOME/go。

下载libnetwork:go get github.com/docker/libnetwork

在$GOPATH/github.com/clovertrail/testlibnetwork目录,创建测试程序,此处直接使用libnetwork的示例,稍作修改

package main
import (
        "fmt"
        "github.com/docker/libnetwork"
        "github.com/docker/libnetwork/options"
        "github.com/docker/libnetwork/netlabel"
        "github.com/docker/libnetwork/config"
)

func main() {
        networkType := "bridge"

        // Create a new controller instance
        driverOptions := options.Generic{}
        genericOption := make(map[string]interface{})
        genericOption[netlabel.GenericData] = driverOptions
        controller,err := libnetwork.New(config.OptionDriverConfig(networkType,genericOption))
        if err != nil {
                fmt.Println(err)
                return
        }

        fmt.Println(controller)
        // Create a network for containers to join.
        // NewNetwork accepts Variadic optional arguments that libnetwork and Drivers can make use of
        network,err := controller.NewNetwork(networkType,"network1","")
        if err != nil {
                fmt.Println(err)
                return
        }
        fmt.Println(network)
        // For each new container: allocate IP and interfaces. The returned network
        // settings will be used for container infos (inspect and such),as well as
        // iptables rules for port publishing. This info is contained or accessible
        // from the returned endpoint.
        ep,err := network.CreateEndpoint("Endpoint1")
        if err != nil {
                fmt.Println(err)
                return
        }
        fmt.Println(ep)
        // Create the sandBox for the container.
        // NewSandBox accepts Variadic optional arguments which libnetwork can use.
        sbx,err := controller.NewSandBox("container1",libnetwork.OptionHostname("test"),libnetwork.OptionDomainname("docker.io"))
        fmt.Println(sbx)
        // A sandBox can join the endpoint via the join api.
        err = ep.Join(sbx)
        if err != nil {
                fmt.Println(err)
                return
        }
}

项目的目录结构如下:

.
`-- testlibnetwork
|-- bingo.go
`-- vendor
`-- github.com
`-- docker
`-- libnetwork -> $GOPATH/src/github.com/docker/libnetwork


重新编译libnetwork,打印编译的命令细节,并关闭内联优化:

go build -a -x -gcflags "-N -l" github.com/docker/libnetwork


编译测试用例,同时关闭内联优化:

go build -gcflags "-N -l" -o ~/go/bin/bingo bingo.go


好了,启动gdb,开始调试:

gdb ~/go/bin/bingo -d $GOROOT

正常情况,gdb会自动load $GOROOT/src/runtime/runtime-gdb.py,如果没有load,请手动load:

(gdb) source $GOROOT/src/runtime/runtime-gdb.py


开始调试,设置断点。go里面的第三方源代码的路径和import里面是一致的,比如我们想在controller.go:180行设断点:

(gdb) b github.com/docker/libnetwork/controller.go:180
Breakpoint 1 at 0x481397: file /home/honzhan/go/src/github.com/clovertrail/testlibnetwork/vendor/github.com/docker/libnetwork/controller.go,line 180.

(gdb) r
Starting program: /usr/home/honzhan/go/bin/bingo
[New LWP 100134 of process 16801]
[New LWP 100260 of process 16801]
[New LWP 100283 of process 16801]
[New LWP 100294 of process 16801]
[New LWP 100470 of process 16801]


Thread 1 hit Breakpoint 1,github.com/clovertrail/testlibnetwork/vendor/github.com/docker/libnetwork.New (
cfgOptions= []github.com/clovertrail/testlibnetwork/vendor/github.com/docker/libnetwork/config.Option = {...},~r1=...,~r2=...)
at /home/honzhan/go/src/github.com/clovertrail/testlibnetwork/vendor/github.com/docker/libnetwork/controller.go:180
180 c := &controller{


更多调试命令请参考https://golang.org/doc/gdb

相关文章

程序目录结构 简单实现,用户登录后返回一个jwt的token,下次请求带上token请求用户信息接口并返回信息...
本篇博客的主要内容是用go写一个简单的Proof-of-Work共识机制,不涉及到网络通信环节,只是一个本地的简...
简介 默克尔树(MerkleTree)是一种典型的二叉树结构,其主要特点为: 最下面的叶节点包含存储数据或其...
接下来学习并发编程, 并发编程是go语言最有特色的地方, go对并发编程是原生支持. goroutine是go中最近本...
先普及一下, 什么是广度优先搜索 广度优先搜索类似于树的层次遍历。从图中的某一顶点出发,遍历每一个顶...
第一天: 接口的定义和实现 第二天: 一. go语言是面向接口编程. 在学习继承的时候说过, go语言只有封装,...