aboutsummaryrefslogtreecommitdiff
path: root/libgo/runtime/go-callers.c
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2020-01-02 15:05:27 -0800
committerIan Lance Taylor <iant@golang.org>2020-01-21 23:53:22 -0800
commit5a8ea165926cb0737ab03bc48c18dc5198ab5305 (patch)
tree962dc3357c57f019f85658f99e2e753e30201c27 /libgo/runtime/go-callers.c
parent6ac6529e155c9baa0aaaed7aca06bd38ebda5b43 (diff)
downloadgcc-5a8ea165926cb0737ab03bc48c18dc5198ab5305.zip
gcc-5a8ea165926cb0737ab03bc48c18dc5198ab5305.tar.gz
gcc-5a8ea165926cb0737ab03bc48c18dc5198ab5305.tar.bz2
libgo: update to Go1.14beta1
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/214297
Diffstat (limited to 'libgo/runtime/go-callers.c')
-rw-r--r--libgo/runtime/go-callers.c87
1 files changed, 68 insertions, 19 deletions
diff --git a/libgo/runtime/go-callers.c b/libgo/runtime/go-callers.c
index e7d53a3..33956ca 100644
--- a/libgo/runtime/go-callers.c
+++ b/libgo/runtime/go-callers.c
@@ -27,8 +27,59 @@ struct callers_data
int index;
int max;
int keep_thunks;
+ int saw_sigtramp;
};
+/* Whether to skip a particular function name in the traceback. This
+ is mostly to keep the output similar to the gc output for
+ runtime.Caller(N).
+
+ See also similar code in runtime/mprof.go that strips out such
+ functions for block/mutex/memory profiles. */
+
+bool
+runtime_skipInCallback(const char *function, struct callers_data *arg)
+{
+ const char *p;
+
+ /* Skip thunks and recover functions. There is no equivalent to
+ these functions in the gc toolchain. */
+
+ p = function + __builtin_strlen (function);
+ while (p > function && p[-1] >= '0' && p[-1] <= '9')
+ --p;
+ if (p - function > 7 && __builtin_strncmp (p - 7, "..thunk", 7) == 0)
+ return true;
+ if (p - function > 3 && __builtin_strcmp (p - 3, "..r") == 0)
+ return true;
+ if (p - function > 6 && __builtin_strncmp (p - 6, "..stub", 6) == 0)
+ return true;
+
+ /* Skip runtime.deferreturn and runtime.sighandler as the gc
+ compiler has no corresponding function. */
+ if (p - function == sizeof ("runtime.deferreturn") - 1
+ && __builtin_strcmp (function, "runtime.deferreturn") == 0)
+ return true;
+ if (p - function == sizeof ("runtime.sighandler") - 1
+ && __builtin_strcmp (function, "runtime.sighandler") == 0)
+ return true;
+
+ /* Skip the signal handler functions that remain on the stack for us
+ but not for gc. */
+ if ((p - function == sizeof ("runtime.sigtramp") - 1
+ && __builtin_strcmp (function, "runtime.sigtramp") == 0)
+ || (p - function == sizeof ("runtime.sigtrampgo") - 1
+ && __builtin_strcmp (function, "runtime.sigtrampgo") == 0))
+ {
+ /* Also try to skip the signal handler function. */
+ if (arg != NULL)
+ arg->saw_sigtramp = 1;
+ return true;
+ }
+
+ return false;
+}
+
/* Callback function for backtrace_full. Just collect the locations.
Return zero to continue, non-zero to stop. */
@@ -39,6 +90,15 @@ callback (void *data, uintptr_t pc, const char *filename, int lineno,
struct callers_data *arg = (struct callers_data *) data;
Location *loc;
+ /* Skip an unnamed function above sigtramp. It is likely the signal
+ handler function. */
+ if (arg->saw_sigtramp)
+ {
+ arg->saw_sigtramp = 0;
+ if (function == NULL)
+ return 0;
+ }
+
/* Skip split stack functions. */
if (function != NULL)
{
@@ -61,25 +121,10 @@ callback (void *data, uintptr_t pc, const char *filename, int lineno,
return 0;
}
- /* Skip thunks and recover functions. There is no equivalent to
- these functions in the gc toolchain, so returning them here means
- significantly different results for runtime.Caller(N). See also
- similar code in runtime/mprof.go that strips out such functions
- for block/mutex/memory profiles. */
- if (function != NULL && !arg->keep_thunks)
- {
- const char *p;
-
- p = function + __builtin_strlen (function);
- while (p > function && p[-1] >= '0' && p[-1] <= '9')
- --p;
- if (p - function > 7 && __builtin_strncmp (p - 7, "..thunk", 7) == 0)
- return 0;
- if (p - function > 3 && __builtin_strcmp (p - 3, "..r") == 0)
- return 0;
- if (p - function > 6 && __builtin_strncmp (p - 6, "..stub", 6) == 0)
- return 0;
- }
+ if (function != NULL
+ && !arg->keep_thunks
+ && runtime_skipInCallback (function, arg))
+ return 0;
if (arg->skip > 0)
{
@@ -204,6 +249,7 @@ runtime_callers (int32 skip, Location *locbuf, int32 m, bool keep_thunks)
data.index = 0;
data.max = m;
data.keep_thunks = keep_thunks;
+ data.saw_sigtramp = 0;
runtime_xadd (&__go_runtime_in_callers, 1);
state = __go_get_backtrace_state ();
backtrace_full (state, 0, callback, error_callback, &data);
@@ -248,6 +294,9 @@ Callers (intgo skip, struct __go_open_array pc)
int ret;
int i;
+ if (pc.__count == 0)
+ return 0;
+
/* Note that calling mallocgc here assumes that we are not going to
store any allocated Go pointers in the slice. */
locbuf = (Location *) runtime_mallocgc (pc.__count * sizeof (Location),