diff --git a/proc/proc.go b/proc/proc.go index 9471726ec4e5bdaaa3a9c847480689f5fb46134c..9312ad7942f9cd4e297fb89d5fb90f5a75b36cb1 100644 --- a/proc/proc.go +++ b/proc/proc.go @@ -501,7 +501,9 @@ func (dbp *Process) GoroutinesInfo() ([]*G, error) { g.Line = loc.Line g.Func = loc.Fn } - allg = append(allg, g) + if g.Status != Gdead { + allg = append(allg, g) + } } dbp.allGCache = allg return allg, nil diff --git a/proc/variables.go b/proc/variables.go index 9400aa0aedcec6623898d8e13bae054e068e046a..f6b5ff0bbddcec8c2b7a9ce70a2fa7b6f1cc3aa3 100644 --- a/proc/variables.go +++ b/proc/variables.go @@ -37,6 +37,19 @@ type M struct { curg uintptr // Current G running on this thread. } +const ( + // G status, from: src/runtime/runtime2.go + Gidle uint64 = iota // 0 + Grunnable // 1 runnable and on a run queue + Grunning // 2 + Gsyscall // 3 + Gwaiting // 4 + Gmoribund_unused // 5 currently unused, but hardcoded in gdb scripts + Gdead // 6 + Genqueue // 7 Only the Gscanenqueue is used. + Gcopystack // 8 in this state when newstack is moving the stack +) + // Represents a runtime G (goroutine) structure (at least the // fields that Delve is interested in). type G struct { @@ -45,6 +58,7 @@ type G struct { SP uint64 // SP of goroutine when it was parked. GoPC uint64 // PC of 'go' statement that created this goroutine. WaitReason string // Reason for goroutine being parked. + Status uint64 // Information on goroutine location. File string @@ -176,6 +190,12 @@ func parseG(thread *Thread, gaddr uint64, deref bool) (*G, error) { if err != nil { return nil, err } + // Parse atomicstatus + atomicStatusAddr, err := rdr.AddrForMember("atomicstatus", initialInstructions) + if err != nil { + return nil, err + } + atomicStatus, err := thread.readUintRaw(uintptr(atomicStatusAddr), 4) // Parse goid goidAddr, err := rdr.AddrForMember("goid", initialInstructions) if err != nil { @@ -215,6 +235,7 @@ func parseG(thread *Thread, gaddr uint64, deref bool) (*G, error) { Func: fn, WaitReason: waitreason, DeferPC: deferPC, + Status: atomicStatus, } return g, nil }