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)
62 loc
= &arg
->locbuf
[arg
->index
];
65 /* The libbacktrace library says that these strings might disappear,
66 but with the current implementation they won't. We can't easily
67 allocate memory here, so for now assume that we can save a
68 pointer to the strings. */
69 loc
->filename
= runtime_gostringnocopy ((const byte
*) filename
);
70 loc
->function
= runtime_gostringnocopy ((const byte
*) function
);
74 return arg
->index
>= arg
->max
;
80 error_callback (void *data
__attribute__ ((unused
)),
81 const char *msg
, int errnum
)
84 runtime_printf ("%s errno %d\n", msg
, errnum
);
88 /* Gather caller PC's. */
91 runtime_callers (int32 skip
, Location
*locbuf
, int32 m
)
93 struct callers_data data
;
99 backtrace_full (__go_get_backtrace_state (), 0, callback
, error_callback
,
104 int Callers (int, struct __go_open_array
)
105 __asm__ (GOSYM_PREFIX
"runtime.Callers");
108 Callers (int skip
, struct __go_open_array pc
)
114 locbuf
= (Location
*) runtime_mal (pc
.__count
* sizeof (Location
));
116 /* In the Go 1 release runtime.Callers has an off-by-one error,
117 which we can not correct because it would break backward
118 compatibility. Normally we would add 1 to SKIP here, but we
119 don't so that we are compatible. */
120 ret
= runtime_callers (skip
, locbuf
, pc
.__count
);
122 for (i
= 0; i
< ret
; i
++)
123 ((uintptr
*) pc
.__values
)[i
] = locbuf
[i
].pc
;