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

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

Как разрешить Golang распечатывать всю трассировку стека goroutines?

Ответ 1

Чтобы распечатать трассировку стека для текущего goroutine, используйте PrintStack() из runtime/debug.

PrintStack печатает стандартную ошибку трассировки стека, возвращаемой Stack.

Например:

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)

Ответ 2

Существует 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

Ответ 3

Чтобы имитировать поведение 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])
    }
}()

Ответ 4

Как и в Java, SIGQUIT может использоваться для печати трассировки стека программы Go и ее подпрограмм.
Однако ключевое отличие состоит в том, что по умолчанию отправка SIGQUIT программам Java не завершает их, в то время как программы Go завершают работу.

Этот подход не требует изменения кода для печати трассировки стека всех подпрограмм существующих программ.

Переменная среды GOTRACEBACK (см. Документацию пакета времени выполнения) контролирует объем генерируемого вывода. Например, чтобы включить все процедуры, установите GOTRACEBACK = all.

Печать трассировки стека инициируется неожиданным условием времени выполнения (необработанный сигнал), первоначально задокументированным в этом коммите, что делает его доступным по крайней мере начиная с версии 1.1.


В качестве альтернативы, если есть возможность изменить исходный код, см. другие ответы.


Обратите внимание, что в терминале Linux SIGQUIT удобно отправлять с помощью комбинации клавиш Ctrl + \.

Ответ 5

Вы можете использовать runtime.Stack, чтобы получить трассировку стека всех goroutines:

buf := make([]byte, 1<<16)
runtime.Stack(buf, true)
fmt.Printf("%s", buf)

Из документации:

func Stack(buf []byte, all bool) int

Стек форматирует трассировку стека вызывающей очереди в buf и возвращает количество байтов, записанных в buf. Если все верно, Stack форматирует стеки следов всех остальных goroutines в buf после трассировки для текущего гортана.

Ответ 6

Нажмите CTRL +\

(Если вы запустите его в терминале и просто хотите убить свою программу и сбросить программы go и т.д.)

Я нашел этот вопрос в поисках последовательности клавиш. Просто хотелось бы быстро и просто узнать, не протекает ли моя программа, выполните следующие действия:)

Ответ 7

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

pkill -SIGABRT program_name

Ответ 8

Необходимо использовать длину, возвращаемую 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]))
}

Ответ 9

По умолчанию нажмите клавиши ^\ (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
$ GOTRACE=all go run main.go

Если вы также хотите распечатать go runoutines:

$ GOTRACE=system go run main.go

Вот все варианты GOTRACE:

  • GOTRACEBACK=none не пропускает трассировки стека GOTRACEBACK=none полностью.
  • GOTRACEBACK=single (по умолчанию) ведет себя как описано выше.
  • GOTRACEBACK=all добавляет трассировки стека для всех пользовательских процедур.
  • GOTRACEBACK=system похожа на '' all '', но добавляет кадры стека для функций времени выполнения и показывает процедуры, созданные внутри во время выполнения.
  • GOTRACEBACK=crash похож на '' system '', но аварийно завершает работу в GOTRACEBACK=crash от операционной системы вместо выхода. Например, в системах Unix сбой вызывает SIGABRT для запуска дампа ядра.

Вот документация

Переменная GOTRACEBACK управляет объемом выходных данных, генерируемых в случае сбоя программы Go из-за невосстановленной паники или неожиданного состояния во время выполнения.

По умолчанию ошибка печатает трассировку стека для текущей программы, исключая внутренние функции системы выполнения, а затем завершает работу с кодом выхода 2. Ошибка печатает трассировки стека для всех программ, если текущая программа не работает или происходит сбой. внутренний для времени выполнения.

По историческим причинам настройки GOTRACEBACK 0, 1 и 2 являются синонимами для none, all и system соответственно.

Функция SetTraceback пакета времени выполнения/отладки позволяет увеличить объем выходных данных во время выполнения, но не может уменьшить объем ниже значения, указанного в переменной среды. Смотрите https://golang.org/pkg/runtime/debug/#SetTraceback.