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 /* Argument passed to callback function. */
24 /* Callback function for backtrace_full. Just collect the locations.
25 Return zero to continue, non-zero to stop. */
28 callback (void *data
, uintptr_t pc
, const char *filename
, int lineno
,
31 struct callers_data
*arg
= (struct callers_data
*) data
;
34 /* Skip split stack functions. */
40 if (__builtin_strncmp (p
, "___", 3) == 0)
42 if (__builtin_strncmp (p
, "__morestack_", 12) == 0)
45 else if (filename
!= NULL
)
49 p
= strrchr (filename
, '/');
52 if (__builtin_strncmp (p
, "/morestack.S", 12) == 0)
56 /* Skip thunks and recover functions. There is no equivalent to
57 these functions in the gc toolchain, so returning them here means
58 significantly different results for runtime.Caller(N). */
63 p
= __builtin_strchr (function
, '.');
64 if (p
!= NULL
&& __builtin_strncmp (p
+ 1, "$thunk", 6) == 0)
66 p
= __builtin_strrchr (function
, '$');
67 if (p
!= NULL
&& __builtin_strcmp(p
, "$recover") == 0)
77 loc
= &arg
->locbuf
[arg
->index
];
80 /* The libbacktrace library says that these strings might disappear,
81 but with the current implementation they won't. We can't easily
82 allocate memory here, so for now assume that we can save a
83 pointer to the strings. */
84 loc
->filename
= runtime_gostringnocopy ((const byte
*) filename
);
85 loc
->function
= runtime_gostringnocopy ((const byte
*) function
);
89 return arg
->index
>= arg
->max
;
95 error_callback (void *data
__attribute__ ((unused
)),
96 const char *msg
, int errnum
)
99 runtime_printf ("%s errno %d\n", msg
, errnum
);
103 /* Gather caller PC's. */
106 runtime_callers (int32 skip
, Location
*locbuf
, int32 m
)
108 struct callers_data data
;
110 data
.locbuf
= locbuf
;
111 data
.skip
= skip
+ 1;
114 backtrace_full (__go_get_backtrace_state (), 0, callback
, error_callback
,
119 int Callers (int, struct __go_open_array
)
120 __asm__ (GOSYM_PREFIX
"runtime.Callers");
123 Callers (int skip
, struct __go_open_array pc
)
129 locbuf
= (Location
*) runtime_mal (pc
.__count
* sizeof (Location
));
131 /* In the Go 1 release runtime.Callers has an off-by-one error,
132 which we can not correct because it would break backward
133 compatibility. Normally we would add 1 to SKIP here, but we
134 don't so that we are compatible. */
135 ret
= runtime_callers (skip
, locbuf
, pc
.__count
);
137 for (i
= 0; i
< ret
; i
++)
138 ((uintptr
*) pc
.__values
)[i
] = locbuf
[i
].pc
;