2013-12-18 7 views
6

Il go test comando ha il supporto per il flag -c, descritto come segue:Come debugare correttamente un binario generato da `go test -c` usando GDB?

-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.) 

Per quanto ho capito, generando un binario come questo è il modo per farlo funzionare in modo interattivo utilizzando GDB. Tuttavia, dal momento che il binario di prova viene creata combinando i file di origine e di test temporaneamente in qualche tmp/directory /, questo è ciò che accade quando corro list in gdb:

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

Questo significa che non posso felicemente ispezionare la fonte Go codice in GDB come sono abituato. So che è possibile forzare la directory temporanea a rimanere passando il flag -work al comando go test, ma in questo caso è ancora una seccatura enorme poiché il file binario non viene creato in tale directory e così via. Mi chiedevo se qualcuno avesse trovato una soluzione pulita a questo problema.

risposta

2

Sfortunatamente, questo sembra essere un problema noto che non verrà risolto. Vedere la discussione:

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

Ho visto due soluzioni a questo problema.

1) creare un file .gdbinit con un comando set-replace-path su reindirizzare gdb alla posizione effettiva dell'origine. Questo file potrebbe essere generato dallo strumento go, ma rischieresti di sovrascrivere il file personalizzato .gdbinit e legherei lo strumento go a gdb che sembra una cattiva idea .

2) Sostituire i percorsi del file di origine nell'eseguibile (che puntano a in/tmp/...) con il percorso in cui risiedono sul disco. Questo è diretto se il percorso reale è più breve del percorso/tmp/.... Questo probabilmente richiederebbe ulteriore supporto dal compilatore/ linker per rendere questa soluzione più generica.

Esso ha generato questo problema sulla questione inseguitore Go Google Code, per cui la decisione ha finito per essere:

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

Questo è fastidioso, ma è l'ultima delle molte possibilità fastidiosi . Come regola, lo strumento go non deve essere scarabocchiato nelle directory di origine , che potrebbero non essere nemmeno scrivibili, e non dovrebbe essere lasciare file altrove dopo la sua uscita. Non c'è quasi nulla di interessante in _testmain.go . Le persone che eseguono test con gdb possono interrompere il test .

Russ Stato: Sfortunato

Così, in breve, fa schifo, e mentre si può lavorare intorno ad esso e GDB un eseguibile di prova, il team di sviluppo è improbabile che rendere il più semplice come potrebbe essere per te.

0

Sono ancora nuovo per il gioco golang ma per quello che vale il debug di base sembra funzionare.

Il comando di elenco che si sta tentando di utilizzare può essere utilizzato fino a quando si è già in un punto di interruzione da qualche parte nel codice. Per esempio:

(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) 

Questo è solo dopo aver eseguito quanto segue nella aws sottodirectory del mio progetto:

go test -c 
gdb aws.test 

Come un avvertimento addizionale, sembra molto selettiva, in cui i punti di interruzione possono essere posizionati. Sembra che debba essere un'espressione, ma quella conclusione è solo attraverso la sperimentazione.

0

Go 1.5 è stato rilasciato e non esiste ancora un debugger Go ufficialmente autorizzato. Non ho avuto molto successo usando GDB per debugging efficace dei programmi Go o dei binari di test. Tuttavia, ho avuto successo con Delve, un debugger non ufficiale che è ancora in fase di sviluppo: https://github.com/derekparker/delve

per eseguire il codice di prova nel debugger, è sufficiente installare Delve:

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

... e quindi avviare i test nel debugger da dentro l'area di lavoro:

dlv test

dal prompt debugger, è possibile single-step, set di punti di interruzione, ecc

Dai un vortice!

0

Se sei disposto a utilizzare strumenti oltre a GDB, controlla godebug. Per usarlo, installare prima con:

go get github.com/mailgun/godebug 

Avanti, inserire un punto di interruzione da qualche aggiungendo la seguente istruzione al codice:

_ = "breakpoint" 

Ora eseguire i test con il comando godebug test.

godebug test 

Supporta molti dei parametri dal comando 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