code

고 루틴 스택 트레이스를 덤프하는 방법은 무엇입니까?

codestyles 2020. 10. 20. 07:39
반응형

고 루틴 스택 트레이스를 덤프하는 방법은 무엇입니까?


저는 Java 배경 지식이 있으며 Java 스레드 덤프를 검사하기 위해 신호 QUIT를 사용하는 것을 좋아합니다.

Golang이 모든 고 루틴 스택 추적을 인쇄하도록하는 방법은 무엇입니까?


에 대한 스택 추적을 인쇄하려면 현재의 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-모든 현재 고 루틴
힙의
스택 추적- 모든 힙 할당의 샘플링 threadcreate-새 OS 스레드
블록 생성으로 이어진 스택 추적-동기화 프리미티브에 대한 차단으로 이어진 스택 추적

예를 들면 :

pprof.Lookup("goroutine").WriteTo(os.Stdout, 1)

runtime/pprofIntermernet의 답변에 언급 된 패키지에 대한 HTTP 프런트 엔드가 있습니다 . 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


SIGQUIT에서 스택 덤프의 Java 동작을 모방하지만 프로그램을 계속 실행하려면 다음을 수행하십시오.

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을 설정합니다.

스택 추적의 인쇄는 원래이 commit에 문서화 된 예기치 않은 런타임 조건 (처리되지 않은 신호)에 의해 트리거되어 최소 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

Stack은 호출하는 goroutine의 스택 추적을 buf로 포맷하고 buf에 기록 된 바이트 수를 반환합니다. 모두 참이면 스택은 현재 고 루틴에 대한 추적 후에 다른 모든 고 루틴의 스택 추적을 buf로 형식화합니다.


Ctrl + \를 누릅니다.

(터미널에서 실행하고 프로그램을 종료하고 go 루틴 등을 덤프하려는 경우)

이 질문은 키 시퀀스를 찾고 있습니다. 내 프로그램이 루틴을 유출하는지 빠르고 쉬운 방법을 원했습니다. :)


* NIX 시스템 (OSX 포함)에서 abort 신호를 보냅니다 SIGABRT.

pkill -SIGABRT program_name


It's necessary to use the length returned by runtime.Stack() to avoid printing a bunch of empty lines after your stack trace. The following recovery function prints a nicely formatted trace:

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]))
}

By default, press ^\ keys ( CTRL+\ ) to dump the stack traces of all goroutines.


Otherwise, for more granular control, you can use panic. The simple way as of Go 1.6+:

go func() {
    s := make(chan os.Signal, 1)
    signal.Notify(s, syscall.SIGQUIT)
    <-s
    panic("give me the stack")
}()

Then, run your program like so:

# Press ^\ to dump the stack traces of all the user-created goroutines
$ GOTRACE=all go run main.go

If you also want to print go runtime goroutines:

$ GOTRACE=system go run main.go

Here are all the GOTRACE options:

  • GOTRACEBACK=none omits the goroutine stack traces entirely.
  • GOTRACEBACK=single (the default) behaves as described above.
  • GOTRACEBACK=all adds stack traces for all user-created goroutines.
  • GOTRACEBACK=system is like ``all'' but adds stack frames for run-time functions and shows goroutines created internally by the run-time.
  • GOTRACEBACK=crash is like ``system'' but crashes in an operating system-specific manner instead of exiting. For example, on Unix systems, the crash raises SIGABRT to trigger a core dump.

Here is the documentation

The GOTRACEBACK variable controls the amount of output generated when a Go program fails due to an unrecovered panic or an unexpected runtime condition.

By default, a failure prints a stack trace for the current goroutine, eliding functions internal to the run-time system, and then exits with exit code 2. The failure prints stack traces for all goroutines if there is no current goroutine or the failure is internal to the run-time.

For historical reasons, the GOTRACEBACK settings 0, 1, and 2 are synonyms for none, all, and system, respectively.

The runtime/debug package's SetTraceback function allows increasing the amount of output at run time, but it cannot reduce the amount below that specified by the environment variable. See https://golang.org/pkg/runtime/debug/#SetTraceback.

참고URL : https://stackoverflow.com/questions/19094099/how-to-dump-goroutine-stacktraces

반응형