// Copyright 2010 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_GOOS_GOARCH.h" #include "os_GOOS.h" #include "signals_GOOS.h" void runtime·dumpregs(Ureg *u) { runtime·printf("ax %X\n", u->ax); runtime·printf("bx %X\n", u->bx); runtime·printf("cx %X\n", u->cx); runtime·printf("dx %X\n", u->dx); runtime·printf("di %X\n", u->di); runtime·printf("si %X\n", u->si); runtime·printf("bp %X\n", u->bp); runtime·printf("sp %X\n", u->sp); runtime·printf("r8 %X\n", u->r8); runtime·printf("r9 %X\n", u->r9); runtime·printf("r10 %X\n", u->r10); runtime·printf("r11 %X\n", u->r11); runtime·printf("r12 %X\n", u->r12); runtime·printf("r13 %X\n", u->r13); runtime·printf("r14 %X\n", u->r14); runtime·printf("r15 %X\n", u->r15); runtime·printf("ip %X\n", u->ip); runtime·printf("flags %X\n", u->flags); runtime·printf("cs %X\n", (uint64)u->cs); runtime·printf("fs %X\n", (uint64)u->fs); runtime·printf("gs %X\n", (uint64)u->gs); } int32 runtime·sighandler(void *v, int8 *s, G *gp) { bool crash; Ureg *ureg; uintptr *sp; SigTab *sig, *nsig; intgo i, len; if(!s) return NCONT; len = runtime·findnull((byte*)s); if(len <= 4 || runtime·mcmp((byte*)s, (byte*)"sys:", 4) != 0) return NDFLT; nsig = nil; sig = runtime·sigtab; for(i=0; i < NSIG; i++) { if(runtime·strstr((byte*)s, (byte*)sig->name)) { nsig = sig; break; } sig++; } if(nsig == nil) return NDFLT; ureg = v; if(nsig->flags & SigPanic) { if(gp == nil || m->notesig == 0) goto Throw; // Save error string from sigtramp's stack, // into gsignal->sigcode0, so we can reliably // access it from the panic routines. if(len > ERRMAX) len = ERRMAX; runtime·memmove((void*)m->notesig, (void*)s, len); gp->sig = i; gp->sigpc = ureg->ip; // Only push runtime·sigpanic if ureg->ip != 0. // If ureg->ip == 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(ureg->ip != 0) { sp = (uintptr*)ureg->sp; *--sp = ureg->ip; ureg->sp = (uint64)sp; } ureg->ip = (uintptr)runtime·sigpanic; return NCONT; } if(!(nsig->flags & SigThrow)) return NDFLT; Throw: m->throwing = 1; m->caughtsig = gp; runtime·startpanic(); runtime·printf("%s\n", s); runtime·printf("PC=%X\n", ureg->ip); runtime·printf("\n"); if(runtime·gotraceback(&crash)) { runtime·traceback(ureg->ip, ureg->sp, 0, gp); runtime·tracebackothers(gp); runtime·dumpregs(ureg); } if(crash) runtime·crash(); runtime·goexitsall(""); runtime·exits(s); return 0; } void runtime·sigenable(uint32 sig) { USED(sig); } void runtime·sigdisable(uint32 sig) { USED(sig); } void runtime·resetcpuprofiler(int32 hz) { // TODO: Enable profiling interrupts. m->profilehz = hz; }