Posted on 2014-10-04 03:51:00 golang
首先需要注意的是:golang1.3之后的版本,对于支持gdb调试存在很大的问题。产生这个问题的原因是,golang的runtime没有完整的被gdb支持。
最新比较完整支持gdb调试的版本是golang 1.2.2,但是也有个别问题存在。
为什么会出现以上种种问题,golang官网给出的解释是:
GDB does not understand Go programs well. The stack management, threading, and runtime contain aspects that differ enough from the execution model GDB expects that they can confuse the debugger, even when the program is compiled with gccgo. As a consequence, although GDB can be useful in some situations, it is not a reliable debugger for Go programs, particularly heavily concurrent ones. Moreover, it is not a priority for the Go project to address these issues, which are difficult. In short, the instructions below should be taken only as a guide to how to use GDB when it works, not as a guarantee of success.
翻译一下:
GDB不能很好的理解GO程序。堆栈管理、线程和runtime包含了非常不一样的执行模式,这不是GDB期望的,他们会扰乱调试器,即使go程序是使用gccgo编译的。结果就是,虽然GDB在某些场合下是有用的,但是对go程序来说并不是一个可靠的调试器。尤其是在大量并发的时候。而且,这不是Golang项目优先考虑的事情,这很困难。总而言之,下面的操作手册,只是当GDB正常工作的时候,引导你如何使用GDB,不能保证总是成功。
并且从google group讨论组和stackoverflow中,可以看到golang的多个版本对于GDB的支持都有这样那样的问题。 不过既然官方的手册都这么说了,我们也只有在合适的场合使用GDB吧。
默认情况下,编译过的二进制文件已经包含了 DWARFv3 调试信息,只要 GDB7.1 以上版本都可以进行调试。 在OSX下,如无法执行调试指令,可尝试用sudo方式执行gdb。
在编译go程序的时候,需要关闭内联优化:** -gcflags “-N -l”**。可以在go get/build/test
的时候指定这个参数。
有两种方式可以下断点:
演示环境:Ubuntu 14.04 LTS amd64 / Golang 1.2.2 / GDB 7.7
package main
import (
"fmt"
"runtime"
)
func test(s string, x int) (r string) {
r = fmt.Sprintf("test: %s %d", s, x)
runtime.Breakpoint()
return r
}
func main() {
s := "haha"
i := 1234
println(test(s, i))
}
启动GDB:
➜ ~ gdb ./test
GNU gdb (Ubuntu 7.7-0ubuntu3) 7.7
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-linux-gnu".
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 ./test...done.
**Loading Go Runtime support.**
(gdb)
以模块名的方式查看源码:
(gdb) l main.main
9 r = fmt.Sprintf("test: %s %d", s, x)
10 runtime.Breakpoint()
11 return r
12 }
13
14 func main() {
15 s := "haha"
16 i := 1234
17 println(test(s, i))
以文件名加行号的方式查看源码:
(gdb) l /home/roy/test.go:1
1 package main
2
3 import (
4 "fmt"
5 "runtime"
6 )
7
8 func test(s string, x int) (r string) {
9 r = fmt.Sprintf("test: %s %d", s, x)
10 runtime.Breakpoint()
设置断点:
(gdb) b main.main
Breakpoint 2 at 0x400d80: file /home/roy/test.go, line 14.
(gdb) b test.go:18
Breakpoint 3 at 0x400e0e: file /home/roy/test.go, line 18.
启动进程,触发断点: (n 单步执行,c执行到下一个断点)
(gdb) run
Starting program: /home/roy/test
Breakpoint 2, main.main () at /home/roy/test.go:14
14 func main() {
查看goroutines:
(gdb) info goroutines
* 1 running runtime.gosched
* 2 syscall runtime.notetsleepg
查看指定goroutine的调用堆栈:
(gdb) goroutine 1 bt
Python Exception <class 'gdb.MemoryError'> Cannot access memory at address 0x8:
Error occurred in Python command: Cannot access memory at address 0x8
当我们想查看goroutine调用堆栈的时候,gdb报告无法访问内存。
Cannot access memory at address 0x8
,这句是说无法访问0x8
位置的内存,所以接下来,gdb收到了一个SIGSEGV的信号,说明触发了段错误:
(gdb) n
Program received signal SIGSEGV, Segmentation fault.
0x000000000041529b in runtime.gosched () at /home/roy/go/src/pkg/runtime/proc.c:1368
1368 runtime·mcall(runtime·gosched0);
此时,我们需要重启gdb的调试,否则执行任何命令都会报告段错误。
打印栈帧信息:
(gdb) info frame
Stack level 0, frame at 0x7ffff7e2ef48:
rip = 0x400d80 in main.main (/home/roy/test.go:14); saved rip = 0x412e1f
source language go.
Arglist at 0x7ffff7e2ef38, args:
Locals at 0x7ffff7e2ef38, Previous frame's sp is 0x7ffff7e2ef48
Saved registers:
rip at 0x7ffff7e2ef40
查看局部变量:
(gdb) info locals
i = 1234
s = "haha"
以Pretty-Print的方式打印变量:
(gdb) p s
$1 = "haha"
获取对象的长度,即cap:
(gdb) p $len(s)
$3 = 4
查看对象类型:
(gdb) whatis i
type = int
(gdb) whatis s
type = struct string
输入n单步执行到进入test函数,查看传递给函数的参数:
(gdb) n
main.test (s="haha", x=1234, r="test: haha 1234") at /home/roy/test.go:11
11 return r
(gdb) info args
s = "haha"
x = 1234
r = "test: haha 1234"
输入q,或者Ctrl-D退出:
(gdb) q
A debugging session is active.
Inferior 1 [process 6079] will be killed.
Quit anyway? (y or n) y
overseas pharmacies that deliver to usa: overseas pharmacies shipping to usa - mexican mail order pharmacy
people play the most. We have developed the system well. เมก้าเกม สล็อต
pg slot games feel to their web based gaming experience. and get the money if you use time to play on this website. http://www.nagagames89.com/
If you are having a hard time deciding between providers, check out the bonuses they offer. The best online casino. ทดลองเล่นสล็อต pg
There are free credits and full slot demo game promotions. There are many games to choose from. ทดลองเล่นสล็อตฟรี
I like the valuable information you provide in your articles. comes with online slots games. The strongest ibizaclub888
เล่นเพลินแถมได้เงินง่าย เว็บตรง ไม่ผ่านเอเย่นต์ บริการเกมสล็อตออนไลน์ ambsuperslot โบนัสแตกสูง แถมยังมีเกมสล็อตมาใหม่อับเดตอยู่เสมอ สล็อตแตกง่าย ทางเข้าเล่นง่าย สามารถสร้างเงินได้ง่ายที่สุดในปัจจุบัน
เล่นสล็อตฟรี สล็อตทดลองซื้อฟรีสปินได้ เล่นสล็อตแตกง่ายได้ทุกวัน ทางเข้าเล่นง่าย เพียงนักเล่นทุกท่าน คลิกเข้ามายังเว็บตรง เว็บไซต์เกมสล็อตออนไลน์ เว็บสล็อตของเราเพื่อรับเครดิตฟรี และทำการ ทดลองเล่นสล็อตฟรี ไม่มีค่าใช้จ่าย
เป็นอีกช่องทางสร้างรายได้ ทดลองเล่นสล็อต pg ซื้อฟรีสปิน เข้าเล่นเลย สล็อตเว็บตรง เกมสล็อตออนไลน์ที่สามารถเข้ามาทำเงิน สร้างกำไรจากการเข้าเล่น สล็อตแตกง่ายสร้างรายได้แบบไม่อั้น เล่นเพลินได้ไม่มีจำกัดเวลา เลือกเล่นสล็อตได้ทุกเกม
สล็อตเว็บตรง ไม่ผ่านเอเย่นต์ นากาสล็อต ไม่ผ่านคนกลาง นักเล่นสายเดิมพันจะไม่มีโดนค่าส่วนต่างอย่างแน่นอน เว็บสล็อตเปิดแล้ว พร้อมให้บริการเล่นเกมสล็อต เลือกได้ทุกค่าย เพิ่มความสนุกมันส์ในการเดิมพันเพิ่มยิ่งขึ้น