| // Copyright 2009 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package runtime |
| |
| import "unsafe" |
| |
| // sigtrampPC is the PC at the beginning of the jmpdefer assembly function. |
| // The traceback needs to recognize it on link register architectures. |
| var sigtrampPC uintptr |
| |
| func sigtramp() |
| |
| func init() { |
| sigtrampPC = funcPC(sigtramp) |
| systraceback = traceback_windows |
| } |
| |
| func traceback_windows(f *_func, frame *stkframe, gp *g, printing bool, callback func(*stkframe, unsafe.Pointer) bool, v unsafe.Pointer) (changed, aborted bool) { |
| // The main traceback thinks it has found a function. Check this. |
| |
| // Windows exception handlers run on the actual g stack (there is room |
| // dedicated to this below the usual "bottom of stack"), not on a separate |
| // stack. As a result, we have to be able to unwind past the exception |
| // handler when called to unwind during stack growth inside the handler. |
| // Recognize the frame at the call to sighandler in sigtramp and unwind |
| // using the context argument passed to the call. This is awful. |
| if f != nil && f.entry == sigtrampPC && frame.pc > f.entry { |
| var r *context |
| // Invoke callback so that stack copier sees an uncopyable frame. |
| if callback != nil { |
| frame.continpc = frame.pc |
| frame.argp = 0 |
| frame.arglen = 0 |
| if !callback(frame, v) { |
| aborted = true |
| return |
| } |
| } |
| r = (*context)(unsafe.Pointer(frame.sp + ptrSize)) |
| frame.pc = contextPC(r) |
| frame.sp = contextSP(r) |
| frame.lr = 0 |
| frame.fp = 0 |
| frame.fn = nil |
| if printing && showframe(nil, gp) { |
| print("----- exception handler -----\n") |
| } |
| f = findfunc(frame.pc) |
| if f == nil { |
| print("runtime: unknown pc ", hex(frame.pc), " after exception handler\n") |
| if callback != nil { |
| gothrow("unknown pc") |
| } |
| } |
| frame.fn = f |
| changed = true |
| return |
| } |
| |
| return |
| } |