mirror of
https://github.com/golang/go
synced 2024-11-19 03:54:42 -07:00
runtime: add GODEBUG invalidptr setting
Fixes #8861. Fixes #8911. LGTM=r R=r CC=golang-codereviews https://golang.org/cl/165780043
This commit is contained in:
parent
c4efaac15d
commit
8fcdc70c5e
@ -39,6 +39,12 @@ a comma-separated list of name=val pairs. Supported names are:
|
|||||||
gcdead: setting gcdead=1 causes the garbage collector to clobber all stack slots
|
gcdead: setting gcdead=1 causes the garbage collector to clobber all stack slots
|
||||||
that it thinks are dead.
|
that it thinks are dead.
|
||||||
|
|
||||||
|
invalidptr: defaults to invalidptr=1, causing the garbage collector and stack
|
||||||
|
copier to crash the program if an invalid pointer value (for example, 1)
|
||||||
|
is found in a pointer-typed location. Setting invalidptr=0 disables this check.
|
||||||
|
This should only be used as a temporary workaround to diagnose buggy code.
|
||||||
|
The real fix is to not store integers in pointer-typed locations.
|
||||||
|
|
||||||
scheddetail: setting schedtrace=X and scheddetail=1 causes the scheduler to emit
|
scheddetail: setting schedtrace=X and scheddetail=1 causes the scheduler to emit
|
||||||
detailed multiline info every X milliseconds, describing state of the scheduler,
|
detailed multiline info every X milliseconds, describing state of the scheduler,
|
||||||
processors, threads and goroutines.
|
processors, threads and goroutines.
|
||||||
|
@ -330,7 +330,7 @@ scanblock(byte *b, uintptr n, byte *ptrmask)
|
|||||||
if(obj == nil)
|
if(obj == nil)
|
||||||
continue;
|
continue;
|
||||||
if(obj < arena_start || obj >= arena_used) {
|
if(obj < arena_start || obj >= arena_used) {
|
||||||
if((uintptr)obj < PhysPageSize) {
|
if((uintptr)obj < PhysPageSize && runtime·invalidptr) {
|
||||||
s = nil;
|
s = nil;
|
||||||
goto badobj;
|
goto badobj;
|
||||||
}
|
}
|
||||||
@ -375,7 +375,7 @@ scanblock(byte *b, uintptr n, byte *ptrmask)
|
|||||||
else
|
else
|
||||||
runtime·printf(" span=%p-%p-%p state=%d\n", (uintptr)s->start<<PageShift, s->limit, (uintptr)(s->start+s->npages)<<PageShift, s->state);
|
runtime·printf(" span=%p-%p-%p state=%d\n", (uintptr)s->start<<PageShift, s->limit, (uintptr)(s->start+s->npages)<<PageShift, s->state);
|
||||||
if(ptrmask != nil)
|
if(ptrmask != nil)
|
||||||
runtime·throw("bad pointer");
|
runtime·throw("invalid heap pointer");
|
||||||
// Add to badblock list, which will cause the garbage collection
|
// Add to badblock list, which will cause the garbage collection
|
||||||
// to keep repeating until it has traced the chain of pointers
|
// to keep repeating until it has traced the chain of pointers
|
||||||
// leading to obj all the way back to a root.
|
// leading to obj all the way back to a root.
|
||||||
|
@ -276,9 +276,13 @@ struct DbgVar
|
|||||||
int32* value;
|
int32* value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Do we report invalid pointers found during stack or heap scans?
|
||||||
|
int32 runtime·invalidptr = 1;
|
||||||
|
|
||||||
#pragma dataflag NOPTR /* dbgvar has no heap pointers */
|
#pragma dataflag NOPTR /* dbgvar has no heap pointers */
|
||||||
static DbgVar dbgvar[] = {
|
static DbgVar dbgvar[] = {
|
||||||
{"allocfreetrace", &runtime·debug.allocfreetrace},
|
{"allocfreetrace", &runtime·debug.allocfreetrace},
|
||||||
|
{"invalidptr", &runtime·invalidptr},
|
||||||
{"efence", &runtime·debug.efence},
|
{"efence", &runtime·debug.efence},
|
||||||
{"gctrace", &runtime·debug.gctrace},
|
{"gctrace", &runtime·debug.gctrace},
|
||||||
{"gcdead", &runtime·debug.gcdead},
|
{"gcdead", &runtime·debug.gcdead},
|
||||||
|
@ -657,6 +657,8 @@ enum {
|
|||||||
byte* runtime·startup_random_data;
|
byte* runtime·startup_random_data;
|
||||||
uint32 runtime·startup_random_data_len;
|
uint32 runtime·startup_random_data_len;
|
||||||
|
|
||||||
|
int32 runtime·invalidptr;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
// hashinit wants this many random bytes
|
// hashinit wants this many random bytes
|
||||||
HashRandomBytes = 32
|
HashRandomBytes = 32
|
||||||
|
@ -401,12 +401,12 @@ adjustpointers(byte **scanp, BitVector *bv, AdjustInfo *adjinfo, Func *f)
|
|||||||
break;
|
break;
|
||||||
case BitsPointer:
|
case BitsPointer:
|
||||||
p = scanp[i];
|
p = scanp[i];
|
||||||
if(f != nil && (byte*)0 < p && (p < (byte*)PageSize || (uintptr)p == PoisonGC || (uintptr)p == PoisonStack)) {
|
if(f != nil && (byte*)0 < p && (p < (byte*)PageSize && runtime·invalidptr || (uintptr)p == PoisonGC || (uintptr)p == PoisonStack)) {
|
||||||
// Looks like a junk value in a pointer slot.
|
// Looks like a junk value in a pointer slot.
|
||||||
// Live analysis wrong?
|
// Live analysis wrong?
|
||||||
g->m->traceback = 2;
|
g->m->traceback = 2;
|
||||||
runtime·printf("runtime: bad pointer in frame %s at %p: %p\n", runtime·funcname(f), &scanp[i], p);
|
runtime·printf("runtime: bad pointer in frame %s at %p: %p\n", runtime·funcname(f), &scanp[i], p);
|
||||||
runtime·throw("bad pointer!");
|
runtime·throw("invalid stack pointer");
|
||||||
}
|
}
|
||||||
if(minp <= p && p < maxp) {
|
if(minp <= p && p < maxp) {
|
||||||
if(StackDebug >= 3)
|
if(StackDebug >= 3)
|
||||||
|
Loading…
Reference in New Issue
Block a user