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 runtime_in_callers
;
21 /* Argument passed to callback function. */
31 /* Callback function for backtrace_full. Just collect the locations.
32 Return zero to continue, non-zero to stop. */
35 callback (void *data
, uintptr_t pc
, const char *filename
, int lineno
,
38 struct callers_data
*arg
= (struct callers_data
*) data
;
41 /* Skip split stack functions. */
47 if (__builtin_strncmp (p
, "___", 3) == 0)
49 if (__builtin_strncmp (p
, "__morestack_", 12) == 0)
52 else if (filename
!= NULL
)
56 p
= strrchr (filename
, '/');
59 if (__builtin_strncmp (p
, "/morestack.S", 12) == 0)
63 /* Skip thunks and recover functions. There is no equivalent to
64 these functions in the gc toolchain, so returning them here means
65 significantly different results for runtime.Caller(N). */
70 p
= __builtin_strchr (function
, '.');
71 if (p
!= NULL
&& __builtin_strncmp (p
+ 1, "$thunk", 6) == 0)
73 p
= __builtin_strrchr (function
, '$');
74 if (p
!= NULL
&& __builtin_strcmp(p
, "$recover") == 0)
84 loc
= &arg
->locbuf
[arg
->index
];
87 /* The libbacktrace library says that these strings might disappear,
88 but with the current implementation they won't. We can't easily
89 allocate memory here, so for now assume that we can save a
90 pointer to the strings. */
91 loc
->filename
= runtime_gostringnocopy ((const byte
*) filename
);
92 loc
->function
= runtime_gostringnocopy ((const byte
*) function
);
96 return arg
->index
>= arg
->max
;
102 error_callback (void *data
__attribute__ ((unused
)),
103 const char *msg
, int errnum
)
106 runtime_printf ("%s errno %d\n", msg
, errnum
);
110 /* Gather caller PC's. */
113 runtime_callers (int32 skip
, Location
*locbuf
, int32 m
)
115 struct callers_data data
;
117 data
.locbuf
= locbuf
;
118 data
.skip
= skip
+ 1;
121 runtime_xadd (&runtime_in_callers
, 1);
122 backtrace_full (__go_get_backtrace_state (), 0, callback
, error_callback
,
124 runtime_xadd (&runtime_in_callers
, -1);
128 int Callers (int, struct __go_open_array
)
129 __asm__ (GOSYM_PREFIX
"runtime.Callers");
132 Callers (int skip
, struct __go_open_array pc
)
138 locbuf
= (Location
*) runtime_mal (pc
.__count
* sizeof (Location
));
140 /* In the Go 1 release runtime.Callers has an off-by-one error,
141 which we can not correct because it would break backward
142 compatibility. Normally we would add 1 to SKIP here, but we
143 don't so that we are compatible. */
144 ret
= runtime_callers (skip
, locbuf
, pc
.__count
);
146 for (i
= 0; i
< ret
; i
++)
147 ((uintptr
*) pc
.__values
)[i
] = locbuf
[i
].pc
;