Commit d5b40b6a authored by Russ Cox's avatar Russ Cox

runtime: add GODEBUG gcshrinkstackoff, gcstackbarrieroff, and gcstoptheworld variables

While we're here, update the documentation and delete variables with no effect.

Change-Id: I4df0d266dff880df61b488ed547c2870205862f0
Reviewed-on: https://go-review.googlesource.com/10790Reviewed-by: 's avatarAustin Clements <austin@google.com>
parent 80ec7117
...@@ -21,8 +21,8 @@ is GOGC=100. Setting GOGC=off disables the garbage collector entirely. ...@@ -21,8 +21,8 @@ is GOGC=100. Setting GOGC=off disables the garbage collector entirely.
The runtime/debug package's SetGCPercent function allows changing this The runtime/debug package's SetGCPercent function allows changing this
percentage at run time. See http://golang.org/pkg/runtime/debug/#SetGCPercent. percentage at run time. See http://golang.org/pkg/runtime/debug/#SetGCPercent.
The GODEBUG variable controls debug output from the runtime. GODEBUG value is The GODEBUG variable controls debugging variables within the runtime.
a comma-separated list of name=val pairs. Supported names are: It is a comma-separated list of name=val pairs setting these named variables:
allocfreetrace: setting allocfreetrace=1 causes every allocation to be allocfreetrace: setting allocfreetrace=1 causes every allocation to be
profiled and a stack trace printed on each object's allocation and free. profiled and a stack trace printed on each object's allocation and free.
...@@ -31,13 +31,34 @@ a comma-separated list of name=val pairs. Supported names are: ...@@ -31,13 +31,34 @@ a comma-separated list of name=val pairs. Supported names are:
where each object is allocated on a unique page and addresses are where each object is allocated on a unique page and addresses are
never recycled. never recycled.
gccheckmark: setting gccheckmark=1 enables verification of the
garbage collector's concurrent mark phase by performing a
second mark pass while the world is stopped. If the second
pass finds a reachable object that was not found by concurrent
mark, the garbage collector will panic.
gcpacertrace: setting gcpacertrace=1 causes the garbage collector to
print information about the internal state of the concurrent pacer.
gcshrinkstackoff: setting gcshrinkstackoff=1 disables moving goroutines
onto smaller stacks. In this mode, a goroutine's stack can only grow.
gcstackbarrieroff: setting gcstackbarrieroff=1 disables the use of stack barriers
that allow the garbage collector to avoid repeating a stack scan during the
mark termination phase.
gcstoptheworld: setting gcstoptheworld=1 disables concurrent garbage collection,
making every garbage collection a stop-the-world event. Setting gcstoptheworld=2
also disables concurrent sweeping after the garbage collection finishes.
gctrace: setting gctrace=1 causes the garbage collector to emit a single line to standard gctrace: setting gctrace=1 causes the garbage collector to emit a single line to standard
error at each collection, summarizing the amount of memory collected and the error at each collection, summarizing the amount of memory collected and the
length of the pause. Setting gctrace=2 emits the same summary but also length of the pause. Setting gctrace=2 emits the same summary but also
repeats each collection. repeats each collection.
gcdead: setting gcdead=1 causes the garbage collector to clobber all stack slots memprofilerate: setting memprofilerate=X will update the value of runtime.MemProfileRate.
that it thinks are dead. When set to 0 memory profiling is disabled. Refer to the description of
MemProfileRate for the default value.
invalidptr: defaults to invalidptr=1, causing the garbage collector and stack invalidptr: defaults to invalidptr=1, causing the garbage collector and stack
copier to crash the program if an invalid pointer value (for example, 1) copier to crash the program if an invalid pointer value (for example, 1)
...@@ -45,9 +66,11 @@ a comma-separated list of name=val pairs. Supported names are: ...@@ -45,9 +66,11 @@ a comma-separated list of name=val pairs. Supported names are:
This should only be used as a temporary workaround to diagnose buggy code. 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. The real fix is to not store integers in pointer-typed locations.
memprofilerate: setting memprofilerate=X will update the value of runtime.MemProfileRate. sbrk: setting sbrk=1 replaces the memory allocator and garbage collector
When set to 0 memory profiling is disabled. Refer to the description of with a trivial allocator that obtains memory from the operating system and
MemProfileRate for the default value. never reclaims any memory.
scavenge: scavenge=1 enables debugging mode of heap scavenger.
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,
...@@ -56,14 +79,6 @@ a comma-separated list of name=val pairs. Supported names are: ...@@ -56,14 +79,6 @@ a comma-separated list of name=val pairs. Supported names are:
schedtrace: setting schedtrace=X causes the scheduler to emit a single line to standard schedtrace: setting schedtrace=X causes the scheduler to emit a single line to standard
error every X milliseconds, summarizing the scheduler state. error every X milliseconds, summarizing the scheduler state.
scavenge: scavenge=1 enables debugging mode of heap scavenger.
gccheckmark: setting gccheckmark=1 enables verification of the
garbage collector's concurrent mark phase by performing a
second mark pass while the world is stopped. If the second
pass finds a reachable object that was not found by concurrent
mark, the garbage collector will panic.
The GOMAXPROCS variable limits the number of operating system threads that 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 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 that can be blocked in system calls on behalf of Go code; those do not count against
......
...@@ -740,6 +740,12 @@ func startGC(mode int) { ...@@ -740,6 +740,12 @@ func startGC(mode int) {
releasem(mp) releasem(mp)
mp = nil mp = nil
if debug.gcstoptheworld == 1 {
mode = gcForceMode
} else if debug.gcstoptheworld == 2 {
mode = gcForceBlockMode
}
if mode != gcBackgroundMode { if mode != gcBackgroundMode {
// special synchronous cases // special synchronous cases
gc(mode) gc(mode)
......
...@@ -327,6 +327,10 @@ func scanstack(gp *g) { ...@@ -327,6 +327,10 @@ func scanstack(gp *g) {
barrierOffset = firstStackBarrierOffset barrierOffset = firstStackBarrierOffset
nextBarrier = sp + barrierOffset nextBarrier = sp + barrierOffset
if debug.gcstackbarrieroff > 0 {
nextBarrier = ^uintptr(0)
}
if gp.stkbarPos != 0 || len(gp.stkbar) != 0 { if gp.stkbarPos != 0 || len(gp.stkbar) != 0 {
// If this happens, it's probably because we // If this happens, it's probably because we
// scanned a stack twice in the same phase. // scanned a stack twice in the same phase.
......
...@@ -306,33 +306,37 @@ type dbgVar struct { ...@@ -306,33 +306,37 @@ type dbgVar struct {
// existing int var for that value, which may // existing int var for that value, which may
// already have an initial value. // already have an initial value.
var debug struct { var debug struct {
allocfreetrace int32 allocfreetrace int32
efence int32 efence int32
gcdead int32 gccheckmark int32
gctrace int32 gcpacertrace int32
invalidptr int32 gcshrinkstackoff int32
scavenge int32 gcstackbarrieroff int32
scheddetail int32 gcstoptheworld int32
schedtrace int32 gctrace int32
wbshadow int32 invalidptr int32
gccheckmark int32 sbrk int32
sbrk int32 scavenge int32
gcpacertrace int32 scheddetail int32
schedtrace int32
wbshadow int32
} }
var dbgvars = []dbgVar{ var dbgvars = []dbgVar{
{"allocfreetrace", &debug.allocfreetrace}, {"allocfreetrace", &debug.allocfreetrace},
{"efence", &debug.efence}, {"efence", &debug.efence},
{"gcdead", &debug.gcdead}, {"gccheckmark", &debug.gccheckmark},
{"gcpacertrace", &debug.gcpacertrace},
{"gcshrinkstackoff", &debug.gcshrinkstackoff},
{"gcstackbarrieroff", &debug.gcstackbarrieroff},
{"gcstoptheworld", &debug.gcstoptheworld},
{"gctrace", &debug.gctrace}, {"gctrace", &debug.gctrace},
{"invalidptr", &debug.invalidptr}, {"invalidptr", &debug.invalidptr},
{"sbrk", &debug.sbrk},
{"scavenge", &debug.scavenge}, {"scavenge", &debug.scavenge},
{"scheddetail", &debug.scheddetail}, {"scheddetail", &debug.scheddetail},
{"schedtrace", &debug.schedtrace}, {"schedtrace", &debug.schedtrace},
{"wbshadow", &debug.wbshadow}, {"wbshadow", &debug.wbshadow},
{"gccheckmark", &debug.gccheckmark},
{"sbrk", &debug.sbrk},
{"gcpacertrace", &debug.gcpacertrace},
} }
func parsedebugvars() { func parsedebugvars() {
......
...@@ -826,6 +826,10 @@ func shrinkstack(gp *g) { ...@@ -826,6 +826,10 @@ func shrinkstack(gp *g) {
throw("missing stack in shrinkstack") throw("missing stack in shrinkstack")
} }
if debug.gcshrinkstackoff > 0 {
return
}
oldsize := gp.stackAlloc oldsize := gp.stackAlloc
newsize := oldsize / 2 newsize := oldsize / 2
if newsize < _FixedStack { if newsize < _FixedStack {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment