// 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 #include "libcgo.h" #ifndef __has_feature #define __has_feature(x) 0 #endif #if __has_feature(memory_sanitizer) #include #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); }