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];
67 // for windows implementation see "os" package
71 s
= runtime_malloc(argc
*sizeof s
[0]);
73 s
[i
] = runtime_gostringnocopy((const byte
*)argv
[i
]);
74 os_Args
.__values
= (void*)s
;
75 os_Args
.__count
= argc
;
76 os_Args
.__capacity
= argc
;
80 runtime_goenvs_unix(void)
85 for(n
=0; argv
[argc
+1+n
] != 0; n
++)
88 s
= runtime_malloc(n
*sizeof s
[0]);
90 s
[i
] = runtime_gostringnocopy(argv
[argc
+1+i
]);
91 syscall_Envs
.__values
= (void*)s
;
92 syscall_Envs
.__count
= n
;
93 syscall_Envs
.__capacity
= n
;
97 runtime_atoi(const byte
*p
)
102 while('0' <= *p
&& *p
<= '9')
103 n
= n
*10 + *p
++ - '0';
107 static struct root_list runtime_roots
=
109 { { &syscall_Envs
, sizeof syscall_Envs
},
110 { &os_Args
, sizeof os_Args
},
122 if(runtime_cas64(&z64
, x64
, 1))
123 runtime_throw("cas64 failed");
125 runtime_throw("cas64 failed");
127 if(!runtime_cas64(&z64
, x64
, 1))
128 runtime_throw("cas64 failed");
129 if(x64
!= 42 || z64
!= 1)
130 runtime_throw("cas64 failed");
131 if(runtime_atomicload64(&z64
) != 1)
132 runtime_throw("load64 failed");
133 runtime_atomicstore64(&z64
, (1ull<<40)+1);
134 if(runtime_atomicload64(&z64
) != (1ull<<40)+1)
135 runtime_throw("store64 failed");
136 if(runtime_xadd64(&z64
, (1ull<<40)+1) != (2ull<<40)+2)
137 runtime_throw("xadd64 failed");
138 if(runtime_atomicload64(&z64
) != (2ull<<40)+2)
139 runtime_throw("xadd64 failed");
140 if(runtime_xchg64(&z64
, (3ull<<40)+3) != (2ull<<40)+2)
141 runtime_throw("xchg64 failed");
142 if(runtime_atomicload64(&z64
) != (3ull<<40)+3)
143 runtime_throw("xchg64 failed");
149 __go_register_gc_roots(&runtime_roots
);
155 runtime_fastrand1(void)
170 runtime_cputicks(void)
172 #if defined(__386__) || defined(__x86_64__)
174 asm("rdtsc" : "=a" (low
), "=d" (high
));
175 return (int64
)(((uint64
)high
<< 32) | (uint64
)low
);
177 // FIXME: implement for other processors.
183 runtime_showframe(String s
, bool current
)
185 static int32 traceback
= -1;
187 if(current
&& runtime_m()->throwing
> 0)
190 traceback
= runtime_gotraceback(nil
);
191 return traceback
> 1 || (__builtin_memchr(s
.str
, '.', s
.len
) != nil
&& __builtin_memcmp(s
.str
, "runtime.", 7) != 0);
194 static Lock ticksLock
;
198 runtime_tickspersecond(void)
200 int64 res
, t0
, t1
, c0
, c1
;
202 res
= (int64
)runtime_atomicload64((uint64
*)&ticks
);
205 runtime_lock(&ticksLock
);
208 t0
= runtime_nanotime();
209 c0
= runtime_cputicks();
210 runtime_usleep(100*1000);
211 t1
= runtime_nanotime();
212 c1
= runtime_cputicks();
215 res
= (c1
-c0
)*1000*1000*1000/(t1
-t0
);
218 runtime_atomicstore64((uint64
*)&ticks
, res
);
220 runtime_unlock(&ticksLock
);
224 int64
runtime_pprof_runtime_cyclesPerSecond(void)
225 __asm__ (GOSYM_PREFIX
"runtime_pprof.runtime_cyclesPerSecond");
228 runtime_pprof_runtime_cyclesPerSecond(void)
230 return runtime_tickspersecond();
233 // Called to initialize a new m (including the bootstrap m).
234 // Called on the parent thread (main thread in case of bootstrap), can allocate memory.
236 runtime_mpreinit(M
*mp
)
238 mp
->gsignal
= runtime_malg(32*1024, &mp
->gsignalstack
, &mp
->gsignalstacksize
); // OS X wants >=8K, Linux >=2K
241 // Called to initialize a new m (including the bootstrap m).
242 // Called on the new thread, can not allocate memory.
249 // Initialize signal handling.
251 runtime_signalstack(m
->gsignalstack
, m
->gsignalstacksize
);
252 if (sigemptyset(&sigs
) != 0)
253 runtime_throw("sigemptyset");
254 pthread_sigmask(SIG_SETMASK
, &sigs
, nil
);
257 // Called from dropm to undo the effect of an minit.
259 runtime_unminit(void)
261 runtime_signalstack(nil
, 0);
266 runtime_signalstack(byte
*p
, int32 n
)
274 st
.ss_flags
= SS_DISABLE
;
275 if(sigaltstack(&st
, nil
) < 0)
279 DebugVars runtime_debug
;
285 {"gctrace", &runtime_debug
.gctrace
},
286 {"schedtrace", &runtime_debug
.schedtrace
},
287 {"scheddetail", &runtime_debug
.scheddetail
},
291 runtime_parsedebugvars(void)
296 p
= runtime_getenv("GODEBUG");
300 for(i
=0; i
<(intgo
)nelem(dbgvar
); i
++) {
301 n
= runtime_findnull((const byte
*)dbgvar
[i
].name
);
302 if(runtime_mcmp(p
, dbgvar
[i
].name
, n
) == 0 && p
[n
] == '=')
303 *dbgvar
[i
].value
= runtime_atoi(p
+n
+1);
305 p
= (const byte
*)runtime_strstr((const char *)p
, ",");
312 // Poor mans 64-bit division.
313 // This is a very special function, do not use it if you are not sure what you are doing.
314 // int64 division is lowered into _divv() call on 386, which does not fit into nosplit functions.
315 // Handles overflow in a time-specific manner.
317 runtime_timediv(int64 v
, int32 div
, int32
*rem
)
321 if(v
>= (int64
)div
*0x7fffffffLL
) {
327 for(bit
= 30; bit
>= 0; bit
--) {
328 if(v
>= ((int64
)div
<<bit
)) {
329 v
= v
- ((int64
)div
<<bit
);
338 // Setting the max stack size doesn't really do anything for gccgo.
340 uintptr runtime_maxstacksize
= 1<<20; // enough until runtime.main sets it for real
342 intgo
runtime_debug_setMaxStack(intgo
)
343 __asm__ (GOSYM_PREFIX
"runtime_debug.setMaxStack");
346 runtime_debug_setMaxStack(intgo in
)
350 out
= runtime_maxstacksize
;
351 runtime_maxstacksize
= in
;