From a7c09ad4fb656ec662bc4df28fa224663873ebc8 Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Mon, 23 Nov 2015 11:29:56 -0500 Subject: runtime: improve stack barrier debugging This improves stack barrier debugging messages in various ways: 1) Rather than printing only the remaining stack barriers (of which there may be none, which isn't very useful), print all of the G's stack barriers with a marker at the position the stack itself has unwound to and a marker at the problematic stack barrier (where applicable). 2) Rather than crashing if we encounter a stack barrier when there are no more stkbar entries, print the same debug message we would if we had encountered a stack barrier at an unexpected location. Hopefully this will help with debugging #12528. Change-Id: I2e6fe6a778e0d36dd8ef30afd4c33d5d94731262 Reviewed-on: https://go-review.googlesource.com/17147 Reviewed-by: Rick Hudson Reviewed-by: Russ Cox --- src/runtime/traceback.go | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'src/runtime/traceback.go') diff --git a/src/runtime/traceback.go b/src/runtime/traceback.go index 1743a93507..ee58473a13 100644 --- a/src/runtime/traceback.go +++ b/src/runtime/traceback.go @@ -144,7 +144,8 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in // Fix up returns to the stack barrier by fetching the // original return PC from gp.stkbar. - stkbar := gp.stkbar[gp.stkbarPos:] + stkbarG := gp + stkbar := stkbarG.stkbar[stkbarG.stkbarPos:] if pc0 == ^uintptr(0) && sp0 == ^uintptr(0) { // Signal to fetch saved values from gp. if gp.syscallsp != 0 { @@ -208,8 +209,8 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in stkbarPos = gp.stkbarPos - 1 } else { printlock() - print("runtime: failed to unwind through stackBarrier at SP ", hex(sp0), " index ", gp.stkbarPos, "; ") - gcPrintStkbars(gp.stkbar) + print("runtime: failed to unwind through stackBarrier at SP ", hex(sp0), "; ") + gcPrintStkbars(gp, int(gp.stkbarPos)) print("\n") throw("inconsistent state in stackBarrier") } @@ -248,7 +249,8 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in sp := frame.sp if flags&_TraceJumpStack != 0 && f.entry == systemstackPC && gp == g.m.g0 && gp.m.curg != nil { sp = gp.m.curg.sched.sp - stkbar = gp.m.curg.stkbar[gp.m.curg.stkbarPos:] + stkbarG = gp.m.curg + stkbar = stkbarG.stkbar[stkbarG.stkbarPos:] } frame.fp = sp + uintptr(funcspdelta(f, frame.pc, &cache)) if !usesLR { @@ -286,9 +288,9 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in } if frame.lr == stackBarrierPC { // Recover original PC. - if stkbar[0].savedLRPtr != lrPtr { + if len(stkbar) == 0 || stkbar[0].savedLRPtr != lrPtr { print("found next stack barrier at ", hex(lrPtr), "; expected ") - gcPrintStkbars(stkbar) + gcPrintStkbars(stkbarG, len(stkbarG.stkbar)-len(stkbar)) print("\n") throw("missed stack barrier") } @@ -505,7 +507,7 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in if callback != nil && n < max && len(stkbar) > 0 { print("runtime: g", gp.goid, ": leftover stack barriers ") - gcPrintStkbars(stkbar) + gcPrintStkbars(stkbarG, len(stkbarG.stkbar)-len(stkbar)) print("\n") throw("traceback has leftover stack barriers") } -- cgit v1.3