mirror of
https://github.com/golang/go
synced 2024-11-12 09:20:22 -07:00
runtime: accept GOTRACEBACK=crash to mean 'crash after panic'
This provides a way to generate core dumps when people need them. The settings are: GOTRACEBACK=0 no traceback on panic, just exit GOTRACEBACK=1 default - traceback on panic, then exit GOTRACEBACK=2 traceback including runtime frames on panic, then exit GOTRACEBACK=crash traceback including runtime frames on panic, then crash Fixes #3257. R=golang-dev, devon.odell, r, daniel.morsing, ality CC=golang-dev https://golang.org/cl/7666044
This commit is contained in:
parent
f6a952599e
commit
5146a93e72
@ -7,6 +7,50 @@
|
|||||||
such as functions to control goroutines. It also includes the low-level type information
|
such as functions to control goroutines. It also includes the low-level type information
|
||||||
used by the reflect package; see reflect's documentation for the programmable
|
used by the reflect package; see reflect's documentation for the programmable
|
||||||
interface to the run-time type system.
|
interface to the run-time type system.
|
||||||
|
|
||||||
|
Environment Variables
|
||||||
|
|
||||||
|
The following environment variables ($name or %name%, depending on the host
|
||||||
|
operating system) control the run-time behavior of Go programs. The meanings
|
||||||
|
and use may change from release to release.
|
||||||
|
|
||||||
|
The GOGC variable sets the initial garbage collection target percentage.
|
||||||
|
A collection is triggered when the ratio of freshly allocated data to live data
|
||||||
|
remaining after the previous collection reaches this percentage. The default
|
||||||
|
is GOGC=100. Setting GOGC=off disables the garbage collector entirely.
|
||||||
|
The runtime/debug package's SetGCPercent function allows changing this
|
||||||
|
percentage at run time. See http://golang.org/pkg/runtime/debug/#SetGCPercent.
|
||||||
|
|
||||||
|
The GOGCTRACE variable controls debug output from the garbage collector.
|
||||||
|
Setting GOGCTRACE=1 causes the garbage collector to emit a single line to standard
|
||||||
|
error at each collection, summarizing the amount of memory collected and the
|
||||||
|
length of the pause. Setting GOGCTRACE=2 emits the same summary but also
|
||||||
|
repeats each collection.
|
||||||
|
|
||||||
|
The GOMAXPROCS variable limits the number of operating system threads that
|
||||||
|
can execute user-level Go code simultaneously. There is no limit to the number of threads
|
||||||
|
that can be blocked in system calls on behalf of Go code; those do not count against
|
||||||
|
the GOMAXPROCS limit. This package's GOMAXPROCS function queries and changes
|
||||||
|
the limit.
|
||||||
|
|
||||||
|
The GOTRACEBACK variable controls the amount of output generated when a Go
|
||||||
|
program fails due to an unrecovered panic or an unexpected runtime condition.
|
||||||
|
By default, a failure prints a stack trace for every extant goroutine, eliding functions
|
||||||
|
internal to the run-time system, and then exits with exit code 2.
|
||||||
|
If GOTRACEBACK=0, the per-goroutine stack traces are omitted entirely.
|
||||||
|
If GOTRACEBACK=1, the default behavior is used.
|
||||||
|
If GOTRACEBACK=2, the per-goroutine stack traces include run-time functions.
|
||||||
|
If GOTRACEBACK=crash, the per-goroutine stack traces include run-time functions,
|
||||||
|
and if possible the program crashes in an operating-specific manner instead of
|
||||||
|
exiting. For example, on Unix systems, the program raises SIGABRT to trigger a
|
||||||
|
core dump.
|
||||||
|
|
||||||
|
The GOARCH, GOOS, GOPATH, and GOROOT environment variables complete
|
||||||
|
the set of Go environment variables. They influence the building of Go programs
|
||||||
|
(see http://golang.org/cmd/go and http://golang.org/pkg/go/build).
|
||||||
|
GOARCH, GOOS, and GOROOT are recorded at compile time and made available by
|
||||||
|
constants or functions in this package, but they do not influence the execution
|
||||||
|
of the run-time system.
|
||||||
*/
|
*/
|
||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
|
@ -91,6 +91,13 @@ runtime·osinit(void)
|
|||||||
runtime·notify(runtime·sigtramp);
|
runtime·notify(runtime·sigtramp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
runtime·crash(void)
|
||||||
|
{
|
||||||
|
runtime·notify(nil);
|
||||||
|
*(int32*)0 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
runtime·get_random_data(byte **rnd, int32 *rnd_len)
|
runtime·get_random_data(byte **rnd, int32 *rnd_len)
|
||||||
{
|
{
|
||||||
|
@ -28,6 +28,7 @@ runtime·dumpregs(Ureg *u)
|
|||||||
int32
|
int32
|
||||||
runtime·sighandler(void *v, int8 *s, G *gp)
|
runtime·sighandler(void *v, int8 *s, G *gp)
|
||||||
{
|
{
|
||||||
|
bool crash;
|
||||||
Ureg *ureg;
|
Ureg *ureg;
|
||||||
uintptr *sp;
|
uintptr *sp;
|
||||||
SigTab *sig, *nsig;
|
SigTab *sig, *nsig;
|
||||||
@ -93,11 +94,15 @@ Throw:
|
|||||||
runtime·printf("PC=%X\n", ureg->pc);
|
runtime·printf("PC=%X\n", ureg->pc);
|
||||||
runtime·printf("\n");
|
runtime·printf("\n");
|
||||||
|
|
||||||
if(runtime·gotraceback()) {
|
if(runtime·gotraceback(&crash)) {
|
||||||
runtime·traceback((void*)ureg->pc, (void*)ureg->sp, 0, gp);
|
runtime·traceback((void*)ureg->pc, (void*)ureg->sp, 0, gp);
|
||||||
runtime·tracebackothers(gp);
|
runtime·tracebackothers(gp);
|
||||||
runtime·dumpregs(ureg);
|
runtime·dumpregs(ureg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(crash)
|
||||||
|
runtime·crash();
|
||||||
|
|
||||||
runtime·goexitsall("");
|
runtime·goexitsall("");
|
||||||
runtime·exits(s);
|
runtime·exits(s);
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@ runtime·dumpregs(Ureg *u)
|
|||||||
int32
|
int32
|
||||||
runtime·sighandler(void *v, int8 *s, G *gp)
|
runtime·sighandler(void *v, int8 *s, G *gp)
|
||||||
{
|
{
|
||||||
|
bool crash;
|
||||||
Ureg *ureg;
|
Ureg *ureg;
|
||||||
uintptr *sp;
|
uintptr *sp;
|
||||||
SigTab *sig, *nsig;
|
SigTab *sig, *nsig;
|
||||||
@ -101,11 +102,15 @@ Throw:
|
|||||||
runtime·printf("PC=%X\n", ureg->ip);
|
runtime·printf("PC=%X\n", ureg->ip);
|
||||||
runtime·printf("\n");
|
runtime·printf("\n");
|
||||||
|
|
||||||
if(runtime·gotraceback()) {
|
if(runtime·gotraceback(&crash)) {
|
||||||
runtime·traceback((void*)ureg->ip, (void*)ureg->sp, 0, gp);
|
runtime·traceback((void*)ureg->ip, (void*)ureg->sp, 0, gp);
|
||||||
runtime·tracebackothers(gp);
|
runtime·tracebackothers(gp);
|
||||||
runtime·dumpregs(ureg);
|
runtime·dumpregs(ureg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(crash)
|
||||||
|
runtime·crash();
|
||||||
|
|
||||||
runtime·goexitsall("");
|
runtime·goexitsall("");
|
||||||
runtime·exits(s);
|
runtime·exits(s);
|
||||||
|
|
||||||
|
@ -455,3 +455,16 @@ int32 runtime·badcallbacklen = sizeof runtime·badcallbackmsg - 1;
|
|||||||
|
|
||||||
int8 runtime·badsignalmsg[] = "runtime: signal received on thread not created by Go.\n";
|
int8 runtime·badsignalmsg[] = "runtime: signal received on thread not created by Go.\n";
|
||||||
int32 runtime·badsignallen = sizeof runtime·badsignalmsg - 1;
|
int32 runtime·badsignallen = sizeof runtime·badsignalmsg - 1;
|
||||||
|
|
||||||
|
void
|
||||||
|
runtime·crash(void)
|
||||||
|
{
|
||||||
|
// TODO: This routine should do whatever is needed
|
||||||
|
// to make the Windows program abort/crash as it
|
||||||
|
// would if Go was not intercepting signals.
|
||||||
|
// On Unix the routine would remove the custom signal
|
||||||
|
// handler and then raise a signal (like SIGABRT).
|
||||||
|
// Something like that should happen here.
|
||||||
|
// It's okay to leave this empty for now: if crash returns
|
||||||
|
// the ordinary exit-after-panic happens.
|
||||||
|
}
|
||||||
|
@ -27,6 +27,7 @@ runtime·dumpregs(Context *r)
|
|||||||
uint32
|
uint32
|
||||||
runtime·sighandler(ExceptionRecord *info, Context *r, G *gp)
|
runtime·sighandler(ExceptionRecord *info, Context *r, G *gp)
|
||||||
{
|
{
|
||||||
|
bool crash;
|
||||||
uintptr *sp;
|
uintptr *sp;
|
||||||
|
|
||||||
switch(info->ExceptionCode) {
|
switch(info->ExceptionCode) {
|
||||||
@ -74,12 +75,16 @@ runtime·sighandler(ExceptionRecord *info, Context *r, G *gp)
|
|||||||
}
|
}
|
||||||
runtime·printf("\n");
|
runtime·printf("\n");
|
||||||
|
|
||||||
if(runtime·gotraceback()){
|
if(runtime·gotraceback(&crash)){
|
||||||
runtime·traceback((void*)r->Eip, (void*)r->Esp, 0, gp);
|
runtime·traceback((void*)r->Eip, (void*)r->Esp, 0, gp);
|
||||||
runtime·tracebackothers(gp);
|
runtime·tracebackothers(gp);
|
||||||
runtime·dumpregs(r);
|
runtime·dumpregs(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(crash)
|
||||||
|
runtime·crash();
|
||||||
|
|
||||||
|
|
||||||
runtime·exit(2);
|
runtime·exit(2);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@ runtime·dumpregs(Context *r)
|
|||||||
uint32
|
uint32
|
||||||
runtime·sighandler(ExceptionRecord *info, Context *r, G *gp)
|
runtime·sighandler(ExceptionRecord *info, Context *r, G *gp)
|
||||||
{
|
{
|
||||||
|
bool crash;
|
||||||
uintptr *sp;
|
uintptr *sp;
|
||||||
|
|
||||||
switch(info->ExceptionCode) {
|
switch(info->ExceptionCode) {
|
||||||
@ -81,12 +82,15 @@ runtime·sighandler(ExceptionRecord *info, Context *r, G *gp)
|
|||||||
}
|
}
|
||||||
runtime·printf("\n");
|
runtime·printf("\n");
|
||||||
|
|
||||||
if(runtime·gotraceback()){
|
if(runtime·gotraceback(&crash)){
|
||||||
runtime·traceback((void*)r->Rip, (void*)r->Rsp, 0, gp);
|
runtime·traceback((void*)r->Rip, (void*)r->Rsp, 0, gp);
|
||||||
runtime·tracebackothers(gp);
|
runtime·tracebackothers(gp);
|
||||||
runtime·dumpregs(r);
|
runtime·dumpregs(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(crash)
|
||||||
|
runtime·crash();
|
||||||
|
|
||||||
runtime·exit(2);
|
runtime·exit(2);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -402,12 +402,13 @@ void
|
|||||||
runtime·dopanic(int32 unused)
|
runtime·dopanic(int32 unused)
|
||||||
{
|
{
|
||||||
static bool didothers;
|
static bool didothers;
|
||||||
|
bool crash;
|
||||||
|
|
||||||
if(g->sig != 0)
|
if(g->sig != 0)
|
||||||
runtime·printf("[signal %x code=%p addr=%p pc=%p]\n",
|
runtime·printf("[signal %x code=%p addr=%p pc=%p]\n",
|
||||||
g->sig, g->sigcode0, g->sigcode1, g->sigpc);
|
g->sig, g->sigcode0, g->sigcode1, g->sigpc);
|
||||||
|
|
||||||
if(runtime·gotraceback()){
|
if(runtime·gotraceback(&crash)){
|
||||||
if(g != m->g0) {
|
if(g != m->g0) {
|
||||||
runtime·printf("\n");
|
runtime·printf("\n");
|
||||||
runtime·goroutineheader(g);
|
runtime·goroutineheader(g);
|
||||||
@ -429,6 +430,9 @@ runtime·dopanic(int32 unused)
|
|||||||
runtime·lock(&deadlock);
|
runtime·lock(&deadlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(crash)
|
||||||
|
runtime·crash();
|
||||||
|
|
||||||
runtime·exit(2);
|
runtime·exit(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,7 +232,7 @@ runtime·tracebackothers(G *me)
|
|||||||
G *gp;
|
G *gp;
|
||||||
int32 traceback;
|
int32 traceback;
|
||||||
|
|
||||||
traceback = runtime·gotraceback();
|
traceback = runtime·gotraceback(nil);
|
||||||
for(gp = runtime·allg; gp != nil; gp = gp->alllink) {
|
for(gp = runtime·allg; gp != nil; gp = gp->alllink) {
|
||||||
if(gp == me || gp->status == Gdead)
|
if(gp == me || gp->status == Gdead)
|
||||||
continue;
|
continue;
|
||||||
|
@ -17,14 +17,27 @@ enum {
|
|||||||
*/
|
*/
|
||||||
void runtime·sigpanic(void);
|
void runtime·sigpanic(void);
|
||||||
|
|
||||||
|
// The GOTRACEBACK environment variable controls the
|
||||||
|
// behavior of a Go program that is crashing and exiting.
|
||||||
|
// GOTRACEBACK=0 suppress all tracebacks
|
||||||
|
// GOTRACEBACK=1 default behavior - show tracebacks but exclude runtime frames
|
||||||
|
// GOTRACEBACK=2 show tracebacks including runtime frames
|
||||||
|
// GOTRACEBACK=crash show tracebacks including runtime frames, then crash (core dump etc)
|
||||||
int32
|
int32
|
||||||
runtime·gotraceback(void)
|
runtime·gotraceback(bool *crash)
|
||||||
{
|
{
|
||||||
byte *p;
|
byte *p;
|
||||||
|
|
||||||
|
if(crash != nil)
|
||||||
|
*crash = false;
|
||||||
p = runtime·getenv("GOTRACEBACK");
|
p = runtime·getenv("GOTRACEBACK");
|
||||||
if(p == nil || p[0] == '\0')
|
if(p == nil || p[0] == '\0')
|
||||||
return 1; // default is on
|
return 1; // default is on
|
||||||
|
if(runtime·strcmp(p, (byte*)"crash") == 0) {
|
||||||
|
if(crash != nil)
|
||||||
|
*crash = true;
|
||||||
|
return 2; // extra information
|
||||||
|
}
|
||||||
return runtime·atoi(p);
|
return runtime·atoi(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -699,7 +699,7 @@ String runtime·gostringw(uint16*);
|
|||||||
void runtime·initsig(void);
|
void runtime·initsig(void);
|
||||||
void runtime·sigenable(uint32 sig);
|
void runtime·sigenable(uint32 sig);
|
||||||
void runtime·sigdisable(uint32 sig);
|
void runtime·sigdisable(uint32 sig);
|
||||||
int32 runtime·gotraceback(void);
|
int32 runtime·gotraceback(bool *crash);
|
||||||
void runtime·goroutineheader(G*);
|
void runtime·goroutineheader(G*);
|
||||||
void runtime·traceback(uint8 *pc, uint8 *sp, uint8 *lr, G* gp);
|
void runtime·traceback(uint8 *pc, uint8 *sp, uint8 *lr, G* gp);
|
||||||
void runtime·tracebackothers(G*);
|
void runtime·tracebackothers(G*);
|
||||||
@ -793,6 +793,7 @@ G* runtime·netpoll(bool);
|
|||||||
void runtime·netpollinit(void);
|
void runtime·netpollinit(void);
|
||||||
int32 runtime·netpollopen(int32, PollDesc*);
|
int32 runtime·netpollopen(int32, PollDesc*);
|
||||||
void runtime·netpollready(G**, PollDesc*, int32);
|
void runtime·netpollready(G**, PollDesc*, int32);
|
||||||
|
void runtime·crash(void);
|
||||||
|
|
||||||
#pragma varargck argpos runtime·printf 1
|
#pragma varargck argpos runtime·printf 1
|
||||||
#pragma varargck type "d" int32
|
#pragma varargck type "d" int32
|
||||||
|
@ -36,6 +36,7 @@ runtime·sighandler(int32 sig, Siginfo *info, void *ctxt, G *gp)
|
|||||||
{
|
{
|
||||||
uintptr *sp;
|
uintptr *sp;
|
||||||
SigTab *t;
|
SigTab *t;
|
||||||
|
bool crash;
|
||||||
|
|
||||||
if(sig == SIGPROF) {
|
if(sig == SIGPROF) {
|
||||||
if(gp != m->g0 && gp != m->gsignal)
|
if(gp != m->g0 && gp != m->gsignal)
|
||||||
@ -109,11 +110,14 @@ Throw:
|
|||||||
}
|
}
|
||||||
runtime·printf("\n");
|
runtime·printf("\n");
|
||||||
|
|
||||||
if(runtime·gotraceback()){
|
if(runtime·gotraceback(&crash)){
|
||||||
runtime·traceback((void*)SIG_EIP(info, ctxt), (void*)SIG_ESP(info, ctxt), 0, gp);
|
runtime·traceback((void*)SIG_EIP(info, ctxt), (void*)SIG_ESP(info, ctxt), 0, gp);
|
||||||
runtime·tracebackothers(gp);
|
runtime·tracebackothers(gp);
|
||||||
runtime·dumpregs(info, ctxt);
|
runtime·dumpregs(info, ctxt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(crash)
|
||||||
|
runtime·crash();
|
||||||
|
|
||||||
runtime·exit(2);
|
runtime·exit(2);
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,7 @@ runtime·sighandler(int32 sig, Siginfo *info, void *ctxt, G *gp)
|
|||||||
{
|
{
|
||||||
uintptr *sp;
|
uintptr *sp;
|
||||||
SigTab *t;
|
SigTab *t;
|
||||||
|
bool crash;
|
||||||
|
|
||||||
if(sig == SIGPROF) {
|
if(sig == SIGPROF) {
|
||||||
if(gp != m->g0 && gp != m->gsignal)
|
if(gp != m->g0 && gp != m->gsignal)
|
||||||
@ -119,11 +120,14 @@ Throw:
|
|||||||
}
|
}
|
||||||
runtime·printf("\n");
|
runtime·printf("\n");
|
||||||
|
|
||||||
if(runtime·gotraceback()){
|
if(runtime·gotraceback(&crash)){
|
||||||
runtime·traceback((void*)SIG_RIP(info, ctxt), (void*)SIG_RSP(info, ctxt), 0, gp);
|
runtime·traceback((void*)SIG_RIP(info, ctxt), (void*)SIG_RSP(info, ctxt), 0, gp);
|
||||||
runtime·tracebackothers(gp);
|
runtime·tracebackothers(gp);
|
||||||
runtime·dumpregs(info, ctxt);
|
runtime·dumpregs(info, ctxt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(crash)
|
||||||
|
runtime·crash();
|
||||||
|
|
||||||
runtime·exit(2);
|
runtime·exit(2);
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,7 @@ void
|
|||||||
runtime·sighandler(int32 sig, Siginfo *info, void *ctxt, G *gp)
|
runtime·sighandler(int32 sig, Siginfo *info, void *ctxt, G *gp)
|
||||||
{
|
{
|
||||||
SigTab *t;
|
SigTab *t;
|
||||||
|
bool crash;
|
||||||
|
|
||||||
if(sig == SIGPROF) {
|
if(sig == SIGPROF) {
|
||||||
if(gp != m->g0 && gp != m->gsignal)
|
if(gp != m->g0 && gp != m->gsignal)
|
||||||
@ -109,12 +110,15 @@ Throw:
|
|||||||
}
|
}
|
||||||
runtime·printf("\n");
|
runtime·printf("\n");
|
||||||
|
|
||||||
if(runtime·gotraceback()){
|
if(runtime·gotraceback(&crash)){
|
||||||
runtime·traceback((void*)SIG_PC(info, ctxt), (void*)SIG_SP(info, ctxt), (void*)SIG_LR(info, ctxt), gp);
|
runtime·traceback((void*)SIG_PC(info, ctxt), (void*)SIG_SP(info, ctxt), (void*)SIG_LR(info, ctxt), gp);
|
||||||
runtime·tracebackothers(gp);
|
runtime·tracebackothers(gp);
|
||||||
runtime·printf("\n");
|
runtime·printf("\n");
|
||||||
runtime·dumpregs(info, ctxt);
|
runtime·dumpregs(info, ctxt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(crash)
|
||||||
|
runtime·crash();
|
||||||
|
|
||||||
runtime·exit(2);
|
runtime·exit(2);
|
||||||
}
|
}
|
||||||
|
@ -98,5 +98,23 @@ void
|
|||||||
os·sigpipe(void)
|
os·sigpipe(void)
|
||||||
{
|
{
|
||||||
runtime·setsig(SIGPIPE, SIG_DFL, false);
|
runtime·setsig(SIGPIPE, SIG_DFL, false);
|
||||||
runtime·raisesigpipe();
|
runtime·raise(SIGPIPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
runtime·crash(void)
|
||||||
|
{
|
||||||
|
#ifdef GOOS_darwin
|
||||||
|
// OS X core dumps are linear dumps of the mapped memory,
|
||||||
|
// from the first virtual byte to the last, with zeros in the gaps.
|
||||||
|
// Because of the way we arrange the address space on 64-bit systems,
|
||||||
|
// this means the OS X core file will be >128 GB and even on a zippy
|
||||||
|
// workstation can take OS X well over an hour to write (uninterruptible).
|
||||||
|
// Save users from making that mistake.
|
||||||
|
if(sizeof(void*) == 8)
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
runtime·setsig(SIGABRT, SIG_DFL, false);
|
||||||
|
runtime·raise(SIGABRT);
|
||||||
}
|
}
|
||||||
|
@ -10,4 +10,5 @@ void runtime·setsig(int32, GoSighandler*, bool);
|
|||||||
GoSighandler* runtime·getsig(int32);
|
GoSighandler* runtime·getsig(int32);
|
||||||
|
|
||||||
void runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp);
|
void runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp);
|
||||||
void runtime·raisesigpipe(void);
|
void runtime·raise(int32);
|
||||||
|
|
||||||
|
@ -670,6 +670,6 @@ runtime·showframe(Func *f, bool current)
|
|||||||
if(current && m->throwing > 0)
|
if(current && m->throwing > 0)
|
||||||
return 1;
|
return 1;
|
||||||
if(traceback < 0)
|
if(traceback < 0)
|
||||||
traceback = runtime·gotraceback();
|
traceback = runtime·gotraceback(nil);
|
||||||
return traceback > 1 || f != nil && contains(f->name, ".") && !hasprefix(f->name, "runtime.");
|
return traceback > 1 || f != nil && contains(f->name, ".") && !hasprefix(f->name, "runtime.");
|
||||||
}
|
}
|
||||||
|
@ -44,13 +44,14 @@ TEXT runtime·write(SB),7,$0
|
|||||||
INT $0x80
|
INT $0x80
|
||||||
RET
|
RET
|
||||||
|
|
||||||
TEXT runtime·raisesigpipe(SB),7,$8
|
TEXT runtime·raise(SB),7,$16
|
||||||
get_tls(CX)
|
MOVL $20, AX // getpid
|
||||||
MOVL m(CX), DX
|
INT $0x80
|
||||||
MOVL m_procid(DX), DX
|
MOVL AX, 4(SP) // pid
|
||||||
MOVL DX, 0(SP) // thread_port
|
MOVL sig+0(FP), AX
|
||||||
MOVL $13, 4(SP) // signal: SIGPIPE
|
MOVL AX, 8(SP) // signal
|
||||||
MOVL $328, AX // __pthread_kill
|
MOVL $1, 12(SP) // posix
|
||||||
|
MOVL $37, AX // kill
|
||||||
INT $0x80
|
INT $0x80
|
||||||
RET
|
RET
|
||||||
|
|
||||||
|
@ -60,12 +60,13 @@ TEXT runtime·write(SB),7,$0
|
|||||||
SYSCALL
|
SYSCALL
|
||||||
RET
|
RET
|
||||||
|
|
||||||
TEXT runtime·raisesigpipe(SB),7,$24
|
TEXT runtime·raise(SB),7,$24
|
||||||
get_tls(CX)
|
MOVL $(0x2000000+20), AX // getpid
|
||||||
MOVQ m(CX), DX
|
SYSCALL
|
||||||
MOVL $13, DI // arg 1 SIGPIPE
|
MOVQ AX, DI // arg 1 - pid
|
||||||
MOVQ m_procid(DX), SI // arg 2 thread_port
|
MOVL sig+0(FP), SI // arg 2 - signal
|
||||||
MOVL $(0x2000000+328), AX // syscall entry __pthread_kill
|
MOVL $1, DX // arg 3 - posix
|
||||||
|
MOVL $(0x2000000+37), AX // kill
|
||||||
SYSCALL
|
SYSCALL
|
||||||
RET
|
RET
|
||||||
|
|
||||||
|
@ -81,16 +81,17 @@ TEXT runtime·getrlimit(SB),7,$-4
|
|||||||
INT $0x80
|
INT $0x80
|
||||||
RET
|
RET
|
||||||
|
|
||||||
TEXT runtime·raisesigpipe(SB),7,$12
|
TEXT runtime·raise(SB),7,$16
|
||||||
// thr_self(&8(SP))
|
// thr_self(&8(SP))
|
||||||
LEAL 8(SP), AX
|
LEAL 8(SP), AX
|
||||||
MOVL AX, 0(SP)
|
MOVL AX, 4(SP)
|
||||||
MOVL $432, AX
|
MOVL $432, AX
|
||||||
INT $0x80
|
INT $0x80
|
||||||
// thr_kill(self, SIGPIPE)
|
// thr_kill(self, SIGPIPE)
|
||||||
MOVL 8(SP), AX
|
MOVL 8(SP), AX
|
||||||
MOVL AX, 0(SP)
|
MOVL AX, 4(SP)
|
||||||
MOVL $13, 4(SP)
|
MOVL sig+0(FP), AX
|
||||||
|
MOVL AX, 8(SP)
|
||||||
MOVL $433, AX
|
MOVL $433, AX
|
||||||
INT $0x80
|
INT $0x80
|
||||||
RET
|
RET
|
||||||
|
@ -95,14 +95,14 @@ TEXT runtime·getrlimit(SB),7,$-8
|
|||||||
SYSCALL
|
SYSCALL
|
||||||
RET
|
RET
|
||||||
|
|
||||||
TEXT runtime·raisesigpipe(SB),7,$16
|
TEXT runtime·raise(SB),7,$16
|
||||||
// thr_self(&8(SP))
|
// thr_self(&8(SP))
|
||||||
LEAQ 8(SP), DI // arg 1 &8(SP)
|
LEAQ 8(SP), DI // arg 1 &8(SP)
|
||||||
MOVL $432, AX
|
MOVL $432, AX
|
||||||
SYSCALL
|
SYSCALL
|
||||||
// thr_kill(self, SIGPIPE)
|
// thr_kill(self, SIGPIPE)
|
||||||
MOVQ 8(SP), DI // arg 1 id
|
MOVQ 8(SP), DI // arg 1 id
|
||||||
MOVQ $13, SI // arg 2 SIGPIPE
|
MOVL sig+0(FP), SI // arg 2
|
||||||
MOVL $433, AX
|
MOVL $433, AX
|
||||||
SYSCALL
|
SYSCALL
|
||||||
RET
|
RET
|
||||||
|
@ -87,13 +87,13 @@ TEXT runtime·getrlimit(SB),7,$-8
|
|||||||
SWI $194
|
SWI $194
|
||||||
RET
|
RET
|
||||||
|
|
||||||
TEXT runtime·raisesigpipe(SB),7,$8
|
TEXT runtime·raise(SB),7,$8
|
||||||
// thr_self(&4(R13))
|
// thr_self(&4(R13))
|
||||||
MOVW $4(R13), R0 // arg 1 &4(R13)
|
MOVW $4(R13), R0 // arg 1 &4(R13)
|
||||||
SWI $432
|
SWI $432
|
||||||
// thr_kill(self, SIGPIPE)
|
// thr_kill(self, SIGPIPE)
|
||||||
MOVW 4(R13), R0 // arg 1 id
|
MOVW 4(R13), R0 // arg 1 id
|
||||||
MOVW $13, R1 // arg 2 SIGPIPE
|
MOVW sig+0(FP), R1 // arg 2 - signal
|
||||||
SWI $433
|
SWI $433
|
||||||
RET
|
RET
|
||||||
|
|
||||||
|
@ -77,11 +77,11 @@ TEXT runtime·usleep(SB),7,$8
|
|||||||
CALL *runtime·_vdso(SB)
|
CALL *runtime·_vdso(SB)
|
||||||
RET
|
RET
|
||||||
|
|
||||||
TEXT runtime·raisesigpipe(SB),7,$12
|
TEXT runtime·raise(SB),7,$12
|
||||||
MOVL $224, AX // syscall - gettid
|
MOVL $224, AX // syscall - gettid
|
||||||
CALL *runtime·_vdso(SB)
|
CALL *runtime·_vdso(SB)
|
||||||
MOVL AX, 0(SP) // arg 1 tid
|
MOVL AX, BX // arg 1 tid
|
||||||
MOVL $13, 4(SP) // arg 2 SIGPIPE
|
MOVL sig+0(FP), CX // arg 2 signal
|
||||||
MOVL $238, AX // syscall - tkill
|
MOVL $238, AX // syscall - tkill
|
||||||
CALL *runtime·_vdso(SB)
|
CALL *runtime·_vdso(SB)
|
||||||
RET
|
RET
|
||||||
|
@ -75,11 +75,11 @@ TEXT runtime·usleep(SB),7,$16
|
|||||||
SYSCALL
|
SYSCALL
|
||||||
RET
|
RET
|
||||||
|
|
||||||
TEXT runtime·raisesigpipe(SB),7,$12
|
TEXT runtime·raise(SB),7,$12
|
||||||
MOVL $186, AX // syscall - gettid
|
MOVL $186, AX // syscall - gettid
|
||||||
SYSCALL
|
SYSCALL
|
||||||
MOVL AX, DI // arg 1 tid
|
MOVL AX, DI // arg 1 tid
|
||||||
MOVL $13, SI // arg 2 SIGPIPE
|
MOVL sig+0(FP), SI // arg 2
|
||||||
MOVL $200, AX // syscall - tkill
|
MOVL $200, AX // syscall - tkill
|
||||||
SYSCALL
|
SYSCALL
|
||||||
RET
|
RET
|
||||||
|
@ -92,11 +92,11 @@ TEXT runtime·exit1(SB),7,$-4
|
|||||||
MOVW $1003, R1
|
MOVW $1003, R1
|
||||||
MOVW R0, (R1) // fail hard
|
MOVW R0, (R1) // fail hard
|
||||||
|
|
||||||
TEXT runtime·raisesigpipe(SB),7,$-4
|
TEXT runtime·raise(SB),7,$-4
|
||||||
MOVW $SYS_gettid, R7
|
MOVW $SYS_gettid, R7
|
||||||
SWI $0
|
SWI $0
|
||||||
// arg 1 tid already in R0 from gettid
|
// arg 1 tid already in R0 from gettid
|
||||||
MOVW $13, R1 // arg 2 SIGPIPE
|
MOVW sig+0(FP), R1 // arg 2 - signal
|
||||||
MOVW $SYS_tkill, R7
|
MOVW $SYS_tkill, R7
|
||||||
SWI $0
|
SWI $0
|
||||||
RET
|
RET
|
||||||
|
@ -61,12 +61,13 @@ TEXT runtime·usleep(SB),7,$24
|
|||||||
INT $0x80
|
INT $0x80
|
||||||
RET
|
RET
|
||||||
|
|
||||||
TEXT runtime·raisesigpipe(SB),7,$12
|
TEXT runtime·raise(SB),7,$12
|
||||||
MOVL $311, AX // sys__lwp_self
|
MOVL $311, AX // sys__lwp_self
|
||||||
INT $0x80
|
INT $0x80
|
||||||
MOVL $0, 0(SP)
|
MOVL $0, 0(SP)
|
||||||
MOVL AX, 4(SP) // arg 1 - target
|
MOVL AX, 4(SP) // arg 1 - target
|
||||||
MOVL $13, 8(SP) // arg 2 - signo == SIGPIPE
|
MOVL sig+0(FP), AX
|
||||||
|
MOVL AX, 8(SP) // arg 2 - signo
|
||||||
MOVL $318, AX // sys__lwp_kill
|
MOVL $318, AX // sys__lwp_kill
|
||||||
INT $0x80
|
INT $0x80
|
||||||
RET
|
RET
|
||||||
|
@ -125,11 +125,11 @@ TEXT runtime·usleep(SB),7,$16
|
|||||||
SYSCALL
|
SYSCALL
|
||||||
RET
|
RET
|
||||||
|
|
||||||
TEXT runtime·raisesigpipe(SB),7,$16
|
TEXT runtime·raise(SB),7,$16
|
||||||
MOVL $311, AX // sys__lwp_self
|
MOVL $311, AX // sys__lwp_self
|
||||||
SYSCALL
|
SYSCALL
|
||||||
MOVQ AX, DI // arg 1 - target
|
MOVQ AX, DI // arg 1 - target
|
||||||
MOVQ $13, SI // arg 2 - signo == SIGPIPE
|
MOVL sig+0(FP), SI // arg 2 - signo
|
||||||
MOVL $318, AX // sys__lwp_kill
|
MOVL $318, AX // sys__lwp_kill
|
||||||
SYSCALL
|
SYSCALL
|
||||||
RET
|
RET
|
||||||
|
@ -88,9 +88,9 @@ TEXT runtime·usleep(SB),7,$16
|
|||||||
SWI $0xa001ae // sys_nanosleep
|
SWI $0xa001ae // sys_nanosleep
|
||||||
RET
|
RET
|
||||||
|
|
||||||
TEXT runtime·raisesigpipe(SB),7,$16
|
TEXT runtime·raise(SB),7,$16
|
||||||
SWI $0xa00137 // sys__lwp_self, the returned R0 is arg 1
|
SWI $0xa00137 // sys__lwp_self, the returned R0 is arg 1
|
||||||
MOVW $13, R1 // arg 2 - signo == SIGPIPE
|
MOVW sig+0(FP), R1 // arg 2 - signal
|
||||||
SWI $0xa0013e // sys__lwp_kill
|
SWI $0xa0013e // sys__lwp_kill
|
||||||
RET
|
RET
|
||||||
|
|
||||||
|
@ -62,12 +62,13 @@ TEXT runtime·usleep(SB),7,$20
|
|||||||
INT $0x80
|
INT $0x80
|
||||||
RET
|
RET
|
||||||
|
|
||||||
TEXT runtime·raisesigpipe(SB),7,$12
|
TEXT runtime·raise(SB),7,$12
|
||||||
MOVL $299, AX // sys_getthrid
|
MOVL $299, AX // sys_getthrid
|
||||||
INT $0x80
|
INT $0x80
|
||||||
MOVL $0, 0(SP)
|
MOVL $0, 0(SP)
|
||||||
MOVL AX, 4(SP) // arg 1 - pid
|
MOVL AX, 4(SP) // arg 1 - pid
|
||||||
MOVL $13, 8(SP) // arg 2 - signum == SIGPIPE
|
MOVL sig+0(FP), AX
|
||||||
|
MOVL AX, 8(SP) // arg 2 - signum
|
||||||
MOVL $37, AX // sys_kill
|
MOVL $37, AX // sys_kill
|
||||||
INT $0x80
|
INT $0x80
|
||||||
RET
|
RET
|
||||||
|
@ -133,11 +133,11 @@ TEXT runtime·usleep(SB),7,$16
|
|||||||
SYSCALL
|
SYSCALL
|
||||||
RET
|
RET
|
||||||
|
|
||||||
TEXT runtime·raisesigpipe(SB),7,$16
|
TEXT runtime·raise(SB),7,$16
|
||||||
MOVL $299, AX // sys_getthrid
|
MOVL $299, AX // sys_getthrid
|
||||||
SYSCALL
|
SYSCALL
|
||||||
MOVQ AX, DI // arg 1 - pid
|
MOVQ AX, DI // arg 1 - pid
|
||||||
MOVQ $13, SI // arg 2 - signum == SIGPIPE
|
MOVL sig+0(FP), SI // arg 2 - signum
|
||||||
MOVL $37, AX // sys_kill
|
MOVL $37, AX // sys_kill
|
||||||
SYSCALL
|
SYSCALL
|
||||||
RET
|
RET
|
||||||
|
Loading…
Reference in New Issue
Block a user