저는 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/pprof
Intermernet의 답변에 언급 된 패키지에 대한 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