Golang GDB - 打印变量

4

我遇到了gdb不能正确打印变量的问题。这个简单的程序是这样构建的:

chmurson-osx:helloworld chmurson$ go build -gcflags '-N' start.go 

然后gdb执行了:

chmurson-osx:helloworld chmurson$ gdb start -d $GOROOT
GNU gdb (GDB) 7.8
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-apple-darwin14.0.0".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from start...done.
warning: Missing auto-load scripts referenced in section .debug_gdb_scripts
of file /Users/chmurson/Dev/goprojects/misc/src/helloworld/start
Use `info auto-load python-scripts [REGEXP]' to list them.
(gdb) 
(gdb) source /usr/local/go/src/pkg/runtime/runtime-gdb.py
Loading Go Runtime support.

下一步我会这样做:
(gdb) list
1   package main
2   
3   import "fmt"
4   
5   func main() {
6       x := "abc"
7       i := 3
8       fmt.Println(i)
9       fmt.Println(x)
10  }
(gdb) b 9
Breakpoint 1 at 0x2106: file /Users/chmurson/Dev/goprojects/misc/src/helloworld/start.go, line 9.
(gdb) run
Starting program: /Users/chmurson/Dev/goprojects/misc/src/helloworld/start 
3
[New Thread 0x1113 of process 14039]

Breakpoint 1, main.main () at /Users/chmurson/Dev/goprojects/misc/src/helloworld/start.go:9
9       fmt.Println(x)
(gdb) p x
Python Exception <type 'exceptions.OverflowError'> signed integer is greater than maximum: 
$1 = 
(gdb) p i
$2 = 8725692800
(gdb) 

你可以看到在检查'p'变量时出现了Python异常,并且在显示'i'的值时完全不是3。出了什么问题?

这是我的Go版本

chmurson-osx:helloworld chmurson$ go version
go version go1.3.1 darwin/amd64

以及 gdb 配置

(gdb) show configuration
This GDB was configured as follows:
   configure --host=x86_64-apple-darwin14.0.0 --target=x86_64-apple-darwin14.0.0
             --with-auto-load-dir=:${prefix}/share/auto-load
             --with-auto-load-safe-path=:${prefix}/share/auto-load
             --with-expat
             --with-gdb-datadir=/usr/local/share/gdb (relocatable)
             --with-jit-reader-dir=/usr/local/lib/gdb (relocatable)
             --without-libunwind-ia64
             --without-lzma
             --with-python=/System/Library/Frameworks/Python.framework/Versions/2.7
             --without-guile
             --with-separate-debug-dir=/usr/local/lib/debug (relocatable)
             --with-zlib
             --without-babeltrace

("Relocatable" means the directory can be moved with the GDB installation
tree, and GDB will still find it.)
2个回答

2
补充@AlexAtNet的回答,Go 1.2.x之后的版本破坏了GDB支持,因此要么使用go 1.2.x进行调试,要么使用gccgo(请注意,gcc 4.8.x支持go 1.1,gcc 4.9.x支持go 1.2)。
另一个选择是使用自己的跟踪函数,虽然不太美观,但目前是go 1.3+唯一真正的调试选项。
我个人在调试时会使用类似这样的代码:
var traceLock sync.Mutex

func trace(a ...interface{}) {
    traceLock.Lock()
    pc, f, ln, ok := runtime.Caller(1)
    fn := ""
    if ok {
        fn = runtime.FuncForPC(pc).Name()
    }
    fmt.Printf("trace: %s %s:%d", fn, filepath.Base(f), ln)
    if len(a) > 0 {
        fmt.Println(append([]interface{}{": "}, a...)...)
    }
    traceLock.Unlock()
}

playground


1
将 Go 降级到 1.2.x 做了点“小技巧”。 Gdb 调试器打印这些变量非常漂亮。此外,Go 运行时源代码会自动加载,无需每次手动插入。对于我来说,Go 1.3 不是必需的要求,因为我还是 Go 新手,所以我很满意。稍后会尝试一下 gccgo 的工作原理。谢谢! - chmurson

2
Go团队并不将GDB支持作为优先事项,因此解决此类问题的数量可能不会很快得到修复。请考虑以下内容:

https://golang.org/doc/gdb

GDB 对 Go 程序的理解不够完善。栈管理、线程和运行时包含的方面与 GDB 期望的执行模型有足够大的差异,即使使用 gccgo 编译程序,它们也可能会使调试器混淆。因此,尽管在某些情况下 GDB 可以有用,但它不是 Go 程序的可靠调试器,特别是对于高度并发的程序。此外,解决这些问题并不是 Go 项目的优先事项,因为它们很难。

然而,您可以使用 Gccgo 工具链成功地调试 Go 程序。但是,在 Mac 上安装它有点麻烦。


1
根据当前最新的gcc版本https://gcc.gnu.org/gcc-4.9/changes.html的文档,它仅支持Go 1.2.1。所以我现在必须暂时放弃Go 1.3。 - chmurson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接