diff options
Diffstat (limited to 'src/runtime/cgo/gcc_traceback.c')
-rw-r--r-- | src/runtime/cgo/gcc_traceback.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/src/runtime/cgo/gcc_traceback.c b/src/runtime/cgo/gcc_traceback.c new file mode 100644 index 0000000..c6643a1 --- /dev/null +++ b/src/runtime/cgo/gcc_traceback.c @@ -0,0 +1,46 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build darwin || linux + +#include <stdint.h> +#include "libcgo.h" + +#ifndef __has_feature +#define __has_feature(x) 0 +#endif + +#if __has_feature(memory_sanitizer) +#include <sanitizer/msan_interface.h> +#endif + +// Call the user's traceback function and then call sigtramp. +// The runtime signal handler will jump to this code. +// We do it this way so that the user's traceback function will be called +// by a C function with proper unwind info. +void +x_cgo_callers(uintptr_t sig, void *info, void *context, void (*cgoTraceback)(struct cgoTracebackArg*), uintptr_t* cgoCallers, void (*sigtramp)(uintptr_t, void*, void*)) { + struct cgoTracebackArg arg; + + arg.Context = 0; + arg.SigContext = (uintptr_t)(context); + arg.Buf = cgoCallers; + arg.Max = 32; // must match len(runtime.cgoCallers) + +#if __has_feature(memory_sanitizer) + // This function is called directly from the signal handler. + // The arguments are passed in registers, so whether msan + // considers cgoCallers to be initialized depends on whether + // it considers the appropriate register to be initialized. + // That can cause false reports in rare cases. + // Explicitly unpoison the memory to avoid that. + // See issue #47543 for more details. + __msan_unpoison(&arg, sizeof arg); +#endif + + _cgo_tsan_acquire(); + (*cgoTraceback)(&arg); + _cgo_tsan_release(); + sigtramp(sig, info, context); +} |