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.
Каждый профиль имеет уникальное имя. Несколько профилей предопределены:
goroutine - трассировки стека всех текущих горутин,
куча - выборка всех распределений кучи
threadcreate - трассировки стека, которые привели к созданию нового
блока потоков ОС - трассировки стека, которые привели к блокировке примитивов синхронизации
Он должен, зовет Stack. "Стек возвращает отформатированную трассировку стека горутины, которая его вызывает. Для каждой процедуры он включает информацию о строке источника и значение ПК, а затем пытается обнаружить для функций Go вызывающую функцию или метод и текст строки, содержащей призыв ".
Intermernet
1
Извините, он печатает только текущую трассировку стека горутины.
4
@HowardGuo Я добавил пример использования runtime / pprof для выгрузки всех трассировок стека.
Существует HTTP-интерфейс для runtime/pprofпакета, упомянутого в ответе Intermernet. Импортируйте пакет net / http / pprof , чтобы зарегистрировать обработчик HTTP для /debug/pprof:
import _ "net/http/pprof"import _ "net/http"
Запустите прослушиватель HTTP, если у вас его еще нет:
Затем укажите в браузере http://localhost:6060/debug/pprofменю или http://localhost:6060/debug/pprof/goroutine?debug=2полный дамп стека горутин.
Таким образом вы также можете узнать о своем работающем коде и другие интересные вещи. Ознакомьтесь с сообщениями в блоге для примеров и более подробной информации:
http://blog.golang.org/profiling-go-programs
Я запустил его, он показывает только выполненные горутины, насколько я понимаю. Могу ли я увидеть все «методы», которые выполняются после запуска main.go?
Лукас Лукач
38
Чтобы имитировать поведение Java при выводе дампа стека при SIGQUIT, но при этом оставив программу работающей:
Я думаю, это то, что действительно искал автор - имитирует то, что делает Java, когда вы отправляете kill -QUIT. Одно небольшое изменение, которое мне пришлось сделать, - это изменить первую строку цикла for () на «<- sigs». Другими словами, просто сбросьте сигнал, дождавшись его. Последние версии Go не позволяют объявлять переменную без ее последующего использования.
Джордж Армхолд
@Bryan, готовы ли вы лицензировать это в соответствии с BSD или другими более разрешительными условиями в дополнение к CC-BY-SA 3.0, требуемому StackOverflow?
Подобно Java, SIGQUIT можно использовать для печати трассировки стека программы Go и ее горутин.
Однако ключевое отличие состоит в том, что по умолчанию отправка SIGQUIT программам Java не завершает их, в то время как программы Go завершаются.
Этот подход не требует изменения кода для печати трассировки стека всех горутин существующих программ.
Переменная среды GOTRACEBACK ( см. Документацию к пакету времени выполнения ) контролирует объем создаваемого вывода. Например, чтобы включить все горутины, установите GOTRACEBACK = all.
Печать трассировки стека запускается неожиданным условием выполнения (необработанный сигнал), изначально задокументированным в этом коммите , что делает его доступным по крайней мере с версии Go 1.1.
В качестве альтернативы, если можно изменить исходный код, см. Другие ответы.
Обратите внимание, что в терминале Linux SIGQUIT можно удобно отправить с помощью комбинации клавиш Ctrl+ \.
Просматривая документы, я не нашел упоминаний о SIGQUIT, точнее о SIGABRT. Судя по моим собственным тестам (с go 1.7), последний также работал над первым.
солтыш
4
это должен быть главный ответ.
Стивен Сорока
В документации говорится о «сбое программы Go из-за неисправной паники или непредвиденного состояния выполнения». Неперехваченный сигнал (SIGQUIT и т. Д.) Является одним из последних. Почему я упомянул SIGQUIT? Поскольку OP выражает свою любовь к использованию SIGQUIT с Java, и этот ответ подчеркивает сходство. Перефразируем ответ, чтобы было понятнее.
Родольфо Карвалью
26
Вы можете использовать runtime.Stack, чтобы получить трассировку стека всех горутин:
Стек форматирует трассировку стека вызывающей горутины в buf и возвращает количество байтов, записанных в buf. Если все верно, Stack форматирует трассировки стека всех других горутин в buf после трассировки для текущей горутины.
Неужели это тот формат, который сводится к использованию невосстановленной паники?
Ztyx
2
Не забудьте добавить строку (buf), иначе вы напечатаете туда необработанные байты.
koda
2
Может быть, я делаю что-то не так, или, возможно, изменилась функциональность, но это не возвращает мне ничего, кроме пустого фрагмента байтов?
17xande 03
1
@koda нет необходимости делать string(buf)здесь, fmt.Printf("%s", buf)и fmt.Printf("%s", string(buf))сделать то же самое (см документации для fmtпакета); единственная разница здесь в том, что stringверсия будет копировать байты bufбез нужды
kbolino
20
Нажмите CTRL + \
(Если вы запускаете его в терминале и просто хотите убить свою программу и сбросить подпрограммы go и т. Д.)
Я нашел этот вопрос в поисках ключевой последовательности. Просто хотел быстрый и простой способ узнать, не утекает ли моя программа подпрограммы go :)
Очевидно, отправка SIGQUIT процессу Java не завершает его, как SIGABRT.
Dave C
Я обнаружил, что это самое простое и наиболее подходящее решение исходного вопроса. Часто вам нужна трассировка стека сразу, без изменения кода.
jotrocken
5
Необходимо использовать длину, возвращаемую до, runtime.Stack()чтобы не печатать кучу пустых строк после трассировки стека. Следующая функция восстановления распечатывает красиво отформатированную трассировку:
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]))
}
Я такого никогда не видел; на какой платформе вы работаете?
Брайан
Что вы еще не видели? Код должен работать на всех платформах; Я тестировал его на Windows 7, Ubuntu 14.04 и Mac.
Дэвид Тотилл
Никогда не видел пустых строк.
Bryan
4
По умолчанию нажмите ^\клавиши ( CTRL + \ ), чтобы выгрузить трассировку стека всех горутин.
В противном случае для более детального контроля вы можете использовать panic. Простой способ для Go 1.6+ :
gofunc() {
s := make(chan os.Signal, 1)
signal.Notify(s, syscall.SIGQUIT)
<-s
panic("give me the stack")
}()
Затем запустите вашу программу так:
# Press ^\ to dump the stack traces of all the user-created goroutines
$ GOTRACEBACK=all go run main.go
Если вы также хотите распечатать горутины времени выполнения:
$ GOTRACEBACK=system go run main.go
Вот все варианты GOTRACEBACK:
GOTRACEBACK=none полностью исключает трассировку стека горутин.
GOTRACEBACK=single(по умолчанию) ведет себя, как описано выше.
GOTRACEBACK=all добавляет трассировки стека для всех горутин, созданных пользователем.
GOTRACEBACK=system похож на `` все '', но добавляет фреймы стека для функций времени выполнения и показывает горутины, созданные внутри среды выполнения.
GOTRACEBACK=crashпохоже на `` систему '', но вместо выхода происходит сбой в зависимости от операционной системы. Например, в системах Unix возникает сбой, вызывающий SIGABRTдамп ядра.
Переменная GOTRACEBACK контролирует количество выходных данных, генерируемых при сбое программы Go из-за невосстановленной паники или неожиданного условия выполнения.
По умолчанию при сбое печатается трассировка стека для текущей горутины, исключаются функции, внутренние для системы времени выполнения, и затем выполняется выход с кодом выхода 2. При сбое печатаются трассировки стека для всех горутин, если текущей горутины нет или сбой произошел. внутренний по отношению к времени выполнения.
По историческим причинам настройки GOTRACEBACK 0, 1 и 2 являются синонимами для none, all и system соответственно.
Функция SetTraceback пакета среды выполнения / отладки позволяет увеличить объем вывода во время выполнения, но не может уменьшить объем ниже указанного в переменной среды. См. Https://golang.org/pkg/runtime/debug/#SetTraceback .
Ответы:
Чтобы распечатать трассировку стека для текущей горутины, используйте
PrintStack()
fromruntime/debug
.Например:
import( "runtime/debug" ) ... debug.PrintStack()
Чтобы распечатать трассировку стека для всех горутин, используйте
Lookup
иWriteTo
изruntime/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.
Например:
pprof.Lookup("goroutine").WriteTo(os.Stdout, 1)
источник
Stack
. "Стек возвращает отформатированную трассировку стека горутины, которая его вызывает. Для каждой процедуры он включает информацию о строке источника и значение ПК, а затем пытается обнаружить для функций Go вызывающую функцию или метод и текст строки, содержащей призыв ".Существует HTTP-интерфейс для
runtime/pprof
пакета, упомянутого в ответе Intermernet. Импортируйте пакет net / http / pprof , чтобы зарегистрировать обработчик HTTP для/debug/pprof
:import _ "net/http/pprof" import _ "net/http"
Запустите прослушиватель HTTP, если у вас его еще нет:
go func() { log.Println(http.ListenAndServe("localhost:6060", nil)) }()
Затем укажите в браузере
http://localhost:6060/debug/pprof
меню илиhttp://localhost:6060/debug/pprof/goroutine?debug=2
полный дамп стека горутин.Таким образом вы также можете узнать о своем работающем коде и другие интересные вещи. Ознакомьтесь с сообщениями в блоге для примеров и более подробной информации: http://blog.golang.org/profiling-go-programs
источник
Чтобы имитировать поведение Java при выводе дампа стека при SIGQUIT, но при этом оставив программу работающей:
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]) } }()
источник
Подобно Java, SIGQUIT можно использовать для печати трассировки стека программы Go и ее горутин.
Однако ключевое отличие состоит в том, что по умолчанию отправка SIGQUIT программам Java не завершает их, в то время как программы Go завершаются.
Этот подход не требует изменения кода для печати трассировки стека всех горутин существующих программ.
Переменная среды GOTRACEBACK ( см. Документацию к пакету времени выполнения ) контролирует объем создаваемого вывода. Например, чтобы включить все горутины, установите GOTRACEBACK = all.
Печать трассировки стека запускается неожиданным условием выполнения (необработанный сигнал), изначально задокументированным в этом коммите , что делает его доступным по крайней мере с версии Go 1.1.
В качестве альтернативы, если можно изменить исходный код, см. Другие ответы.
Обратите внимание, что в терминале Linux SIGQUIT можно удобно отправить с помощью комбинации клавиш Ctrl+ \.
источник
Вы можете использовать runtime.Stack, чтобы получить трассировку стека всех горутин:
buf := make([]byte, 1<<16) runtime.Stack(buf, true) fmt.Printf("%s", buf)
Из документации:
func Stack(buf []byte, all bool) int
источник
string(buf)
здесь,fmt.Printf("%s", buf)
иfmt.Printf("%s", string(buf))
сделать то же самое (см документации дляfmt
пакета); единственная разница здесь в том, чтоstring
версия будет копировать байтыbuf
без нуждыНажмите CTRL + \
(Если вы запускаете его в терминале и просто хотите убить свою программу и сбросить подпрограммы go и т. Д.)
Я нашел этот вопрос в поисках ключевой последовательности. Просто хотел быстрый и простой способ узнать, не утекает ли моя программа подпрограммы go :)
источник
В системах * NIX (включая OSX) отправьте сигнал прерывания
SIGABRT
:pkill -SIGABRT program_name
источник
Необходимо использовать длину, возвращаемую до,
runtime.Stack()
чтобы не печатать кучу пустых строк после трассировки стека. Следующая функция восстановления распечатывает красиво отформатированную трассировку: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])) }
источник
runtime.Trace
;runtime.Stack
уже упоминалось полтора года назад .По умолчанию нажмите
^\
клавиши ( CTRL + \ ), чтобы выгрузить трассировку стека всех горутин.В противном случае для более детального контроля вы можете использовать
panic
. Простой способ для Go 1.6+ :go func() { s := make(chan os.Signal, 1) signal.Notify(s, syscall.SIGQUIT) <-s panic("give me the stack") }()
Затем запустите вашу программу так:
# Press ^\ to dump the stack traces of all the user-created goroutines $ GOTRACEBACK=all go run main.go
Если вы также хотите распечатать горутины времени выполнения:
$ GOTRACEBACK=system go run main.go
Вот все варианты GOTRACEBACK:
GOTRACEBACK=none
полностью исключает трассировку стека горутин.GOTRACEBACK=single
(по умолчанию) ведет себя, как описано выше.GOTRACEBACK=all
добавляет трассировки стека для всех горутин, созданных пользователем.GOTRACEBACK=system
похож на `` все '', но добавляет фреймы стека для функций времени выполнения и показывает горутины, созданные внутри среды выполнения.GOTRACEBACK=crash
похоже на `` систему '', но вместо выхода происходит сбой в зависимости от операционной системы. Например, в системах Unix возникает сбой, вызывающийSIGABRT
дамп ядра.Вот документация
источник