2013-12-18 70 views
6

go test命令具有用於-c標誌支撐,描述如下:如何使用GDB正確調試`go test -c`生成的二進制文件?

-c Compile the test binary to pkg.test but do not run it. 
    (Where pkg is the last element of the package's import path.) 

據我明白了,產生這樣一個二進制是交互方式使用GDB來運行它的方式。然而,由於測試的二進制是由一些的/ tmp /目錄暫時結合源和測試文件創建,這是發生了什麼,當我在gdb運行list

Loading Go Runtime support. 
(gdb) list 
42  github.com/<username>/<project>/_test/_testmain.go: No such file or directory. 

這意味着我不能快樂地檢查圍棋源GDB中的代碼就像我習慣的那樣。我知道可以通過將-work標誌傳遞給go test命令來強制臨時目錄停留,但這仍然是一個巨大的麻煩,因爲二進制文件不是在該目錄等中創建的。我想知道是否有人發現這個問題的乾淨解決方案。

回答

2

不幸的是,這似乎是一個尚未解決的已知問題。看到這個討論:

https://groups.google.com/forum/#!topic/golang-nuts/nIA09gp3eNU

我已經看到了兩個解決這個問題。

1)使用設置的替代路徑命令創建一個.gdbinit文件到 將gdb重定向到源的實際位置。該文件可能是由go工具生成的 ,但您可能會冒險覆蓋某人的自定義 .gdbinit文件,並將go工具綁定到gdb,這似乎是一個不好的 想法。

2)將可執行文件(將 指向/ tmp/...)中的源文件路徑替換爲它們駐留在磁盤上的位置。如果真實路徑比/ tmp/...路徑短,則這是直接的 。 這可能需要編譯器/ 鏈接器的額外支持才能使此解決方案更通用。

這催生了對圍棋谷歌代碼問題跟蹤這個問題,對此判決結束了:

https://code.google.com/p/go/issues/detail?id=2881

這很煩人,但它是最的多煩人的可能性。 通常,go工具不應該在 目錄中塗寫,這些目錄甚至可能不可寫,並且在退出後不應在 之外的地方留下文件。 _testmain.go中沒有什麼 有趣。用gdb測試的人可以在 測試中打破。

拉斯 狀態:不幸

因此,簡而言之,它很爛,而你可以解決它和GDB測試可執行文件,開發團隊是不太可能使它容易,因爲它可能是爲你。

0

我還是新來的golang遊戲,但它的價值基本調試似乎工作。

只要您已經在代碼中的某個斷點處,就可以使用您嘗試工作的列表命令。例如:

(gdb) b aws.go:54 
Breakpoint 1 at 0x61841: file /Users/mat/gocode/src/github.com/stellar/deliverator/aws/aws.go, line 54. 
(gdb) r 
Starting program: /Users/mat/gocode/src/github.com/stellar/deliverator/aws/aws.test 
[snip: some arnings about BinaryCache] 

Breakpoint 1, github.com/stellar/deliverator/aws.imageIsNewer (latest=0xc2081fe2d0, ami=0xc2081fe3c0, ~r2=false) 
    at /Users/mat/gocode/src/github.com/stellar/deliverator/aws/aws.go:54 
54  layout := "2006-01-02T15:04:05.000Z" 
(gdb) list 
49 func imageIsNewer(latest *ec2.Image, ami *ec2.Image) bool { 
50  if latest == nil { 
51   return true 
52  } 
53 
54  layout := "2006-01-02T15:04:05.000Z" 
55 
56  amiCreationTime, amiErr := time.Parse(layout, *ami.CreationDate) 
57  if amiErr != nil { 
58   panic(amiErr) 

這只是運行在aws子目錄我的項目的以下後:

go test -c 
gdb aws.test 

作爲一個額外的警告,它似乎在哪裏斷點可以放在非常有選擇性。似乎它必須是一個表達式,但結論只能通過實驗。

0

Go 1.5已經發布,並且還沒有官方認可的Go調試器。使用GDB有效地調試Go程序或測試二進制文件,我沒有取得太大的成功。不過,我一直在使用藏坑,即仍處於發展的一個非官方的調試器取得了成功:https://github.com/derekparker/delve

要運行在調試器中測試代碼,只需安裝鑽研:

go get -u github.com/derekparker/delve/cmd/dlv

...然後從您的工作空間內開始調試測試:

dlv test

從調試器提示,您可以單步,設置斷點,等等。

給它一個旋轉!

0

如果您願意使用GDB以外的工具,請查看godebug。要使用它,先用安裝:

go get github.com/mailgun/godebug 

接下來,通過將以下語句添加到您的代碼中插入某處斷點:

_ = "breakpoint" 

現在用godebug test命令運行測試。

godebug test 

它支持來自go test命令的許多參數。

-test.bench string 
     regular expression per path component to select benchmarks to run 
    -test.benchmem 
     print memory allocations for benchmarks 
    -test.benchtime duration 
     approximate run time for each benchmark (default 1s) 
    -test.blockprofile string 
     write a goroutine blocking profile to the named file after execution 
    -test.blockprofilerate int 
     if >= 0, calls runtime.SetBlockProfileRate() (default 1) 
    -test.count n 
     run tests and benchmarks n times (default 1) 
    -test.coverprofile string 
     write a coverage profile to the named file after execution 
    -test.cpu string 
     comma-separated list of number of CPUs to use for each test 
    -test.cpuprofile string 
     write a cpu profile to the named file during execution 
    -test.memprofile string 
     write a memory profile to the named file after execution 
    -test.memprofilerate int 
     if >=0, sets runtime.MemProfileRate 
    -test.outputdir string 
     directory in which to write profiles 
    -test.parallel int 
     maximum test parallelism (default 4) 
    -test.run string 
     regular expression to select tests and examples to run 
    -test.short 
     run smaller test suite to save time 
    -test.timeout duration 
     if positive, sets an aggregate time limit for all tests 
    -test.trace string 
     write an execution trace to the named file after execution 
    -test.v 
     verbose: print additional output 
相關問題