mirror of
https://github.com/golang/go
synced 2024-11-12 04:00:23 -07:00
runtime: harden conditions when runtime panics on crash
This is especially important for SetPanicOnCrash, but also useful for e.g. nil deref in mallocgc. Panics on such crashes can't lead to anything useful, only to deadlocks, hangs and obscure crashes. This is a copy of broken but already LGTMed https://golang.org/cl/68540043/ TBR=rsc R=rsc CC=golang-codereviews https://golang.org/cl/75320043
This commit is contained in:
parent
5daffee17f
commit
1569628725
@ -485,6 +485,29 @@ runtime·throwinit(void)
|
||||
runtime·throw("recursive call during initialization - linker skew");
|
||||
}
|
||||
|
||||
bool
|
||||
runtime·canpanic(G *gp)
|
||||
{
|
||||
byte g;
|
||||
|
||||
USED(&g); // don't use global g, it points to gsignal
|
||||
|
||||
// Is it okay for gp to panic instead of crashing the program?
|
||||
// Yes, as long as it is running Go code, not runtime code,
|
||||
// and not stuck in a system call.
|
||||
if(gp == nil || gp != m->curg)
|
||||
return false;
|
||||
if(m->locks != 0 || m->mallocing != 0 || m->throwing != 0 || m->gcing != 0 || m->dying != 0)
|
||||
return false;
|
||||
if(gp->status != Grunning || gp->syscallsp != 0)
|
||||
return false;
|
||||
#ifdef GOOS_windows
|
||||
if(m->libcallsp != 0)
|
||||
return false;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
runtime·throw(int8 *s)
|
||||
{
|
||||
|
@ -836,6 +836,7 @@ void runtime·goenvs_unix(void);
|
||||
void* runtime·getu(void);
|
||||
void runtime·throw(int8*);
|
||||
void runtime·panicstring(int8*);
|
||||
bool runtime·canpanic(G*);
|
||||
void runtime·prints(int8*);
|
||||
void runtime·printf(int8*, ...);
|
||||
byte* runtime·mchr(byte*, byte, byte*);
|
||||
|
@ -45,7 +45,7 @@ runtime·sighandler(int32 sig, Siginfo *info, void *ctxt, G *gp)
|
||||
|
||||
t = &runtime·sigtab[sig];
|
||||
if(SIG_CODE0(info, ctxt) != SI_USER && (t->flags & SigPanic)) {
|
||||
if(gp == nil || gp == m->g0)
|
||||
if(!runtime·canpanic(gp))
|
||||
goto Throw;
|
||||
|
||||
// Make it look like a call to the signal func.
|
||||
|
@ -54,7 +54,7 @@ runtime·sighandler(int32 sig, Siginfo *info, void *ctxt, G *gp)
|
||||
|
||||
t = &runtime·sigtab[sig];
|
||||
if(SIG_CODE0(info, ctxt) != SI_USER && (t->flags & SigPanic)) {
|
||||
if(gp == nil || gp == m->g0)
|
||||
if(!runtime·canpanic(gp))
|
||||
goto Throw;
|
||||
|
||||
// Make it look like a call to the signal func.
|
||||
|
@ -52,7 +52,7 @@ runtime·sighandler(int32 sig, Siginfo *info, void *ctxt, G *gp)
|
||||
|
||||
t = &runtime·sigtab[sig];
|
||||
if(SIG_CODE0(info, ctxt) != SI_USER && (t->flags & SigPanic)) {
|
||||
if(gp == nil || gp == m->g0)
|
||||
if(!runtime·canpanic(gp))
|
||||
goto Throw;
|
||||
|
||||
// Make it look like a call to the signal func.
|
||||
|
Loading…
Reference in New Issue
Block a user