Skip to content

Commit

Permalink
proc: fix stacktraces on freebsd/amd64/go1.20 (#3458)
Browse files Browse the repository at this point in the history
TestStacktraceGoroutine failed intermittently on freebsd/amd64/go1.20.

This happens because of two windows, in the scheduler (right after
parking a goroutine and just before resuming a parked goroutine) where
a thread is associated with a goroutine but running in the system stack
and there is no systemstack_switch frame to connect the two stacks.
  • Loading branch information
aarzilli committed Aug 14, 2023
1 parent ec07c27 commit 281f392
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 4 deletions.
10 changes: 9 additions & 1 deletion pkg/proc/amd64_arch.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,11 +200,19 @@ func amd64SwitchStack(it *stackIterator, _ *op.DwarfRegisters) bool {

return true

case "runtime.goexit", "runtime.rt0_go", "runtime.mcall":
case "runtime.goexit", "runtime.rt0_go":
// Look for "top of stack" functions.
it.atend = true
return true

case "runtime.mcall":
if it.systemstack && it.g != nil {
it.switchToGoroutineStack()
return true
}
it.atend = true
return true

case "runtime.mstart":
// Calls to runtime.systemstack will switch to the systemstack then:
// 1. alter the goroutine stack so that it looks like systemstack_switch
Expand Down
11 changes: 10 additions & 1 deletion pkg/proc/arm64_arch.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,10 +217,19 @@ func arm64SwitchStack(it *stackIterator, callFrameRegs *op.DwarfRegisters) bool
return true
}

case "runtime.goexit", "runtime.rt0_go", "runtime.mcall":
case "runtime.goexit", "runtime.rt0_go":
// Look for "top of stack" functions.
it.atend = true
return true

case "runtime.mcall":
if it.systemstack && it.g != nil {
it.switchToGoroutineStack()
return true
}
it.atend = true
return true

case "crosscall2":
// The offsets get from runtime/cgo/asm_arm64.s:10
bpoff := uint64(14)
Expand Down
10 changes: 9 additions & 1 deletion pkg/proc/i386_arch.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,19 @@ func i386SwitchStack(it *stackIterator, _ *op.DwarfRegisters) bool {
switch it.frame.Current.Fn.Name {
case "runtime.asmcgocall", "runtime.cgocallback_gofunc": // TODO(chainhelen), need to support cgo stacktraces.
return false
case "runtime.goexit", "runtime.rt0_go", "runtime.mcall":
case "runtime.goexit", "runtime.rt0_go":
// Look for "top of stack" functions.
it.atend = true
return true

case "runtime.mcall":
if it.systemstack && it.g != nil {
it.switchToGoroutineStack()
return true
}
it.atend = true
return true

case "runtime.mstart":
// Calls to runtime.systemstack will switch to the systemstack then:
// 1. alter the goroutine stack so that it looks like systemstack_switch
Expand Down
9 changes: 8 additions & 1 deletion pkg/proc/ppc64le_arch.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,17 @@ func ppc64leSwitchStack(it *stackIterator, callFrameRegs *op.DwarfRegisters) boo
switch it.frame.Current.Fn.Name {
case "runtime.asmcgocall", "runtime.cgocallback_gofunc", "runtime.sigpanic", "runtime.cgocallback":
//do nothing
case "runtime.goexit", "runtime.rt0_go", "runtime.mcall":
case "runtime.goexit", "runtime.rt0_go":
// Look for "top of stack" functions.
it.atend = true
return true
case "runtime.mcall":
if it.systemstack && it.g != nil {
it.switchToGoroutineStack()
return true
}
it.atend = true
return true
case "crosscall2":
//The offsets get from runtime/cgo/asm_ppc64x.s:10
newsp, _ := readUintRaw(it.mem, it.regs.SP()+8*24, int64(it.bi.Arch.PtrSize()))
Expand Down

0 comments on commit 281f392

Please sign in to comment.