8 ответов:
для печати трассировки стека для настоящее goroutine, используйте
PrintStack()Сruntime/debug.печать PrintStack стандартное сообщение об ошибке трассировки стека, возвращаемое стека.
например:
import( "runtime/debug" ) ... debug.PrintStack()чтобы напечатать трассировку стека для все goroutines использовать
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.каждый профиль имеет уникальное имя. Несколько профилей предопределены:
goroutine-стек трассировки всех текущих goroutines
куча-выборка всех выделений кучи
threadcreate - трассировки стека, которые привели к созданию новой операционной системы потоков
трассировки стека блоков, которые привели к блокировке примитивов синхронизациидля пример:
pprof.Lookup("goroutine").WriteTo(os.Stdout, 1)
существует 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для полного сброса стека goroutine.есть и другие интересные вещи, которые вы можете узнать о своем запущенном коде таким же образом. Проверять сообщение в блоге для примеров и более подробной информации: http://blog.golang.org/profiling-go-programs
чтобы имитировать поведение Java stack-dump на 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]) } }()
можно использовать во время выполнения.Стек чтобы получить трассировку стека всех goroutines:
buf := make([]byte, 1<<16) runtime.Stack(buf, true) fmt.Printf("%s", buf)из документации:
func Stack(buf []byte, all bool) intстек форматирует трассировку стека вызывающего goroutine в buf и возвращает количество байтов, записанных в buf. Если все верно, стек форматы стек трассировки всех других goroutines в buf после трассировки для текущего goroutine.
по словам документы пакета времени выполнения, отправляя SIGQUIT в программу Go, по умолчанию будет печатать трассировку стека для каждого существующего goroutine, выделяя функции, внутренние для системы времени выполнения, а затем выход с кодом выхода 2.
переменная окружения GOTRACEBACK управляет количеством генерируемых выходных данных. Чтобы включить все goroutines, без фильтрации, установите GOTRACEBACK=2. Чтобы дополнительно создать дамп ядра (в системах Unix), установите GOTRACEBACK=авария.
документация и возможность генерировать дампы ядра были добавлены в этот коммит, и, AFAICT, доступно с Go 1.1.
таким образом, этот подход не требует кода для печати трассировки стека всех goroutines. Разница с Java заключается в том, что Java будет продолжать работать с программой, в то время как Go выйдет.
пресс CTRL+\
(Если вы запустите его в терминале и просто хотите убить свою программу и сбросить подпрограммы go и т. д.)
Я нашел этот вопрос ищет последовательность клавиш. Просто хотел быстрый и простой способ сказать, если моя программа протекает go процедуры :)
необходимо использовать длину возвращаемого
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])) }
Comments