1
0
mirror of https://github.com/golang/go synced 2024-11-18 15:04:44 -07:00

runtime: introduce GODEBUG env var

Currently it replaces GOGCTRACE env var (GODEBUG=gctrace=1).
The plan is to extend it with other type of debug tracing,
e.g. GODEBUG=gctrace=1,schedtrace=100.

R=rsc
CC=bradfitz, daniel.morsing, gobot, golang-dev
https://golang.org/cl/10026045
This commit is contained in:
Dmitriy Vyukov 2013-06-28 18:37:06 +04:00
parent 1e112cd59f
commit 4b536a550f
8 changed files with 53 additions and 25 deletions

View File

@ -14,7 +14,7 @@ import (
"text/template"
)
// testEnv excludes GOGCTRACE from the environment
// testEnv excludes GODEBUG from the environment
// to prevent its output from breaking tests that
// are trying to parse other command output.
func testEnv(cmd *exec.Cmd) *exec.Cmd {
@ -22,7 +22,7 @@ func testEnv(cmd *exec.Cmd) *exec.Cmd {
panic("environment already set")
}
for _, env := range os.Environ() {
if strings.HasPrefix(env, "GOGCTRACE=") {
if strings.HasPrefix(env, "GODEBUG=") {
continue
}
cmd.Env = append(cmd.Env, env)

View File

@ -21,10 +21,11 @@ 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
The GODEBUG variable controls debug output from the runtime. GODEBUG value is
a comma-separated list of name=val pairs. Supported names are:
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
length of the pause. Setting GOGCTRACE=2 emits the same summary but also
length of the pause. Setting gctrace=2 emits the same summary but also
repeats each collection.
The GOMAXPROCS variable limits the number of operating system threads that

View File

@ -82,8 +82,6 @@ enum {
//
uint32 runtime·worldsema = 1;
static int32 gctrace;
typedef struct Obj Obj;
struct Obj
{
@ -1950,7 +1948,6 @@ static FuncVal runfinqv = {runfinq};
void
runtime·gc(int32 force)
{
byte *p;
struct gc_args a;
int32 i;
@ -1978,10 +1975,6 @@ runtime·gc(int32 force)
if(gcpercent == GcpercentUnknown)
gcpercent = readgogc();
runtime·unlock(&runtime·mheap);
p = runtime·getenv("GOGCTRACE");
if(p != nil)
gctrace = runtime·atoi(p);
}
if(gcpercent < 0)
return;
@ -2004,7 +1997,7 @@ runtime·gc(int32 force)
// the root set down a bit (g0 stacks are not scanned, and
// we don't need to scan gc's internal state). Also an
// enabler for copyable stacks.
for(i = 0; i < (gctrace > 1 ? 2 : 1); i++) {
for(i = 0; i < (runtime·debug.gctrace > 1 ? 2 : 1); i++) {
if(g == m->g0) {
// already on g0
gc(&a);
@ -2068,7 +2061,7 @@ gc(struct gc_args *args)
heap0 = 0;
obj0 = 0;
if(gctrace) {
if(runtime·debug.gctrace) {
updatememstats(nil);
heap0 = mstats.heap_alloc;
obj0 = mstats.nmalloc - mstats.nfree;
@ -2131,7 +2124,7 @@ gc(struct gc_args *args)
if(mstats.debuggc)
runtime·printf("pause %D\n", t4-t0);
if(gctrace) {
if(runtime·debug.gctrace) {
updatememstats(&stats);
heap1 = mstats.heap_alloc;
obj1 = mstats.nmalloc - mstats.nfree;

View File

@ -441,8 +441,6 @@ runtime·MHeap_Scavenger(void)
uint64 tick, now, forcegc, limit;
uint32 k;
uintptr sumreleased;
byte *env;
bool trace;
Note note, *notep;
g->issystem = true;
@ -459,11 +457,6 @@ runtime·MHeap_Scavenger(void)
else
tick = limit/2;
trace = false;
env = runtime·getenv("GOGCTRACE");
if(env != nil)
trace = runtime·atoi(env) > 0;
h = &runtime·mheap;
for(k=0;; k++) {
runtime·noteclear(&note);
@ -484,7 +477,7 @@ runtime·MHeap_Scavenger(void)
runtime·entersyscallblock();
runtime·notesleep(&note);
runtime·exitsyscall();
if(trace)
if(runtime·debug.gctrace > 0)
runtime·printf("scvg%d: GC forced\n", k);
runtime·lock(h);
now = runtime·nanotime();
@ -492,7 +485,7 @@ runtime·MHeap_Scavenger(void)
sumreleased = scavenge(now, limit);
runtime·unlock(h);
if(trace) {
if(runtime·debug.gctrace > 0) {
if(sumreleased > 0)
runtime·printf("scvg%d: %p MB released\n", k, sumreleased>>20);
runtime·printf("scvg%d: inuse: %D, idle: %D, sys: %D, released: %D, consumed: %D (MB)\n",

View File

@ -132,6 +132,7 @@ runtime·schedinit(void)
runtime·goargs();
runtime·goenvs();
runtime·parsedebugvars();
// Allocate internal symbol table representation now, we need it for GC anyway.
runtime·symtabinit();

View File

@ -147,7 +147,7 @@ func runTests() ([]byte, error) {
// It is required because the tests contain a lot of data races on the same addresses
// (the tests are simple and the memory is constantly reused).
for _, env := range os.Environ() {
if strings.HasPrefix(env, "GOMAXPROCS=") || strings.HasPrefix(env, "GOGCTRACE=") {
if strings.HasPrefix(env, "GOMAXPROCS=") || strings.HasPrefix(env, "GODEBUG=") {
continue
}
cmd.Env = append(cmd.Env, env)

View File

@ -365,3 +365,34 @@ runtimepprof·runtime_cyclesPerSecond(int64 res)
res = runtime·tickspersecond();
FLUSH(&res);
}
DebugVars runtime·debug;
static struct {
int8* name;
int32* value;
} dbgvar[] = {
{"gctrace", &runtime·debug.gctrace},
};
void
runtime·parsedebugvars(void)
{
byte *p;
int32 i, n;
p = runtime·getenv("GODEBUG");
if(p == nil)
return;
for(;;) {
for(i=0; i<nelem(dbgvar); i++) {
n = runtime·findnull((byte*)dbgvar[i].name);
if(runtime·mcmp(p, (byte*)dbgvar[i].name, n) == 0 && p[n] == '=')
*dbgvar[i].value = runtime·atoi(p+n+1);
}
p = runtime·strstr(p, (byte*)",");
if(p == nil)
break;
p++;
}
}

View File

@ -86,6 +86,7 @@ typedef struct ParFor ParFor;
typedef struct ParForThread ParForThread;
typedef struct CgoMal CgoMal;
typedef struct PollDesc PollDesc;
typedef struct DebugVars DebugVars;
/*
* Per-CPU declaration.
@ -525,6 +526,12 @@ struct CgoMal
void *alloc;
};
// Holds variables parsed from GODEBUG env var.
struct DebugVars
{
int32 gctrace;
};
/*
* defined macros
* you need super-gopher-guru privilege
@ -702,6 +709,7 @@ extern uint32 runtime·maxstring;
extern uint32 runtime·Hchansize;
extern uint32 runtime·cpuid_ecx;
extern uint32 runtime·cpuid_edx;
extern DebugVars runtime·debug;
/*
* common functions and data
@ -841,6 +849,7 @@ int32 runtime·netpollopen(uintptr, PollDesc*);
int32 runtime·netpollclose(uintptr);
void runtime·netpollready(G**, PollDesc*, int32);
void runtime·crash(void);
void runtime·parsedebugvars(void);
void _rt0_go(void);
#pragma varargck argpos runtime·printf 1