aboutsummaryrefslogtreecommitdiff
path: root/libgo/runtime
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
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')
-rw-r--r--libgo/runtime/go-caller.c41
-rw-r--r--libgo/runtime/go-callers.c87
-rw-r--r--libgo/runtime/go-nanotime.c4
-rw-r--r--libgo/runtime/go-now.c4
-rw-r--r--libgo/runtime/runtime.h9
-rw-r--r--libgo/runtime/runtime_c.c16
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)