Как сбросить goroutine stacktraces?



У меня есть фон Java, и я люблю использовать signal QUIT для проверки дампа потока Java.



Как позволить Golang распечатать все goroutines stack trace?

648   8  
go

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 выйдет.

на * Nix системах (включая OSX) отправить сигнал прерывания SIGABRT:

pkill -SIGABRT program_name

пресс 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

    Ничего не найдено.