funcLookup(name string) *Profile// Lookup returns the profile with the given name,// or nil if no such profile exists.func(p *Profile)WriteTo(w io.Writer, debug int)error// WriteTo writes a pprof-formatted snapshot of the profile to w.// If a write to w returns an error, WriteTo returns that error.// Otherwise, WriteTo returns nil.
Setiap Profil memiliki nama yang unik. Beberapa profil sudah ditentukan sebelumnya:
goroutine - tumpukan jejak dari semua
tumpukan goroutine saat ini - sebuah contoh dari semua alokasi tumpukan
threadcreate - jejak tumpukan yang mengarah ke pembuatan
blok utas OS baru - jejak tumpukan yang menyebabkan pemblokiran pada sinkronisasi primitif
Apakah itu mencetak jejak tumpukan semua goroutine?
Seharusnya, itu panggilan Stack. "Stack mengembalikan pelacakan tumpukan yang diformat dari goroutine yang memanggilnya. Untuk setiap rutinitas, ini menyertakan informasi baris sumber dan nilai PC, kemudian mencoba menemukan, untuk fungsi Go, fungsi atau metode pemanggil dan teks dari baris yang berisi doa."
Intermernet
1
Maaf, ini hanya mencetak jejak tumpukan goroutine.
4
@ HowardGuo Saya telah menambahkan contoh menggunakan runtime / pprof untuk membuang semua jejak tumpukan.
Intermernet
1
Saya pikir ini hanya mengeluarkan setiap utas goroutine yang sedang berjalan, tidak semua goroutine, mis .: play.golang.org/p/0hVB0_LMdm
rogerdpack
41
Ada frontend HTTP untuk runtime/pprofpaket yang disebutkan dalam jawaban Intermernet. Impor paket net / http / pprof untuk mendaftarkan penangan HTTP untuk /debug/pprof:
Kemudian arahkan browser ke http://localhost:6060/debug/pprofmenu, atau http://localhost:6060/debug/pprof/goroutine?debug=2untuk tumpukan dump goroutine lengkap.
Ada hal menyenangkan lainnya yang dapat Anda pelajari tentang kode yang sedang berjalan dengan cara ini juga. Lihat entri blog untuk mengetahui contoh dan detail lebih lanjut:
http://blog.golang.org/profiling-go-programs
saya membuatnya berjalan dengan itu hanya menunjukkan goroutine yang dieksekusi sejauh yang saya lihat. Apakah ada cara agar saya bisa melihat semua "metode" yang dijalankan setelah main.go diluncurkan?
Lukas Lukac
38
Untuk meniru perilaku Java stack-dump di SIGQUIT tetapi tetap membiarkan program berjalan:
Saya rasa inilah yang sebenarnya dicari oleh penulis- meniru apa yang dilakukan Java ketika Anda mengirim kill -QUIT. Satu perubahan kecil yang harus saya lakukan adalah mengubah baris pertama loop for () menjadi: "<- sigs". Dengan kata lain, buang saja sinyal setelah menunggu. Versi terbaru Go tidak mengizinkan Anda mendeklarasikan variabel tanpa menggunakannya nanti.
George Armhold
@ Bryan, apakah Anda bersedia melisensikan ini di bawah BSD atau persyaratan lain yang lebih permisif tambahan untuk CC-BY-SA 3.0 yang disyaratkan oleh StackOverflow?
Mirip dengan Java, SIGQUIT dapat digunakan untuk mencetak jejak tumpukan program Go dan goroutine-nya.
Perbedaan utama, bagaimanapun, adalah bahwa secara default mengirim SIGQUIT ke program Java tidak menghentikannya, sementara program Go keluar.
Pendekatan ini tidak memerlukan perubahan kode untuk mencetak jejak tumpukan semua goroutine dari program yang ada.
Variabel lingkungan GOTRACEBACK ( lihat dokumentasi paket runtime ) mengontrol jumlah keluaran yang dihasilkan. Misalnya, untuk menyertakan semua goroutine, setel GOTRACEBACK = all.
Pencetakan pelacakan tumpukan dipicu oleh kondisi waktu proses yang tidak terduga (sinyal tidak tertangani), yang awalnya didokumentasikan dalam pengubahan ini , membuatnya tersedia setidaknya sejak Go 1.1.
Atau, jika memodifikasi kode sumber adalah sebuah pilihan, lihat jawaban lain.
Perhatikan bahwa di terminal Linux, SIGQUIT dapat dengan mudah dikirim dengan kombinasi tombol Ctrl+ \.
Saat melihat-lihat dokumen, saya tidak menemukan menyebutkan SIGQUIT, melainkan SIGABRT. Dari pengujian saya sendiri (dengan go 1.7) yang terakhir juga bekerja di atas yang pertama.
soltysh
4
ini harus menjadi jawaban teratas.
Steven Soroka
Dokumen mengacu pada "ketika program Go gagal karena kepanikan yang belum pulih atau kondisi runtime yang tidak terduga". Sinyal yang tidak tertangkap (SIGQUIT, dll) adalah salah satu yang terakhir. Mengapa saya menyebutkan SIGQUIT? Karena OP mengungkapkan kecintaannya pada penggunaan SIGQUIT dengan Java, dan jawaban ini menekankan kesamaan. Mengucapkan ulang jawaban agar lebih jelas.
Rodolfo Carvalho
26
Anda bisa menggunakan runtime.Stack untuk mendapatkan pelacakan tumpukan semua goroutine:
Stack memformat pelacakan tumpukan dari pemanggilan goroutine ke dalam buf dan mengembalikan jumlah byte yang ditulis ke buf. Jika semuanya benar, format Stack menumpuk jejak dari semua goroutine lain ke dalam buf setelah jejak goroutine saat ini.
Ini termasuk jejak belakang dari semua goroutine, bagus!
rogerdpack
Apakah ini format yang digunakan oleh kepanikan yang belum pulih?
Ztyx
2
Jangan lupa untuk menambahkan string (buf) atau Anda akan mencetak byte mentah di sana.
koda
2
Mungkin saya melakukan sesuatu yang salah, atau mungkin fungsinya telah berubah, tetapi ini tidak mengambil apa pun untuk saya kecuali sepotong byte kosong?
17xande
1
@koda tidak perlu melakukan di string(buf)sini, fmt.Printf("%s", buf)dan fmt.Printf("%s", string(buf))melakukan hal yang persis sama (lihat dokumen untuk fmtpaket); satu-satunya perbedaan di sini adalah bahwa stringversi akan menyalin byte dari yang buftidak perlu
kbolino
20
Tekan CTRL + \
(Jika Anda menjalankannya di terminal dan hanya ingin mematikan program Anda dan membuang rutinitas go, dll.)
Saya menemukan pertanyaan ini mencari urutan kuncinya. Hanya ingin cara cepat dan mudah untuk mengetahui apakah program saya membocorkan rutinitas go :)
Rupanya, mengirim SIGQUIT ke proses Java tidak menghentikannya seperti yang akan dilakukan SIGABRT.
Dave C
Saya menemukan ini sebagai solusi paling sederhana dan paling cocok dengan pertanyaan asli. Seringkali Anda membutuhkan stacktrace segera, tanpa mengubah kode Anda.
jotrocken
5
Anda perlu menggunakan panjang yang dikembalikan oleh runtime.Stack()untuk menghindari mencetak banyak garis kosong setelah jejak tumpukan Anda. Fungsi pemulihan berikut mencetak jejak yang diformat dengan baik:
if r := recover(); r != nil {
log.Printf("Internal error: %v", r))
buf := make([]byte, 1<<16)
stackSize := runtime.Stack(buf, true)
log.Printf("%s\n", string(buf[0:stackSize]))
}
GOTRACEBACK=single(default) berperilaku seperti yang dijelaskan di atas.
GOTRACEBACK=all menambahkan pelacakan tumpukan untuk semua goroutine buatan pengguna.
GOTRACEBACK=system seperti "semua '' tetapi menambahkan frame stack untuk fungsi run-time dan menampilkan goroutine yang dibuat secara internal oleh run-time.
GOTRACEBACK=crashseperti `` sistem '' tetapi macet dengan cara khusus sistem operasi alih-alih keluar. Misalnya, pada sistem Unix, crash muncul SIGABRTuntuk memicu dump inti.
Variabel GOTRACEBACK mengontrol jumlah output yang dihasilkan saat program Go gagal karena kepanikan yang belum pulih atau kondisi waktu proses yang tidak terduga.
Secara default, kegagalan mencetak pelacakan tumpukan untuk goroutine saat ini, memilih fungsi internal ke sistem run-time, lalu keluar dengan kode keluar 2. Kegagalan mencetak jejak tumpukan untuk semua goroutine jika tidak ada goroutine saat ini atau kegagalannya internal ke run-time.
Untuk alasan historis, setelan GOTRACEBACK 0, 1, dan 2 adalah sinonim untuk masing-masing tidak ada, semua, dan sistem.
Fungsi SetTraceback paket runtime / debug memungkinkan peningkatan jumlah output pada waktu proses, tetapi tidak dapat mengurangi jumlah di bawah yang ditentukan oleh variabel lingkungan. Lihat https://golang.org/pkg/runtime/debug/#SetTraceback .
Jawaban:
Untuk mencetak jejak tumpukan untuk goroutine saat ini , gunakan
PrintStack()
fromruntime/debug
.Sebagai contoh:
import( "runtime/debug" ) ... debug.PrintStack()
Untuk mencetak jejak tumpukan untuk semua penggunaan
Lookup
danWriteTo
dari goroutineruntime/pprof
.func Lookup(name string) *Profile // Lookup returns the profile with the given name, // or nil if no such profile exists. func (p *Profile) WriteTo(w io.Writer, debug int) error // WriteTo writes a pprof-formatted snapshot of the profile to w. // If a write to w returns an error, WriteTo returns that error. // Otherwise, WriteTo returns nil.
Sebagai contoh:
pprof.Lookup("goroutine").WriteTo(os.Stdout, 1)
sumber
Stack
. "Stack mengembalikan pelacakan tumpukan yang diformat dari goroutine yang memanggilnya. Untuk setiap rutinitas, ini menyertakan informasi baris sumber dan nilai PC, kemudian mencoba menemukan, untuk fungsi Go, fungsi atau metode pemanggil dan teks dari baris yang berisi doa."Ada frontend HTTP untuk
runtime/pprof
paket yang disebutkan dalam jawaban Intermernet. Impor paket net / http / pprof untuk mendaftarkan penangan HTTP untuk/debug/pprof
:import _ "net/http/pprof" import _ "net/http"
Mulai pendengar HTTP jika Anda belum memilikinya:
go func() { log.Println(http.ListenAndServe("localhost:6060", nil)) }()
Kemudian arahkan browser ke
http://localhost:6060/debug/pprof
menu, atauhttp://localhost:6060/debug/pprof/goroutine?debug=2
untuk tumpukan dump goroutine lengkap.Ada hal menyenangkan lainnya yang dapat Anda pelajari tentang kode yang sedang berjalan dengan cara ini juga. Lihat entri blog untuk mengetahui contoh dan detail lebih lanjut: http://blog.golang.org/profiling-go-programs
sumber
Untuk meniru perilaku Java stack-dump di SIGQUIT tetapi tetap membiarkan program berjalan:
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("=== received SIGQUIT ===\n*** goroutine dump...\n%s\n*** end\n", buf[:stacklen]) } }()
sumber
Mirip dengan Java, SIGQUIT dapat digunakan untuk mencetak jejak tumpukan program Go dan goroutine-nya.
Perbedaan utama, bagaimanapun, adalah bahwa secara default mengirim SIGQUIT ke program Java tidak menghentikannya, sementara program Go keluar.
Pendekatan ini tidak memerlukan perubahan kode untuk mencetak jejak tumpukan semua goroutine dari program yang ada.
Variabel lingkungan GOTRACEBACK ( lihat dokumentasi paket runtime ) mengontrol jumlah keluaran yang dihasilkan. Misalnya, untuk menyertakan semua goroutine, setel GOTRACEBACK = all.
Pencetakan pelacakan tumpukan dipicu oleh kondisi waktu proses yang tidak terduga (sinyal tidak tertangani), yang awalnya didokumentasikan dalam pengubahan ini , membuatnya tersedia setidaknya sejak Go 1.1.
Atau, jika memodifikasi kode sumber adalah sebuah pilihan, lihat jawaban lain.
Perhatikan bahwa di terminal Linux, SIGQUIT dapat dengan mudah dikirim dengan kombinasi tombol Ctrl+ \.
sumber
Anda bisa menggunakan runtime.Stack untuk mendapatkan pelacakan tumpukan semua goroutine:
buf := make([]byte, 1<<16) runtime.Stack(buf, true) fmt.Printf("%s", buf)
Dari dokumentasi:
func Stack(buf []byte, all bool) int
sumber
string(buf)
sini,fmt.Printf("%s", buf)
danfmt.Printf("%s", string(buf))
melakukan hal yang persis sama (lihat dokumen untukfmt
paket); satu-satunya perbedaan di sini adalah bahwastring
versi akan menyalin byte dari yangbuf
tidak perluTekan CTRL + \
(Jika Anda menjalankannya di terminal dan hanya ingin mematikan program Anda dan membuang rutinitas go, dll.)
Saya menemukan pertanyaan ini mencari urutan kuncinya. Hanya ingin cara cepat dan mudah untuk mengetahui apakah program saya membocorkan rutinitas go :)
sumber
Pada sistem * NIX (termasuk OSX) mengirim sinyal batal
SIGABRT
:pkill -SIGABRT program_name
sumber
Anda perlu menggunakan panjang yang dikembalikan oleh
runtime.Stack()
untuk menghindari mencetak banyak garis kosong setelah jejak tumpukan Anda. Fungsi pemulihan berikut mencetak jejak yang diformat dengan baik:if r := recover(); r != nil { log.Printf("Internal error: %v", r)) buf := make([]byte, 1<<16) stackSize := runtime.Stack(buf, true) log.Printf("%s\n", string(buf[0:stackSize])) }
sumber
runtime.Trace
;runtime.Stack
sudah disebutkan satu setengah tahun yang lalu .Secara default, tekan
^\
tombol ( CTRL + \ ) untuk membuang jejak tumpukan semua goroutine.Jika tidak, untuk kontrol yang lebih terperinci, Anda dapat menggunakan
panic
. Cara sederhana mulai Go 1.6+ :go func() { s := make(chan os.Signal, 1) signal.Notify(s, syscall.SIGQUIT) <-s panic("give me the stack") }()
Kemudian, jalankan program Anda seperti ini:
# Press ^\ to dump the stack traces of all the user-created goroutines $ GOTRACEBACK=all go run main.go
Jika Anda juga ingin mencetak go runtime goroutine:
$ GOTRACEBACK=system go run main.go
Berikut semua opsi GOTRACEBACK:
GOTRACEBACK=none
menghilangkan jejak tumpukan goroutine seluruhnya.GOTRACEBACK=single
(default) berperilaku seperti yang dijelaskan di atas.GOTRACEBACK=all
menambahkan pelacakan tumpukan untuk semua goroutine buatan pengguna.GOTRACEBACK=system
seperti "semua '' tetapi menambahkan frame stack untuk fungsi run-time dan menampilkan goroutine yang dibuat secara internal oleh run-time.GOTRACEBACK=crash
seperti `` sistem '' tetapi macet dengan cara khusus sistem operasi alih-alih keluar. Misalnya, pada sistem Unix, crash munculSIGABRT
untuk memicu dump inti.Berikut dokumentasinya
sumber