J'ai une expérience en Java, et j'adore utiliser le signal QUIT pour inspecter le vidage de thread Java.
Comment faire en sorte que Golang imprime toutes les traces de pile des goroutines ?
J'ai une expérience en Java, et j'adore utiliser le signal QUIT pour inspecter le vidage de thread Java.
Comment faire en sorte que Golang imprime toutes les traces de pile des goroutines ?
Pour imprimer la trace de la pile pour la goroutine actuelle, utilisez PrintStack()
de runtime/debug
..
PrintStack imprime sur la sortie d'erreur standard la trace de la pile retournée par Stack.
Par exemple:
import(
"runtime/debug"
)
...
debug.PrintStack()
Pour imprimer la trace de la pile de toutes les goroutines, utilisez Lookup
et WriteTo
de runtime/pprof
.
func Lookup(name string) *Profile
// Lookup retourne le profil avec le nom donné,
// ou nil s'il n'existe pas.
func (p *Profile) WriteTo(w io.Writer, debug int) error
// WriteTo écrit un instantané formaté pprof du profil sur w.
// Si une écriture sur w retourne une erreur, WriteTo renvoie cette erreur.
// Sinon, WriteTo renvoie nil.
Chaque Profile a un nom unique. Quelques profils sont prédéfinis:
goroutine - traces de piles de toutes les goroutines actuelles
heap - un échantillonnage de toutes les allocations de la mémoire heap
threadcreate - traces de piles qui ont conduit à la création de nouveaux threads OS
block - traces de piles qui ont conduit à un blocage sur des primitives de synchronisation
Par exemple:
pprof.Lookup("goroutine").WriteTo(os.Stdout, 1)
Il existe un frontend HTTP pour le package runtime/pprof
mentionné dans la réponse d'Intermernet. Importez le package net/http/pprof pour enregistrer un gestionnaire HTTP pour /debug/pprof
:
import _ "net/http/pprof"
import _ "net/http"
Démarrer un écouteur HTTP si vous n'en avez pas déjà un :
go func() {
log.Println(http.ListenAndServe("localhost:6060", nil))
}()
Ensuite, pointez un navigateur vers http://localhost:6060/debug/pprof
pour un menu, ou http://localhost:6060/debug/pprof/goroutine?debug=2
pour un vidage complet de la pile de goroutine.
Il y a d'autres choses intéressantes que vous pouvez apprendre sur votre code en cours d'exécution de cette manière. Consultez l'article de blog pour des exemples et plus de détails : http://blog.golang.org/profiling-go-programs
Tout comme en Java, SIGQUIT peut être utilisé pour imprimer une trace de pile d'un programme Go et de ses goroutines.
Une différence clé, cependant, est que l'envoi de SIGQUIT aux programmes Java par défaut ne les termine pas, tandis que les programmes Go le font.
Cette approche ne nécessite aucun changement de code pour imprimer une trace de pile de toutes les goroutines des programmes existants.
La variable d'environnement GOTRACEBACK (voir la documentation du package runtime) contrôle la quantité de sortie générée. Par exemple, pour inclure toutes les goroutines, définissez GOTRACEBACK sur all.
L'impression de la trace de la pile est déclenchée par une condition d'exécution inattendue (signal non géré), initialement documentée dans ce commit, la rendant disponible depuis au moins la version 1.1 de Go.
Alternativement, si la modification du code source est une option, voir d'autres réponses.
Notez qu'à partir d'un terminal Linux, SIGQUIT peut être envoyé facilement avec la combinaison de touches Ctrl+\.
Pour imiter le comportement Java de stack-dump sur SIGQUIT tout en laissant le programme s'exécuter :
go func() {
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGQUIT)
buf := make([]byte, 1<<20)
for {
<-sigs
stacklen := runtime.Stack(buf, true)
log.Printf("=== reçu SIGQUIT ===\n*** dump de la goroutine...\n%s\n*** fin\n", buf[:stacklen])
}
}()
Vous pouvez utiliser runtime.Stack pour obtenir la trace de la pile de toutes les goroutines :
buf := make([]byte, 1<<16)
runtime.Stack(buf, true)
fmt.Printf("%s", buf)
De la documentation :
func Stack(buf []byte, all bool) int
Stack formate une trace de pile de la goroutine appelante dans le buf et renvoie le nombre d'octets écrits dans le buf. Si all est vrai, Stack formate les traces de pile de toutes les autres goroutines dans le buf après la trace pour la goroutine actuelle.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.