У мене фон Java, і я люблю використовувати сигнал QUIT для перевірки дампа потоку Java.
Як дозволити Golang роздрукувати всі стеки трасируючих програм?
У мене фон Java, і я люблю використовувати сигнал QUIT для перевірки дампа потоку Java.
Як дозволити Golang роздрукувати всі стеки трасируючих програм?
Відповіді:
Щоб надрукувати трасування стека для поточної програми , використовуйте 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)
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 = все.
Друк трасування стека ініціюється несподіваною умовою виконання (необроблений сигнал), спочатку задокументованою в цьому коміті , що робить його доступним принаймні з 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
Стек форматує трасування стека викликаючої програми в buf і повертає кількість байтів, записаних у buf. Якщо все правда, формати стеку стекують сліди всіх інших програм у buf після трасування поточної програми.
string(buf), fmt.Printf("%s", buf)і fmt.Printf("%s", string(buf))робити точно те саме (див. документи для fmtпакету); єдина різниця тут полягає в тому, що stringверсія скопіює байти з bufнепотрібності
Натисніть CTRL + \
(Якщо ви запускаєте його в терміналі і просто хочете вбити вашу програму і скинути підпрограми 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]))
}
За замовчуванням натисніть ^\клавіші ( 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
Якщо ви також хочете надрукувати GoRutine GoRutine:
$ GOTRACEBACK=system go run main.go
Ось усі варіанти GOTRACEBACK:
GOTRACEBACK=none повністю опускає сліди стеку програми.GOTRACEBACK=single (за замовчуванням) поводиться, як описано вище.GOTRACEBACK=all додає сліди стека для всіх створених користувачем програм.GOTRACEBACK=system схожий на `ʻall ', але додає кадри стека для функцій часу виконання і показує програми, створені внутрішньо під час виконання.GOTRACEBACK=crashсхожа на `` систему '', але аварійно завершує роботу, а не виходить із системи. Наприклад, в системах Unix збій піднімається, SIGABRTщоб викликати дамп ядра.Змінна GOTRACEBACK контролює кількість вихідних даних, що генеруються, коли програма Go не працює через невизначену паніку або несподівану умову виконання.
За замовчуванням збій друкує трасування стека для поточної програми, видаляючи функції, що є внутрішньою системою виконання, а потім виходить із кодом виходу 2. Помилка друкує сліди стека для всіх програм, якщо поточної програми немає або внутрішній під час виконання.
З історичних причин налаштування GOTRACEBACK 0, 1 та 2 є синонімами відповідно none, all та system.
Функція SetTraceback пакета виконання / налагодження дозволяє збільшити кількість вихідних даних під час виконання, але вона не може зменшити кількість, нижчу за вказану змінною середовища. Див. Https://golang.org/pkg/runtime/debug/#SetTraceback .