]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: pass signal context to cgo traceback function
authorIan Lance Taylor <iant@golang.org>
Fri, 27 May 2016 17:05:52 +0000 (10:05 -0700)
committerIan Lance Taylor <iant@golang.org>
Tue, 31 May 2016 21:17:40 +0000 (21:17 +0000)
When doing a backtrace from a signal that occurs in C code compiled
without using -fasynchronous-unwind-tables, we have to rely on frame
pointers. In order to do that, the traceback function needs the signal
context to reliably pick up the frame pointer.

Change-Id: I7b45930fced01685c337d108e0f146057928f876
Reviewed-on: https://go-review.googlesource.com/23494
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/runtime/cgo/gcc_traceback.c
src/runtime/testdata/testprogcgo/pprof.go
src/runtime/testdata/testprogcgo/traceback.go
src/runtime/testdata/testprogcgo/tracebackctxt_c.c
src/runtime/traceback.go

index 01f9bb128b7795c141a5018aa2046e1672a0a8ab..667ea4c0cfd70fc00229cd04e24f9cbe8252ab9b 100644 (file)
@@ -9,6 +9,7 @@
 
 struct cgoTracebackArg {
        uintptr_t  Context;
+       uintptr_t  SigContext;
        uintptr_t* Buf;
        uintptr_t  Max;
 };
@@ -22,6 +23,7 @@ x_cgo_callers(uintptr_t sig, void *info, void *context, void (*cgoTraceback)(str
        struct cgoTracebackArg arg;
 
        arg.Context = 0;
+       arg.SigContext = (uintptr_t)(context);
        arg.Buf = cgoCallers;
        arg.Max = 32; // must match len(runtime.cgoCallers)
        (*cgoTraceback)(&arg);
index 04ac4fe92e22b4b040004fc213c106f81221913b..cb30ec5b250d67950fb4391d9ab1d00f20010ed7 100644 (file)
@@ -30,6 +30,7 @@ static int cpuHogCount;
 
 struct cgoTracebackArg {
        uintptr_t  context;
+       uintptr_t  sigContext;
        uintptr_t* buf;
        uintptr_t  max;
 };
index 38cdef537ae2fe17160fed346199a4e22128fa00..e8b0a04556a0f135f22e8ac9597d2fb96930101f 100644 (file)
@@ -30,6 +30,7 @@ static int f1() {
 
 struct cgoTracebackArg {
        uintptr_t  context;
+       uintptr_t  sigContext;
        uintptr_t* buf;
        uintptr_t  max;
 };
index bbac39658e6e8554141fbf76f5cdec328ceb1291..900cada0d3d7fc1f1c541f43f90f970b4cb5d0b4 100644 (file)
@@ -26,6 +26,7 @@ struct cgoContextArg {
 
 struct cgoTracebackArg {
        uintptr_t  context;
+       uintptr_t  sigContext;
        uintptr_t* buf;
        uintptr_t  max;
 };
index 279fb52fc0c4e3044e48b1523cbecd05e7ce6cab..f9d9f21eea133c02abfef2b5f27ab35a7c18e936 100644 (file)
@@ -858,15 +858,17 @@ func isSystemGoroutine(gp *g) bool {
 // pointer to a struct:
 //
 //     struct {
-//             Context uintptr
-//             Buf     *uintptr
-//             Max     uintptr
+//             Context    uintptr
+//             SigContext uintptr
+//             Buf        *uintptr
+//             Max        uintptr
 //     }
 //
 // In C syntax, this struct will be
 //
 //     struct {
 //             uintptr_t  Context;
+//             uintptr_t  SigContext;
 //             uintptr_t* Buf;
 //             uintptr_t  Max;
 //     };
@@ -887,6 +889,13 @@ func isSystemGoroutine(gp *g) bool {
 // result, if possible, the first time this is called for a specific
 // context value.
 //
+// If the traceback function is called from a signal handler on a Unix
+// system, SigContext will be the signal context argument passed to
+// the signal handler (a C ucontext_t* cast to uintptr_t). This may be
+// used to start tracing at the point where the signal occurred. If
+// the traceback function is not called from a signal handler,
+// SigContext will be zero.
+//
 // Buf is where the traceback information should be stored. It should
 // be PC values, such that Buf[0] is the PC of the caller, Buf[1] is
 // the PC of that function's caller, and so on.  Max is the maximum
@@ -973,9 +982,10 @@ var cgoSymbolizer unsafe.Pointer
 
 // cgoTracebackArg is the type passed to cgoTraceback.
 type cgoTracebackArg struct {
-       context uintptr
-       buf     *uintptr
-       max     uintptr
+       context    uintptr
+       sigContext uintptr
+       buf        *uintptr
+       max        uintptr
 }
 
 // cgoContextArg is the type passed to the context function.