Skip to content

Commit 8fcdc70

Browse files
committed
runtime: add GODEBUG invalidptr setting
Fixes #8861. Fixes #8911. LGTM=r R=r CC=golang-codereviews https://golang.org/cl/165780043
1 parent c4efaac commit 8fcdc70

File tree

5 files changed

+16
-4
lines changed

5 files changed

+16
-4
lines changed

src/runtime/extern.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@ a comma-separated list of name=val pairs. Supported names are:
3939
gcdead: setting gcdead=1 causes the garbage collector to clobber all stack slots
4040
that it thinks are dead.
4141
42+
invalidptr: defaults to invalidptr=1, causing the garbage collector and stack
43+
copier to crash the program if an invalid pointer value (for example, 1)
44+
is found in a pointer-typed location. Setting invalidptr=0 disables this check.
45+
This should only be used as a temporary workaround to diagnose buggy code.
46+
The real fix is to not store integers in pointer-typed locations.
47+
4248
scheddetail: setting schedtrace=X and scheddetail=1 causes the scheduler to emit
4349
detailed multiline info every X milliseconds, describing state of the scheduler,
4450
processors, threads and goroutines.

src/runtime/mgc0.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ scanblock(byte *b, uintptr n, byte *ptrmask)
330330
if(obj == nil)
331331
continue;
332332
if(obj < arena_start || obj >= arena_used) {
333-
if((uintptr)obj < PhysPageSize) {
333+
if((uintptr)obj < PhysPageSize && runtime·invalidptr) {
334334
s = nil;
335335
goto badobj;
336336
}
@@ -375,7 +375,7 @@ scanblock(byte *b, uintptr n, byte *ptrmask)
375375
else
376376
runtime·printf(" span=%p-%p-%p state=%d\n", (uintptr)s->start<<PageShift, s->limit, (uintptr)(s->start+s->npages)<<PageShift, s->state);
377377
if(ptrmask != nil)
378-
runtime·throw("bad pointer");
378+
runtime·throw("invalid heap pointer");
379379
// Add to badblock list, which will cause the garbage collection
380380
// to keep repeating until it has traced the chain of pointers
381381
// leading to obj all the way back to a root.

src/runtime/runtime.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,9 +276,13 @@ struct DbgVar
276276
int32* value;
277277
};
278278

279+
// Do we report invalid pointers found during stack or heap scans?
280+
int32 runtime·invalidptr = 1;
281+
279282
#pragma dataflag NOPTR /* dbgvar has no heap pointers */
280283
static DbgVar dbgvar[] = {
281284
{"allocfreetrace", &runtime·debug.allocfreetrace},
285+
{"invalidptr", &runtime·invalidptr},
282286
{"efence", &runtime·debug.efence},
283287
{"gctrace", &runtime·debug.gctrace},
284288
{"gcdead", &runtime·debug.gcdead},

src/runtime/runtime.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,8 @@ enum {
657657
byte* runtime·startup_random_data;
658658
uint32 runtime·startup_random_data_len;
659659

660+
int32 runtime·invalidptr;
661+
660662
enum {
661663
// hashinit wants this many random bytes
662664
HashRandomBytes = 32

src/runtime/stack.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -401,12 +401,12 @@ adjustpointers(byte **scanp, BitVector *bv, AdjustInfo *adjinfo, Func *f)
401401
break;
402402
case BitsPointer:
403403
p = scanp[i];
404-
if(f != nil && (byte*)0 < p && (p < (byte*)PageSize || (uintptr)p == PoisonGC || (uintptr)p == PoisonStack)) {
404+
if(f != nil && (byte*)0 < p && (p < (byte*)PageSize && runtime·invalidptr || (uintptr)p == PoisonGC || (uintptr)p == PoisonStack)) {
405405
// Looks like a junk value in a pointer slot.
406406
// Live analysis wrong?
407407
g->m->traceback = 2;
408408
runtime·printf("runtime: bad pointer in frame %s at %p: %p\n", runtime·funcname(f), &scanp[i], p);
409-
runtime·throw("bad pointer!");
409+
runtime·throw("invalid stack pointer");
410410
}
411411
if(minp <= p && p < maxp) {
412412
if(StackDebug >= 3)

0 commit comments

Comments
 (0)