aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/cgo/gcc_traceback.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime/cgo/gcc_traceback.c')
-rw-r--r--src/runtime/cgo/gcc_traceback.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/src/runtime/cgo/gcc_traceback.c b/src/runtime/cgo/gcc_traceback.c
index d86331c583..6e9470c43c 100644
--- a/src/runtime/cgo/gcc_traceback.c
+++ b/src/runtime/cgo/gcc_traceback.c
@@ -7,6 +7,14 @@
#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
@@ -19,6 +27,18 @@ x_cgo_callers(uintptr_t sig, void *info, void *context, void (*cgoTraceback)(str
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
+
(*cgoTraceback)(&arg);
sigtramp(sig, info, context);
}