1 /* go-callers.c -- get callers for Go.
3 Copyright 2012 The Go Authors. All rights reserved.
4 Use of this source code is governed by a BSD-style
5 license that can be found in the LICENSE file. */
14 /* This is set to non-zero when calling backtrace_full. This is used
15 to avoid getting hanging on a recursive lock in dl_iterate_phdr on
16 older versions of glibc when a SIGPROF signal arrives while
17 collecting a backtrace. */
19 uint32 __go_runtime_in_callers
;
21 /* Argument passed to callback function. */
33 /* Whether to skip a particular function name in the traceback. This
34 is mostly to keep the output similar to the gc output for
37 See also similar code in runtime/mprof.go that strips out such
38 functions for block/mutex/memory profiles. */
41 runtime_skipInCallback(const char *function
, struct callers_data
*arg
)
45 /* Skip thunks and recover functions. There is no equivalent to
46 these functions in the gc toolchain. */
48 p
= function
+ __builtin_strlen (function
);
49 while (p
> function
&& p
[-1] >= '0' && p
[-1] <= '9')
51 if (p
- function
> 7 && __builtin_strncmp (p
- 7, "..thunk", 7) == 0)
53 if (p
- function
> 3 && __builtin_strcmp (p
- 3, "..r") == 0)
55 if (p
- function
> 6 && __builtin_strncmp (p
- 6, "..stub", 6) == 0)
58 /* Skip runtime.deferreturn and runtime.sighandler as the gc
59 compiler has no corresponding function. */
60 if (p
- function
== sizeof ("runtime.deferreturn") - 1
61 && __builtin_strcmp (function
, "runtime.deferreturn") == 0)
63 if (p
- function
== sizeof ("runtime.sighandler") - 1
64 && __builtin_strcmp (function
, "runtime.sighandler") == 0)
67 /* Skip the signal handler functions that remain on the stack for us
69 if ((p
- function
== sizeof ("runtime.sigtramp") - 1
70 && __builtin_strcmp (function
, "runtime.sigtramp") == 0)
71 || (p
- function
== sizeof ("runtime.sigtrampgo") - 1
72 && __builtin_strcmp (function
, "runtime.sigtrampgo") == 0))
74 /* Also try to skip the signal handler function. */
76 arg
->saw_sigtramp
= 1;
83 /* Callback function for backtrace_full. Just collect the locations.
84 Return zero to continue, non-zero to stop. */
87 callback (void *data
, uintptr_t pc
, const char *filename
, int lineno
,
90 struct callers_data
*arg
= (struct callers_data
*) data
;
93 /* Skip an unnamed function above sigtramp. It is likely the signal
95 if (arg
->saw_sigtramp
)
97 arg
->saw_sigtramp
= 0;
102 /* Skip split stack functions. */
103 if (function
!= NULL
)
108 if (__builtin_strncmp (p
, "___", 3) == 0)
110 if (__builtin_strncmp (p
, "__morestack_", 12) == 0)
113 else if (filename
!= NULL
)
117 p
= strrchr (filename
, '/');
120 if (__builtin_strncmp (p
, "/morestack.S", 12) == 0)
126 && runtime_skipInCallback (function
, arg
))
135 loc
= &arg
->locbuf
[arg
->index
];
137 /* On the call to backtrace_full the pc value was most likely
138 decremented if there was a normal call, since the pc referred to
139 the instruction where the call returned and not the call itself.
140 This was done so that the line number referred to the call
141 instruction. To make sure the actual pc from the call stack is
142 used, it is incremented here.
144 In the case of a signal, the pc was not decremented by
145 backtrace_full but still incremented here. That doesn't really
146 hurt anything since the line number is right and the pc refers to
147 the same instruction. */
151 /* The libbacktrace library says that these strings might disappear,
152 but with the current implementation they won't. We can't easily
153 allocate memory here, so for now assume that we can save a
154 pointer to the strings. */
155 loc
->filename
= runtime_gostringnocopy ((const byte
*) filename
);
156 loc
->function
= runtime_gostringnocopy ((const byte
*) function
);
158 loc
->lineno
= lineno
;
161 /* There is no point to tracing past certain runtime functions.
162 Stopping the backtrace here can avoid problems on systems that
163 don't provide proper unwind information for makecontext, such as
164 Solaris (http://gcc.gnu.org/PR52583 comment #21). */
165 if (function
!= NULL
)
167 if (__builtin_strcmp (function
, "makecontext") == 0)
169 if (filename
!= NULL
)
173 p
= strrchr (filename
, '/');
176 if (__builtin_strcmp (p
, "/proc.c") == 0)
178 if (__builtin_strcmp (function
, "runtime_mstart") == 0)
181 else if (__builtin_strcmp (p
, "/proc.go") == 0)
183 if (__builtin_strcmp (function
, "runtime.kickoff") == 0
184 || __builtin_strcmp (function
, "runtime.main") == 0)
190 return arg
->index
>= arg
->max
;
193 /* Syminfo callback. */
196 __go_syminfo_fnname_callback (void *data
,
197 uintptr_t pc
__attribute__ ((unused
)),
199 uintptr_t address
__attribute__ ((unused
)),
200 uintptr_t size
__attribute__ ((unused
)))
202 String
* strptr
= (String
*) data
;
205 *strptr
= runtime_gostringnocopy ((const byte
*) symname
);
208 /* Error callback. */
211 error_callback (void *data
__attribute__ ((unused
)),
212 const char *msg
, int errnum
)
216 /* No debug info available. Carry on as best we can. */
220 runtime_printf ("%s errno %d\n", msg
, errnum
);
224 /* Return whether we are already collecting a stack trace. This is
225 called from the signal handler. */
227 bool alreadyInCallers(void)
228 __attribute__ ((no_split_stack
));
229 bool alreadyInCallers(void)
230 __asm__ (GOSYM_PREFIX
"runtime.alreadyInCallers");
235 return runtime_atomicload(&__go_runtime_in_callers
) > 0;
238 /* Gather caller PC's. */
241 runtime_callers (int32 skip
, Location
*locbuf
, int32 m
, bool keep_thunks
)
243 struct callers_data data
;
244 struct backtrace_state
* state
;
247 data
.locbuf
= locbuf
;
248 data
.skip
= skip
+ 1;
251 data
.keep_thunks
= keep_thunks
;
252 data
.saw_sigtramp
= 0;
253 runtime_xadd (&__go_runtime_in_callers
, 1);
254 state
= __go_get_backtrace_state ();
255 backtrace_full (state
, 0, callback
, error_callback
, &data
);
256 runtime_xadd (&__go_runtime_in_callers
, -1);
258 /* For some reason GCC sometimes loses the name of a thunk function
259 at the top of the stack. If we are skipping thunks, skip that
263 && locbuf
[data
.index
- 2].function
.len
== 0
264 && locbuf
[data
.index
- 1].function
.str
!= NULL
265 && __builtin_strcmp ((const char *) locbuf
[data
.index
- 1].function
.str
,
266 "runtime.kickoff") == 0)
268 locbuf
[data
.index
- 2] = locbuf
[data
.index
- 1];
272 /* Try to use backtrace_syminfo to fill in any missing function
273 names. This can happen when tracing through an object which has
274 no debug info; backtrace_syminfo will look at the symbol table to
275 get the name. This should only happen when tracing through code
276 that is not written in Go and is not part of libgo. */
277 for (i
= 0; i
< data
.index
; ++i
)
279 if (locbuf
[i
].function
.len
== 0 && locbuf
[i
].pc
!= 0)
280 backtrace_syminfo (state
, locbuf
[i
].pc
, __go_syminfo_fnname_callback
,
281 error_callback
, &locbuf
[i
].function
);
287 intgo
Callers (intgo
, struct __go_open_array
)
288 __asm__ (GOSYM_PREFIX
"runtime.Callers");
291 Callers (intgo skip
, struct __go_open_array pc
)
300 /* Note that calling mallocgc here assumes that we are not going to
301 store any allocated Go pointers in the slice. */
302 locbuf
= (Location
*) runtime_mallocgc (pc
.__count
* sizeof (Location
),
305 /* In the Go 1 release runtime.Callers has an off-by-one error,
306 which we can not correct because it would break backward
307 compatibility. Normally we would add 1 to SKIP here, but we
308 don't so that we are compatible. */
309 ret
= runtime_callers (skip
, locbuf
, pc
.__count
, false);
311 for (i
= 0; i
< ret
; i
++)
312 ((uintptr
*) pc
.__values
)[i
] = locbuf
[i
].pc
;
317 struct callersRaw_data
324 // Callback function for backtrace_simple. Just collect pc's.
325 // Return zero to continue, non-zero to stop.
327 static int callback_raw (void *data
, uintptr_t pc
)
329 struct callersRaw_data
*arg
= (struct callersRaw_data
*) data
;
331 /* On the call to backtrace_simple the pc value was most likely
332 decremented if there was a normal call, since the pc referred to
333 the instruction where the call returned and not the call itself.
334 This was done so that the line number referred to the call
335 instruction. To make sure the actual pc from the call stack is
336 used, it is incremented here.
338 In the case of a signal, the pc was not decremented by
339 backtrace_full but still incremented here. That doesn't really
340 hurt anything since the line number is right and the pc refers to
341 the same instruction. */
343 arg
->pcbuf
[arg
->index
] = pc
+ 1;
345 return arg
->index
>= arg
->max
;
348 /* runtime_callersRaw is similar to runtime_callers() above, but
349 it returns raw PC values as opposed to file/func/line locations. */
351 runtime_callersRaw (uintptr
*pcbuf
, int32 m
)
353 struct callersRaw_data data
;
354 struct backtrace_state
* state
;
359 runtime_xadd (&__go_runtime_in_callers
, 1);
360 state
= __go_get_backtrace_state ();
361 backtrace_simple (state
, 0, callback_raw
, error_callback
, &data
);
362 runtime_xadd (&__go_runtime_in_callers
, -1);
367 /* runtime_pcInlineCallers returns the inline stack of calls for a PC.
368 This is like runtime_callers, but instead of doing a backtrace,
369 just finds the information for a single PC value. */
371 int32
runtime_pcInlineCallers (uintptr
, Location
*, int32
)
372 __asm__ (GOSYM_PREFIX
"runtime.pcInlineCallers");
375 runtime_pcInlineCallers (uintptr pc
, Location
*locbuf
, int32 m
)
377 struct callers_data data
;
378 struct backtrace_state
*state
;
381 data
.locbuf
= locbuf
;
385 data
.keep_thunks
= false;
386 data
.saw_sigtramp
= 0;
387 runtime_xadd (&__go_runtime_in_callers
, 1);
388 state
= __go_get_backtrace_state ();
389 backtrace_pcinfo (state
, pc
, callback
, error_callback
, &data
);
390 runtime_xadd (&__go_runtime_in_callers
, -1);
392 /* Try to use backtrace_syminfo to fill in missing names. See
394 for (i
= 0; i
< data
.index
; ++i
)
396 if (locbuf
[i
].function
.len
== 0 && locbuf
[i
].pc
!= 0)
397 backtrace_syminfo (state
, locbuf
[i
].pc
, __go_syminfo_fnname_callback
,
398 error_callback
, &locbuf
[i
].function
);