mirror of
https://github.com/golang/go
synced 2024-10-04 22:21:22 -06:00
cc4e6aad8e
Currently we lose lots of profiling signals. Most notably, GC is not accounted at all. But stack splits, scheduler, syscalls, etc are lost as well. This creates seriously misleading profile. With this change all profiling signals are accounted. Now I see these additional entries that were previously absent: 161 29.7% 29.7% 164 30.3% syscall.Syscall 12 2.2% 50.9% 12 2.2% scanblock 11 2.0% 55.0% 11 2.0% markonly 10 1.8% 58.9% 10 1.8% sweepspan 2 0.4% 85.8% 2 0.4% runtime.newstack It is still impossible to understand what causes stack splits, but at least it's clear how many time is spent on them. Update #2197. Update #5659. R=golang-dev, rsc CC=golang-dev https://golang.org/cl/12179043
126 lines
3.5 KiB
C
126 lines
3.5 KiB
C
// Copyright 2013 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.
|
|
|
|
// +build darwin freebsd linux netbsd openbsd
|
|
|
|
#include "runtime.h"
|
|
#include "defs_GOOS_GOARCH.h"
|
|
#include "os_GOOS.h"
|
|
#include "signal_GOOS_GOARCH.h"
|
|
#include "signals_GOOS.h"
|
|
|
|
void
|
|
runtime·dumpregs(Siginfo *info, void *ctxt)
|
|
{
|
|
USED(info);
|
|
USED(ctxt);
|
|
|
|
runtime·printf("eax %x\n", SIG_EAX(info, ctxt));
|
|
runtime·printf("ebx %x\n", SIG_EBX(info, ctxt));
|
|
runtime·printf("ecx %x\n", SIG_ECX(info, ctxt));
|
|
runtime·printf("edx %x\n", SIG_EDX(info, ctxt));
|
|
runtime·printf("edi %x\n", SIG_EDI(info, ctxt));
|
|
runtime·printf("esi %x\n", SIG_ESI(info, ctxt));
|
|
runtime·printf("ebp %x\n", SIG_EBP(info, ctxt));
|
|
runtime·printf("esp %x\n", SIG_ESP(info, ctxt));
|
|
runtime·printf("eip %x\n", SIG_EIP(info, ctxt));
|
|
runtime·printf("eflags %x\n", SIG_EFLAGS(info, ctxt));
|
|
runtime·printf("cs %x\n", SIG_CS(info, ctxt));
|
|
runtime·printf("fs %x\n", SIG_FS(info, ctxt));
|
|
runtime·printf("gs %x\n", SIG_GS(info, ctxt));
|
|
}
|
|
|
|
void
|
|
runtime·sighandler(int32 sig, Siginfo *info, void *ctxt, G *gp)
|
|
{
|
|
uintptr *sp;
|
|
SigTab *t;
|
|
bool crash;
|
|
|
|
if(sig == SIGPROF) {
|
|
runtime·sigprof((byte*)SIG_EIP(info, ctxt), (byte*)SIG_ESP(info, ctxt), nil, gp);
|
|
return;
|
|
}
|
|
|
|
t = &runtime·sigtab[sig];
|
|
if(SIG_CODE0(info, ctxt) != SI_USER && (t->flags & SigPanic)) {
|
|
if(gp == nil || gp == m->g0)
|
|
goto Throw;
|
|
|
|
// 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 = sig;
|
|
gp->sigcode0 = SIG_CODE0(info, ctxt);
|
|
gp->sigcode1 = SIG_CODE1(info, ctxt);
|
|
gp->sigpc = SIG_EIP(info, ctxt);
|
|
|
|
#ifdef GOOS_darwin
|
|
// Work around Leopard bug that doesn't set FPE_INTDIV.
|
|
// Look at instruction to see if it is a divide.
|
|
// Not necessary in Snow Leopard (si_code will be != 0).
|
|
if(sig == SIGFPE && gp->sigcode0 == 0) {
|
|
byte *pc;
|
|
pc = (byte*)gp->sigpc;
|
|
if(pc[0] == 0x66) // 16-bit instruction prefix
|
|
pc++;
|
|
if(pc[0] == 0xF6 || pc[0] == 0xF7)
|
|
gp->sigcode0 = FPE_INTDIV;
|
|
}
|
|
#endif
|
|
|
|
// Only push runtime·sigpanic if eip != 0.
|
|
// If 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(SIG_EIP(info, ctxt) != 0) {
|
|
sp = (uintptr*)SIG_ESP(info, ctxt);
|
|
*--sp = SIG_EIP(info, ctxt);
|
|
SIG_ESP(info, ctxt) = (uintptr)sp;
|
|
}
|
|
SIG_EIP(info, ctxt) = (uintptr)runtime·sigpanic;
|
|
return;
|
|
}
|
|
|
|
if(SIG_CODE0(info, ctxt) == SI_USER || (t->flags & SigNotify))
|
|
if(runtime·sigsend(sig))
|
|
return;
|
|
if(t->flags & SigKill)
|
|
runtime·exit(2);
|
|
if(!(t->flags & SigThrow))
|
|
return;
|
|
|
|
Throw:
|
|
m->throwing = 1;
|
|
m->caughtsig = gp;
|
|
runtime·startpanic();
|
|
|
|
if(sig < 0 || sig >= NSIG)
|
|
runtime·printf("Signal %d\n", sig);
|
|
else
|
|
runtime·printf("%s\n", runtime·sigtab[sig].name);
|
|
|
|
runtime·printf("PC=%x\n", SIG_EIP(info, ctxt));
|
|
if(m->lockedg != nil && m->ncgo > 0 && gp == m->g0) {
|
|
runtime·printf("signal arrived during cgo execution\n");
|
|
gp = m->lockedg;
|
|
}
|
|
runtime·printf("\n");
|
|
|
|
if(runtime·gotraceback(&crash)){
|
|
runtime·traceback(SIG_EIP(info, ctxt), SIG_ESP(info, ctxt), 0, gp);
|
|
runtime·tracebackothers(gp);
|
|
runtime·printf("\n");
|
|
runtime·dumpregs(info, ctxt);
|
|
}
|
|
|
|
if(crash)
|
|
runtime·crash();
|
|
|
|
runtime·exit(2);
|
|
}
|