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 | |
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')
-rw-r--r-- | libgo/runtime/go-caller.c | 41 | ||||
-rw-r--r-- | libgo/runtime/go-callers.c | 87 | ||||
-rw-r--r-- | libgo/runtime/go-nanotime.c | 4 | ||||
-rw-r--r-- | libgo/runtime/go-now.c | 4 | ||||
-rw-r--r-- | libgo/runtime/runtime.h | 9 | ||||
-rw-r--r-- | libgo/runtime/runtime_c.c | 16 |
6 files changed, 122 insertions, 39 deletions
diff --git a/libgo/runtime/go-caller.c b/libgo/runtime/go-caller.c index 5e31f91..a187876 100644 --- a/libgo/runtime/go-caller.c +++ b/libgo/runtime/go-caller.c @@ -27,6 +27,7 @@ struct caller intgo line; intgo index; intgo frames; + bool more; }; /* Collect file/line information for a PC value. If this is called @@ -40,7 +41,19 @@ callback (void *data, uintptr_t pc __attribute__ ((unused)), { struct caller *c = (struct caller *) data; - c->frames++; + /* We want to make sure we return at least one frame. If we already + have at least one frame, see if we should skip this one. */ + if (c->frames > 0 + && function != NULL + && runtime_skipInCallback (function, NULL)) + return 0; + + /* If we already have a frame, don't increment frames if we should + skip that one. */ + if (c->frames == 0 + || c->fn.len == 0 + || !runtime_skipInCallback ((const char *) c->fn.str, NULL)) + c->frames++; /* The libbacktrace library says that these strings might disappear, but with the current implementation they won't. We can't easily @@ -51,7 +64,16 @@ callback (void *data, uintptr_t pc __attribute__ ((unused)), c->line = lineno; if (c->index == 0) - return 1; + { + /* If there are more frames after the indexed one, and we should + skip this one, then skip it. */ + if (c->more + && c->fn.len > 0 + && runtime_skipInCallback((const char *) c->fn.str, NULL)) + return 0; + + return 1; + } if (c->index > 0) --c->index; @@ -129,18 +151,21 @@ __go_get_backtrace_state () return back_state; } -/* Return function/file/line/nframes information for PC. The index parameter - is the entry on the stack of inlined functions; -1 means the last - one, with *nframes set to the count of inlined frames for this PC. */ +/* Return function/file/line/nframes information for PC. The index + parameter is the entry on the stack of inlined functions; -1 means + the last one, with *nframes set to the count of inlined frames for + this PC. If index is not -1, more is whether there are more frames + after this one. */ static _Bool -__go_file_line (uintptr pc, int index, String *fn, String *file, intgo *line, intgo *nframes) +__go_file_line (uintptr pc, int index, bool more, String *fn, String *file, intgo *line, intgo *nframes) { struct caller c; struct backtrace_state *state; runtime_memclr (&c, sizeof c); c.index = index; + c.more = more; c.frames = 0; runtime_xadd (&__go_runtime_in_callers, 1); state = __go_get_backtrace_state (); @@ -223,11 +248,11 @@ Caller (intgo skip) /* Look up the function name, file name, and line number for a PC. */ struct funcfileline_return -runtime_funcfileline (uintptr targetpc, int32 index) +runtime_funcfileline (uintptr targetpc, int32 index, bool more) { struct funcfileline_return ret; - if (!__go_file_line (targetpc, index, &ret.retfn, &ret.retfile, + if (!__go_file_line (targetpc, index, more, &ret.retfn, &ret.retfile, &ret.retline, &ret.retframes)) runtime_memclr (&ret, sizeof ret); return ret; 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), diff --git a/libgo/runtime/go-nanotime.c b/libgo/runtime/go-nanotime.c index d221847..c7adfff 100644 --- a/libgo/runtime/go-nanotime.c +++ b/libgo/runtime/go-nanotime.c @@ -8,11 +8,11 @@ #include "runtime.h" -int64 runtime_nanotime (void) +int64 runtime_nanotime1 (void) __attribute__ ((no_split_stack)); int64 -runtime_nanotime (void) +runtime_nanotime1 (void) { struct timespec ts; diff --git a/libgo/runtime/go-now.c b/libgo/runtime/go-now.c index a45890b..1c02e52 100644 --- a/libgo/runtime/go-now.c +++ b/libgo/runtime/go-now.c @@ -8,7 +8,7 @@ #include "runtime.h" -// Return current time. This is the implementation of time.walltime(). +// Return current time. This is the implementation of time.walltime1(). struct walltime_ret { @@ -16,7 +16,7 @@ struct walltime_ret int32_t nsec; }; -struct walltime_ret now(void) __asm__ (GOSYM_PREFIX "runtime.walltime") +struct walltime_ret now(void) __asm__ (GOSYM_PREFIX "runtime.walltime1") __attribute__ ((no_split_stack)); struct walltime_ret diff --git a/libgo/runtime/runtime.h b/libgo/runtime/runtime.h index 89134c1..f46eaea 100644 --- a/libgo/runtime/runtime.h +++ b/libgo/runtime/runtime.h @@ -283,8 +283,11 @@ void runtime_entersyscallblock() __asm__ (GOSYM_PREFIX "runtime.entersyscallblock"); G* __go_go(uintptr, void*); int32 runtime_callers(int32, Location*, int32, bool keep_callers); -int64 runtime_nanotime(void) // monotonic time - __asm__(GOSYM_PREFIX "runtime.nanotime"); +struct callers_data; +bool runtime_skipInCallback(const char *, struct callers_data *) + __asm__ (GOSYM_PREFIX "runtime.skipInCallback"); +int64 runtime_nanotime1(void) // monotonic time + __asm__(GOSYM_PREFIX "runtime.nanotime1"); void runtime_dopanic(int32) __attribute__ ((noreturn)); void runtime_startpanic(void) __asm__ (GOSYM_PREFIX "runtime.startpanic"); @@ -464,7 +467,7 @@ struct funcfileline_return }; struct funcfileline_return -runtime_funcfileline (uintptr targetpc, int32 index) +runtime_funcfileline (uintptr targetpc, int32 index, bool more) __asm__ (GOSYM_PREFIX "runtime.funcfileline"); /* diff --git a/libgo/runtime/runtime_c.c b/libgo/runtime/runtime_c.c index 7531431..e7951a0 100644 --- a/libgo/runtime/runtime_c.c +++ b/libgo/runtime/runtime_c.c @@ -134,16 +134,22 @@ int32 go_read(int32, void *, int32) int32 go_read(int32 fd, void *p, int32 n) { - return runtime_read(fd, p, n); + ssize_t r = runtime_read(fd, p, n); + if (r < 0) + r = - errno; + return (int32)r; } -int32 go_write(uintptr, void *, int32) - __asm__ (GOSYM_PREFIX "runtime.write"); +int32 go_write1(uintptr, void *, int32) + __asm__ (GOSYM_PREFIX "runtime.write1"); int32 -go_write(uintptr fd, void *p, int32 n) +go_write1(uintptr fd, void *p, int32 n) { - return runtime_write(fd, p, n); + ssize_t r = runtime_write(fd, p, n); + if (r < 0) + r = - errno; + return (int32)r; } int32 go_closefd(int32) |