]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/rocksdb/port/stack_trace.cc
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / rocksdb / port / stack_trace.cc
index dee8bd9cea69943715417d676ae439ae66fc6485..ef7144947fb178846a1e19d5835e8d9bb6e0cd9b 100644 (file)
@@ -7,7 +7,7 @@
 
 #if defined(ROCKSDB_LITE) ||                                                  \
     !(defined(ROCKSDB_BACKTRACE) || defined(OS_MACOSX)) || defined(CYGWIN) || \
-    defined(OS_FREEBSD) || defined(OS_SOLARIS) || defined(OS_WIN)
+    defined(OS_SOLARIS) || defined(OS_WIN)
 
 // noop
 
@@ -24,13 +24,22 @@ void* SaveStack(int* /*num_frames*/, int /*first_frames_to_skip*/) {
 
 #else
 
+#include <cxxabi.h>
 #include <execinfo.h>
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#include <cxxabi.h>
+
+#if defined(OS_FREEBSD)
+#include <sys/sysctl.h>
+#endif
+#ifdef OS_LINUX
+#include <sys/prctl.h>
+#endif
+
+#include "port/lang.h"
 
 namespace ROCKSDB_NAMESPACE {
 namespace port {
@@ -41,6 +50,7 @@ namespace {
 const char* GetExecutableName() {
   static char name[1024];
 
+#if !defined(OS_FREEBSD)
   char link[1024];
   snprintf(link, sizeof(link), "/proc/%d/exe", getpid());
   auto read = readlink(link, name, sizeof(name) - 1);
@@ -50,6 +60,17 @@ const char* GetExecutableName() {
     name[read] = 0;
     return name;
   }
+#else
+  int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1};
+  size_t namesz = sizeof(name);
+
+  auto ret = sysctl(mib, 4, name, &namesz, nullptr, 0);
+  if (-1 == ret) {
+    return nullptr;
+  } else {
+    return name;
+  }
+#endif
 }
 
 void PrintStackTraceLine(const char* symbol, void* frame) {
@@ -144,6 +165,20 @@ static void StackTraceHandler(int sig) {
   fprintf(stderr, "Received signal %d (%s)\n", sig, strsignal(sig));
   // skip the top three signal handler related frames
   PrintStack(3);
+
+  // Efforts to fix or suppress TSAN warnings "signal-unsafe call inside of
+  // a signal" have failed, so just warn the user about them.
+#ifdef __SANITIZE_THREAD__
+  fprintf(stderr,
+          "==> NOTE: any above warnings about \"signal-unsafe call\" are\n"
+          "==> ignorable, as they are expected when generating a stack\n"
+          "==> trace because of a signal under TSAN. Consider why the\n"
+          "==> signal was generated to begin with, and the stack trace\n"
+          "==> in the TSAN warning can be useful for that. (The stack\n"
+          "==> trace printed by the signal handler is likely obscured\n"
+          "==> by TSAN output.)\n");
+#endif
+
   // re-signal to default handler (so we still get core dump if needed...)
   raise(sig);
 }
@@ -155,6 +190,10 @@ void InstallStackTraceHandler() {
   signal(SIGSEGV, StackTraceHandler);
   signal(SIGBUS, StackTraceHandler);
   signal(SIGABRT, StackTraceHandler);
+  // Allow ouside debugger to attach, even with Yama security restrictions
+#ifdef PR_SET_PTRACER_ANY
+  (void)prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, 0, 0, 0);
+#endif
 }
 
 }  // namespace port