1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
14 // The GOTRACEBACK environment variable controls the
15 // behavior of a Go program that is crashing and exiting.
16 // GOTRACEBACK=0 suppress all tracebacks
17 // GOTRACEBACK=1 default behavior - show tracebacks but exclude runtime frames
18 // GOTRACEBACK=2 show tracebacks including runtime frames
19 // GOTRACEBACK=crash show tracebacks including runtime frames, then crash (core dump etc)
21 runtime_gotraceback(bool *crash)
27 p = runtime_getenv("GOTRACEBACK");
28 if(p == nil || p[0] == '\0')
29 return 1; // default is on
30 if(runtime_strcmp((const char *)p, "crash") == 0) {
33 return 2; // extra information
35 return runtime_atoi(p);
41 extern Slice os_Args __asm__ (GOSYM_PREFIX "os.Args");
42 extern Slice syscall_Envs __asm__ (GOSYM_PREFIX "syscall.Envs");
44 void (*runtime_sysargs)(int32, uint8**);
47 runtime_args(int32 c, byte **v)
51 if(runtime_sysargs != nil)
52 runtime_sysargs(c, v);
58 return argc == 0 ? nil : argv[0];
61 // Information about what cpu features are available.
62 // Set on startup in asm_{x86/amd64}.s.
63 uint32 runtime_cpuid_ecx;
64 uint32 runtime_cpuid_edx;
72 // for windows implementation see "os" package
76 s = runtime_malloc(argc*sizeof s[0]);
78 s[i] = runtime_gostringnocopy((const byte*)argv[i]);
79 os_Args.__values = (void*)s;
80 os_Args.__count = argc;
81 os_Args.__capacity = argc;
85 runtime_goenvs_unix(void)
90 for(n=0; argv[argc+1+n] != 0; n++)
93 s = runtime_malloc(n*sizeof s[0]);
95 s[i] = runtime_gostringnocopy(argv[argc+1+i]);
96 syscall_Envs.__values = (void*)s;
97 syscall_Envs.__count = n;
98 syscall_Envs.__capacity = n;
102 runtime_atoi(const byte *p)
107 while('0' <= *p && *p <= '9')
108 n = n*10 + *p++ - '0';
112 static struct root_list runtime_roots =
114 { { &syscall_Envs, sizeof syscall_Envs },
115 { &os_Args, sizeof os_Args },
127 if(runtime_cas64(&z64, &x64, 1))
128 runtime_throw("cas64 failed");
130 runtime_throw("cas64 failed");
131 if(!runtime_cas64(&z64, &x64, 1))
132 runtime_throw("cas64 failed");
133 if(x64 != 42 || z64 != 1)
134 runtime_throw("cas64 failed");
135 if(runtime_atomicload64(&z64) != 1)
136 runtime_throw("load64 failed");
137 runtime_atomicstore64(&z64, (1ull<<40)+1);
138 if(runtime_atomicload64(&z64) != (1ull<<40)+1)
139 runtime_throw("store64 failed");
140 if(runtime_xadd64(&z64, (1ull<<40)+1) != (2ull<<40)+2)
141 runtime_throw("xadd64 failed");
142 if(runtime_atomicload64(&z64) != (2ull<<40)+2)
143 runtime_throw("xadd64 failed");
144 if(runtime_xchg64(&z64, (3ull<<40)+3) != (2ull<<40)+2)
145 runtime_throw("xchg64 failed");
146 if(runtime_atomicload64(&z64) != (3ull<<40)+3)
147 runtime_throw("xchg64 failed");
153 __go_register_gc_roots(&runtime_roots);
159 runtime_fastrand1(void)
174 runtime_cputicks(void)
176 #if defined(__386__) || defined(__x86_64__)
178 asm("rdtsc" : "=a" (low), "=d" (high));
179 return (int64)(((uint64)high << 32) | (uint64)low);
181 // FIXME: implement for other processors.
187 runtime_showframe(String s, bool current)
189 static int32 traceback = -1;
191 if(current && runtime_m()->throwing > 0)
194 traceback = runtime_gotraceback(nil);
195 return traceback > 1 || (__builtin_memchr(s.str, '.', s.len) != nil && __builtin_memcmp(s.str, "runtime.", 7) != 0);
198 static Lock ticksLock;
202 runtime_tickspersecond(void)
204 int64 res, t0, t1, c0, c1;
206 res = (int64)runtime_atomicload64((uint64*)&ticks);
209 runtime_lock(&ticksLock);
212 t0 = runtime_nanotime();
213 c0 = runtime_cputicks();
214 runtime_usleep(100*1000);
215 t1 = runtime_nanotime();
216 c1 = runtime_cputicks();
219 res = (c1-c0)*1000*1000*1000/(t1-t0);
222 runtime_atomicstore64((uint64*)&ticks, res);
224 runtime_unlock(&ticksLock);
228 int64 runtime_pprof_runtime_cyclesPerSecond(void)
229 __asm__ (GOSYM_PREFIX "runtime_pprof.runtime_cyclesPerSecond");
232 runtime_pprof_runtime_cyclesPerSecond(void)
234 return runtime_tickspersecond();
237 // Called to initialize a new m (including the bootstrap m).
238 // Called on the parent thread (main thread in case of bootstrap), can allocate memory.
240 runtime_mpreinit(M *mp)
242 mp->gsignal = runtime_malg(32*1024, &mp->gsignalstack, &mp->gsignalstacksize); // OS X wants >=8K, Linux >=2K
245 // Called to initialize a new m (including the bootstrap m).
246 // Called on the new thread, can not allocate memory.
253 // Initialize signal handling.
255 runtime_signalstack(m->gsignalstack, m->gsignalstacksize);
256 if (sigemptyset(&sigs) != 0)
257 runtime_throw("sigemptyset");
258 sigprocmask(SIG_SETMASK, &sigs, nil);
261 // Called from dropm to undo the effect of an minit.
263 runtime_unminit(void)
265 runtime_signalstack(nil, 0);
270 runtime_signalstack(byte *p, int32 n)
278 st.ss_flags = SS_DISABLE;
279 if(sigaltstack(&st, nil) < 0)