diff options
Diffstat (limited to 'src/pkg/runtime/windows/386/signal.c')
-rw-r--r-- | src/pkg/runtime/windows/386/signal.c | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/src/pkg/runtime/windows/386/signal.c b/src/pkg/runtime/windows/386/signal.c new file mode 100644 index 000000000..cc6a2302f --- /dev/null +++ b/src/pkg/runtime/windows/386/signal.c @@ -0,0 +1,98 @@ +// 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. + +#include "runtime.h" +#include "defs.h" +#include "os.h" + +void +runtime·dumpregs(Context *r) +{ + runtime·printf("eax %x\n", r->Eax); + runtime·printf("ebx %x\n", r->Ebx); + runtime·printf("ecx %x\n", r->Ecx); + runtime·printf("edx %x\n", r->Edx); + runtime·printf("edi %x\n", r->Edi); + runtime·printf("esi %x\n", r->Esi); + runtime·printf("ebp %x\n", r->Ebp); + runtime·printf("esp %x\n", r->Esp); + runtime·printf("eip %x\n", r->Eip); + runtime·printf("eflags %x\n", r->EFlags); + runtime·printf("cs %x\n", r->SegCs); + runtime·printf("fs %x\n", r->SegFs); + runtime·printf("gs %x\n", r->SegGs); +} + +void +runtime·initsig(int32) +{ + runtime·siginit(); +} + +uint32 +runtime·sighandler(ExceptionRecord *info, void *frame, Context *r) +{ + uintptr *sp; + G *gp; + + USED(frame); + + switch(info->ExceptionCode) { + case EXCEPTION_BREAKPOINT: + r->Eip--; // because 8l generates 2 bytes for INT3 + return 1; + } + + if((gp = m->curg) != nil && runtime·issigpanic(info->ExceptionCode)) { + // Make it look like a call to the signal func. + // Have to pass arguments out of band since + // augmenting the stack frame would break + // the unwinding code. + gp->sig = info->ExceptionCode; + gp->sigcode0 = info->ExceptionInformation[0]; + gp->sigcode1 = info->ExceptionInformation[1]; + gp->sigpc = r->Eip; + + // Only push runtime·sigpanic if r->eip != 0. + // If r->eip == 0, probably panicked because of a + // call to a nil func. Not pushing that onto sp will + // make the trace look like a call to runtime·sigpanic instead. + // (Otherwise the trace will end at runtime·sigpanic and we + // won't get to see who faulted.) + if(r->Eip != 0) { + sp = (uintptr*)r->Esp; + *--sp = r->Eip; + r->Esp = (uintptr)sp; + } + r->Eip = (uintptr)runtime·sigpanic; + return 0; + } + + if(runtime·panicking) // traceback already printed + runtime·exit(2); + runtime·panicking = 1; + + runtime·printf("Exception %x %p %p\n", info->ExceptionCode, + info->ExceptionInformation[0], info->ExceptionInformation[1]); + + runtime·printf("PC=%x\n", r->Eip); + runtime·printf("\n"); + + if(runtime·gotraceback()){ + runtime·traceback((void*)r->Eip, (void*)r->Esp, 0, m->curg); + runtime·tracebackothers(m->curg); + runtime·dumpregs(r); + } + + runtime·exit(2); + return 0; +} + +void +runtime·resetcpuprofiler(int32 hz) +{ + // TODO: Enable profiling interrupts. + + m->profilehz = hz; +} |