diff options
author | Ian Lance Taylor <iant@golang.org> | 2020-01-02 15:05:27 -0800 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2020-01-21 23:53:22 -0800 |
commit | 5a8ea165926cb0737ab03bc48c18dc5198ab5305 (patch) | |
tree | 962dc3357c57f019f85658f99e2e753e30201c27 /libgo/runtime/go-callers.c | |
parent | 6ac6529e155c9baa0aaaed7aca06bd38ebda5b43 (diff) | |
download | gcc-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.c | 87 |
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), |