werat updated this revision to Diff 406483.
werat added a comment.
Herald added subscribers: JDevlieghere, mstorsjo.

Initialize signal handlers in `PrintStackTraceOnErrorSignal()` only once.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D119009/new/

https://reviews.llvm.org/D119009

Files:
  lldb/source/API/SystemInitializerFull.cpp
  llvm/lib/Support/Unix/Signals.inc
  llvm/lib/Support/Windows/Signals.inc

Index: llvm/lib/Support/Windows/Signals.inc
===================================================================
--- llvm/lib/Support/Windows/Signals.inc
+++ llvm/lib/Support/Windows/Signals.inc
@@ -26,98 +26,99 @@
 #include "llvm/Support/Windows/WindowsSupport.h"
 
 #ifdef __MINGW32__
- #include <imagehlp.h>
+#include <imagehlp.h>
 #else
- #include <crtdbg.h>
- #include <dbghelp.h>
+#include <crtdbg.h>
+#include <dbghelp.h>
 #endif
 #include <psapi.h>
 
 #ifdef _MSC_VER
- #pragma comment(lib, "psapi.lib")
+#pragma comment(lib, "psapi.lib")
 #elif __MINGW32__
- // The version of g++ that comes with MinGW does *not* properly understand
- // the ll format specifier for printf. However, MinGW passes the format
- // specifiers on to the MSVCRT entirely, and the CRT understands the ll
- // specifier. So these warnings are spurious in this case. Since we compile
- // with -Wall, this will generate these warnings which should be ignored. So
- // we will turn off the warnings for this just file. However, MinGW also does
- // not support push and pop for diagnostics, so we have to manually turn it
- // back on at the end of the file.
- #pragma GCC diagnostic ignored "-Wformat"
- #pragma GCC diagnostic ignored "-Wformat-extra-args"
-
- #if !defined(__MINGW64_VERSION_MAJOR)
- // MinGW.org does not have updated support for the 64-bit versions of the
- // DebugHlp APIs. So we will have to load them manually. The structures and
- // method signatures were pulled from DbgHelp.h in the Windows Platform SDK,
- // and adjusted for brevity.
- typedef struct _IMAGEHLP_LINE64 {
-   DWORD    SizeOfStruct;
-   PVOID    Key;
-   DWORD    LineNumber;
-   PCHAR    FileName;
-   DWORD64  Address;
- } IMAGEHLP_LINE64, *PIMAGEHLP_LINE64;
-
- typedef struct _IMAGEHLP_SYMBOL64 {
-   DWORD   SizeOfStruct;
-   DWORD64 Address;
-   DWORD   Size;
-   DWORD   Flags;
-   DWORD   MaxNameLength;
-   CHAR    Name[1];
- } IMAGEHLP_SYMBOL64, *PIMAGEHLP_SYMBOL64;
-
- typedef struct _tagADDRESS64 {
-   DWORD64       Offset;
-   WORD          Segment;
-   ADDRESS_MODE  Mode;
- } ADDRESS64, *LPADDRESS64;
-
- typedef struct _KDHELP64 {
-   DWORD64   Thread;
-   DWORD   ThCallbackStack;
-   DWORD   ThCallbackBStore;
-   DWORD   NextCallback;
-   DWORD   FramePointer;
-   DWORD64   KiCallUserMode;
-   DWORD64   KeUserCallbackDispatcher;
-   DWORD64   SystemRangeStart;
-   DWORD64   KiUserExceptionDispatcher;
-   DWORD64   StackBase;
-   DWORD64   StackLimit;
-   DWORD64   Reserved[5];
- } KDHELP64, *PKDHELP64;
-
- typedef struct _tagSTACKFRAME64 {
-   ADDRESS64   AddrPC;
-   ADDRESS64   AddrReturn;
-   ADDRESS64   AddrFrame;
-   ADDRESS64   AddrStack;
-   ADDRESS64   AddrBStore;
-   PVOID       FuncTableEntry;
-   DWORD64     Params[4];
-   BOOL        Far;
-   BOOL        Virtual;
-   DWORD64     Reserved[3];
-   KDHELP64    KdHelp;
- } STACKFRAME64, *LPSTACKFRAME64;
- #endif // !defined(__MINGW64_VERSION_MAJOR)
+// The version of g++ that comes with MinGW does *not* properly understand
+// the ll format specifier for printf. However, MinGW passes the format
+// specifiers on to the MSVCRT entirely, and the CRT understands the ll
+// specifier. So these warnings are spurious in this case. Since we compile
+// with -Wall, this will generate these warnings which should be ignored. So
+// we will turn off the warnings for this just file. However, MinGW also does
+// not support push and pop for diagnostics, so we have to manually turn it
+// back on at the end of the file.
+#pragma GCC diagnostic ignored "-Wformat"
+#pragma GCC diagnostic ignored "-Wformat-extra-args"
+
+#if !defined(__MINGW64_VERSION_MAJOR)
+// MinGW.org does not have updated support for the 64-bit versions of the
+// DebugHlp APIs. So we will have to load them manually. The structures and
+// method signatures were pulled from DbgHelp.h in the Windows Platform SDK,
+// and adjusted for brevity.
+typedef struct _IMAGEHLP_LINE64 {
+  DWORD SizeOfStruct;
+  PVOID Key;
+  DWORD LineNumber;
+  PCHAR FileName;
+  DWORD64 Address;
+} IMAGEHLP_LINE64, *PIMAGEHLP_LINE64;
+
+typedef struct _IMAGEHLP_SYMBOL64 {
+  DWORD SizeOfStruct;
+  DWORD64 Address;
+  DWORD Size;
+  DWORD Flags;
+  DWORD MaxNameLength;
+  CHAR Name[1];
+} IMAGEHLP_SYMBOL64, *PIMAGEHLP_SYMBOL64;
+
+typedef struct _tagADDRESS64 {
+  DWORD64 Offset;
+  WORD Segment;
+  ADDRESS_MODE Mode;
+} ADDRESS64, *LPADDRESS64;
+
+typedef struct _KDHELP64 {
+  DWORD64 Thread;
+  DWORD ThCallbackStack;
+  DWORD ThCallbackBStore;
+  DWORD NextCallback;
+  DWORD FramePointer;
+  DWORD64 KiCallUserMode;
+  DWORD64 KeUserCallbackDispatcher;
+  DWORD64 SystemRangeStart;
+  DWORD64 KiUserExceptionDispatcher;
+  DWORD64 StackBase;
+  DWORD64 StackLimit;
+  DWORD64 Reserved[5];
+} KDHELP64, *PKDHELP64;
+
+typedef struct _tagSTACKFRAME64 {
+  ADDRESS64 AddrPC;
+  ADDRESS64 AddrReturn;
+  ADDRESS64 AddrFrame;
+  ADDRESS64 AddrStack;
+  ADDRESS64 AddrBStore;
+  PVOID FuncTableEntry;
+  DWORD64 Params[4];
+  BOOL Far;
+  BOOL Virtual;
+  DWORD64 Reserved[3];
+  KDHELP64 KdHelp;
+} STACKFRAME64, *LPSTACKFRAME64;
+#endif // !defined(__MINGW64_VERSION_MAJOR)
 #endif // __MINGW32__
 
-typedef BOOL (__stdcall *PREAD_PROCESS_MEMORY_ROUTINE64)(HANDLE hProcess,
-                      DWORD64 qwBaseAddress, PVOID lpBuffer, DWORD nSize,
-                      LPDWORD lpNumberOfBytesRead);
+typedef BOOL(__stdcall *PREAD_PROCESS_MEMORY_ROUTINE64)(
+    HANDLE hProcess, DWORD64 qwBaseAddress, PVOID lpBuffer, DWORD nSize,
+    LPDWORD lpNumberOfBytesRead);
 
-typedef PVOID (__stdcall *PFUNCTION_TABLE_ACCESS_ROUTINE64)( HANDLE ahProcess,
-                      DWORD64 AddrBase);
+typedef PVOID(__stdcall *PFUNCTION_TABLE_ACCESS_ROUTINE64)(HANDLE ahProcess,
+                                                           DWORD64 AddrBase);
 
-typedef DWORD64 (__stdcall *PGET_MODULE_BASE_ROUTINE64)(HANDLE hProcess,
-                      DWORD64 Address);
+typedef DWORD64(__stdcall *PGET_MODULE_BASE_ROUTINE64)(HANDLE hProcess,
+                                                       DWORD64 Address);
 
-typedef DWORD64 (__stdcall *PTRANSLATE_ADDRESS_ROUTINE64)(HANDLE hProcess,
-                      HANDLE hThread, LPADDRESS64 lpaddr);
+typedef DWORD64(__stdcall *PTRANSLATE_ADDRESS_ROUTINE64)(HANDLE hProcess,
+                                                         HANDLE hThread,
+                                                         LPADDRESS64 lpaddr);
 
 typedef BOOL(WINAPI *fpMiniDumpWriteDump)(HANDLE, DWORD, HANDLE, MINIDUMP_TYPE,
                                           PMINIDUMP_EXCEPTION_INFORMATION,
@@ -125,61 +126,62 @@
                                           PMINIDUMP_CALLBACK_INFORMATION);
 static fpMiniDumpWriteDump fMiniDumpWriteDump;
 
-typedef BOOL (WINAPI *fpStackWalk64)(DWORD, HANDLE, HANDLE, LPSTACKFRAME64,
-                      PVOID, PREAD_PROCESS_MEMORY_ROUTINE64,
-                      PFUNCTION_TABLE_ACCESS_ROUTINE64,
-                      PGET_MODULE_BASE_ROUTINE64,
-                      PTRANSLATE_ADDRESS_ROUTINE64);
+typedef BOOL(WINAPI *fpStackWalk64)(DWORD, HANDLE, HANDLE, LPSTACKFRAME64,
+                                    PVOID, PREAD_PROCESS_MEMORY_ROUTINE64,
+                                    PFUNCTION_TABLE_ACCESS_ROUTINE64,
+                                    PGET_MODULE_BASE_ROUTINE64,
+                                    PTRANSLATE_ADDRESS_ROUTINE64);
 static fpStackWalk64 fStackWalk64;
 
-typedef DWORD64 (WINAPI *fpSymGetModuleBase64)(HANDLE, DWORD64);
+typedef DWORD64(WINAPI *fpSymGetModuleBase64)(HANDLE, DWORD64);
 static fpSymGetModuleBase64 fSymGetModuleBase64;
 
-typedef BOOL (WINAPI *fpSymGetSymFromAddr64)(HANDLE, DWORD64,
-                      PDWORD64, PIMAGEHLP_SYMBOL64);
+typedef BOOL(WINAPI *fpSymGetSymFromAddr64)(HANDLE, DWORD64, PDWORD64,
+                                            PIMAGEHLP_SYMBOL64);
 static fpSymGetSymFromAddr64 fSymGetSymFromAddr64;
 
-typedef BOOL (WINAPI *fpSymGetLineFromAddr64)(HANDLE, DWORD64,
-                      PDWORD, PIMAGEHLP_LINE64);
+typedef BOOL(WINAPI *fpSymGetLineFromAddr64)(HANDLE, DWORD64, PDWORD,
+                                             PIMAGEHLP_LINE64);
 static fpSymGetLineFromAddr64 fSymGetLineFromAddr64;
 
 typedef BOOL(WINAPI *fpSymGetModuleInfo64)(HANDLE hProcess, DWORD64 dwAddr,
                                            PIMAGEHLP_MODULE64 ModuleInfo);
 static fpSymGetModuleInfo64 fSymGetModuleInfo64;
 
-typedef PVOID (WINAPI *fpSymFunctionTableAccess64)(HANDLE, DWORD64);
+typedef PVOID(WINAPI *fpSymFunctionTableAccess64)(HANDLE, DWORD64);
 static fpSymFunctionTableAccess64 fSymFunctionTableAccess64;
 
-typedef DWORD (WINAPI *fpSymSetOptions)(DWORD);
+typedef DWORD(WINAPI *fpSymSetOptions)(DWORD);
 static fpSymSetOptions fSymSetOptions;
 
-typedef BOOL (WINAPI *fpSymInitialize)(HANDLE, PCSTR, BOOL);
+typedef BOOL(WINAPI *fpSymInitialize)(HANDLE, PCSTR, BOOL);
 static fpSymInitialize fSymInitialize;
 
-typedef BOOL (WINAPI *fpEnumerateLoadedModules)(HANDLE,PENUMLOADED_MODULES_CALLBACK64,PVOID);
+typedef BOOL(WINAPI *fpEnumerateLoadedModules)(HANDLE,
+                                               PENUMLOADED_MODULES_CALLBACK64,
+                                               PVOID);
 static fpEnumerateLoadedModules fEnumerateLoadedModules;
 
 static bool load64BitDebugHelp(void) {
   HMODULE hLib = ::LoadLibraryW(L"Dbghelp.dll");
   if (hLib) {
-    fMiniDumpWriteDump = (fpMiniDumpWriteDump)
-                      ::GetProcAddress(hLib, "MiniDumpWriteDump");
-    fStackWalk64 = (fpStackWalk64)
-                      ::GetProcAddress(hLib, "StackWalk64");
-    fSymGetModuleBase64 = (fpSymGetModuleBase64)
-                      ::GetProcAddress(hLib, "SymGetModuleBase64");
-    fSymGetSymFromAddr64 = (fpSymGetSymFromAddr64)
-                      ::GetProcAddress(hLib, "SymGetSymFromAddr64");
-    fSymGetLineFromAddr64 = (fpSymGetLineFromAddr64)
-                      ::GetProcAddress(hLib, "SymGetLineFromAddr64");
-    fSymGetModuleInfo64 = (fpSymGetModuleInfo64)
-                      ::GetProcAddress(hLib, "SymGetModuleInfo64");
-    fSymFunctionTableAccess64 = (fpSymFunctionTableAccess64)
-                     ::GetProcAddress(hLib, "SymFunctionTableAccess64");
+    fMiniDumpWriteDump =
+        (fpMiniDumpWriteDump)::GetProcAddress(hLib, "MiniDumpWriteDump");
+    fStackWalk64 = (fpStackWalk64)::GetProcAddress(hLib, "StackWalk64");
+    fSymGetModuleBase64 =
+        (fpSymGetModuleBase64)::GetProcAddress(hLib, "SymGetModuleBase64");
+    fSymGetSymFromAddr64 =
+        (fpSymGetSymFromAddr64)::GetProcAddress(hLib, "SymGetSymFromAddr64");
+    fSymGetLineFromAddr64 =
+        (fpSymGetLineFromAddr64)::GetProcAddress(hLib, "SymGetLineFromAddr64");
+    fSymGetModuleInfo64 =
+        (fpSymGetModuleInfo64)::GetProcAddress(hLib, "SymGetModuleInfo64");
+    fSymFunctionTableAccess64 = (fpSymFunctionTableAccess64)::GetProcAddress(
+        hLib, "SymFunctionTableAccess64");
     fSymSetOptions = (fpSymSetOptions)::GetProcAddress(hLib, "SymSetOptions");
     fSymInitialize = (fpSymInitialize)::GetProcAddress(hLib, "SymInitialize");
-    fEnumerateLoadedModules = (fpEnumerateLoadedModules)
-      ::GetProcAddress(hLib, "EnumerateLoadedModules64");
+    fEnumerateLoadedModules = (fpEnumerateLoadedModules)::GetProcAddress(
+        hLib, "EnumerateLoadedModules64");
   }
   return fStackWalk64 && fSymInitialize && fSymSetOptions && fMiniDumpWriteDump;
 }
@@ -257,12 +259,11 @@
   intptr_t *Offsets;
   StringSaver *StrPool;
 };
-}
+} // namespace
 
-static BOOL CALLBACK findModuleCallback(PCSTR ModuleName,
-                                        DWORD64 ModuleBase, ULONG ModuleSize,
-                                        void *VoidData) {
-  FindModuleData *Data = (FindModuleData*)VoidData;
+static BOOL CALLBACK findModuleCallback(PCSTR ModuleName, DWORD64 ModuleBase,
+                                        ULONG ModuleSize, void *VoidData) {
+  FindModuleData *Data = (FindModuleData *)VoidData;
   intptr_t Beg = ModuleBase;
   intptr_t End = Beg + ModuleSize;
   for (int I = 0; I < Data->Depth; I++) {
@@ -330,14 +331,14 @@
 // Print the parameters.  Assume there are four.
 #if defined(_M_X64) || defined(_M_ARM64)
     OS << format(" (0x%016llX 0x%016llX 0x%016llX 0x%016llX)",
-            StackFrame.Params[0], StackFrame.Params[1], StackFrame.Params[2],
-            StackFrame.Params[3]);
+                 StackFrame.Params[0], StackFrame.Params[1],
+                 StackFrame.Params[2], StackFrame.Params[3]);
 #elif defined(_M_IX86) || defined(_M_ARM)
     OS << format(" (0x%08lX 0x%08lX 0x%08lX 0x%08lX)",
-            static_cast<DWORD>(StackFrame.Params[0]),
-            static_cast<DWORD>(StackFrame.Params[1]),
-            static_cast<DWORD>(StackFrame.Params[2]),
-            static_cast<DWORD>(StackFrame.Params[3]));
+                 static_cast<DWORD>(StackFrame.Params[0]),
+                 static_cast<DWORD>(StackFrame.Params[1]),
+                 static_cast<DWORD>(StackFrame.Params[2]),
+                 static_cast<DWORD>(StackFrame.Params[3]));
 #endif
     // Verify the PC belongs to a module in this process.
     if (!fSymGetModuleBase64(hProcess, PC)) {
@@ -360,10 +361,10 @@
 
     buffer[511] = 0;
     if (dwDisp > 0)
-      OS << format(", %s() + 0x%llX bytes(s)", (const char*)symbol->Name,
+      OS << format(", %s() + 0x%llX bytes(s)", (const char *)symbol->Name,
                    dwDisp);
     else
-      OS << format(", %s", (const char*)symbol->Name);
+      OS << format(", %s", (const char *)symbol->Name);
 
     // Print the source file and line number information.
     IMAGEHLP_LINE64 line = {};
@@ -448,7 +449,7 @@
 }
 
 // The public API
-bool sys::RemoveFileOnSignal(StringRef Filename, std::string* ErrMsg) {
+bool sys::RemoveFileOnSignal(StringRef Filename, std::string *ErrMsg) {
   RegisterHandler();
 
   if (CleanupExecuted) {
@@ -476,7 +477,7 @@
   std::vector<std::string>::reverse_iterator I =
       find(reverse(*FilesToRemove), Filename);
   if (I != FilesToRemove->rend())
-    FilesToRemove->erase(I.base()-1);
+    FilesToRemove->erase(I.base() - 1);
 
   LeaveCriticalSection(&CriticalSection);
 }
@@ -504,6 +505,11 @@
 /// process, print a stack trace and then exit.
 void sys::PrintStackTraceOnErrorSignal(StringRef Argv0,
                                        bool DisableCrashReporting) {
+  // If ::Argv0 is non-empty, then this function has already been called and
+  // there's no need to initialize the error handling again.
+  if (!::Argv0.empty())
+    return;
+
   ::Argv0 = Argv0;
 
   if (DisableCrashReporting || getenv("LLVM_DISABLE_CRASH_REPORT"))
@@ -513,7 +519,7 @@
   RegisterHandler();
   LeaveCriticalSection(&CriticalSection);
 }
-}
+} // namespace llvm
 
 #if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
 // Provide a prototype for RtlCaptureContext, mingw32 from mingw.org is
@@ -691,8 +697,7 @@
   DWORD DumpType;
   DWORD TypeSize = sizeof(DumpType);
   if (ERROR_SUCCESS != ::RegGetValueW(Key, NULL, L"DumpType", RRF_RT_REG_DWORD,
-                                      NULL, &DumpType,
-                                      &TypeSize))
+                                      NULL, &DumpType, &TypeSize))
     return false;
 
   switch (DumpType) {
@@ -848,14 +853,14 @@
   // If an interrupt function has been set, go and run one it; otherwise,
   // the process dies.
   void (*IF)() = InterruptFunction;
-  InterruptFunction = 0;      // Don't run it on another CTRL-C.
+  InterruptFunction = 0; // Don't run it on another CTRL-C.
 
   if (IF) {
     // Note: if the interrupt function throws an exception, there is nothing
     // to catch it in this thread so it will kill the process.
-    IF();                     // Run it now.
+    IF(); // Run it now.
     LeaveCriticalSection(&CriticalSection);
-    return TRUE;              // Don't kill the process.
+    return TRUE; // Don't kill the process.
   }
 
   // Allow normal processing to take place; i.e., the process dies.
@@ -864,12 +869,12 @@
 }
 
 #if __MINGW32__
- // We turned these warnings off for this file so that MinGW-g++ doesn't
- // complain about the ll format specifiers used.  Now we are turning the
- // warnings back on.  If MinGW starts to support diagnostic stacks, we can
- // replace this with a pop.
- #pragma GCC diagnostic warning "-Wformat"
- #pragma GCC diagnostic warning "-Wformat-extra-args"
+// We turned these warnings off for this file so that MinGW-g++ doesn't
+// complain about the ll format specifiers used.  Now we are turning the
+// warnings back on.  If MinGW starts to support diagnostic stacks, we can
+// replace this with a pop.
+#pragma GCC diagnostic warning "-Wformat"
+#pragma GCC diagnostic warning "-Wformat-extra-args"
 #endif
 
 void sys::unregisterHandlers() {}
Index: llvm/lib/Support/Unix/Signals.inc
===================================================================
--- llvm/lib/Support/Unix/Signals.inc
+++ llvm/lib/Support/Unix/Signals.inc
@@ -637,7 +637,10 @@
 /// process, print a stack trace and then exit.
 void llvm::sys::PrintStackTraceOnErrorSignal(StringRef Argv0,
                                              bool DisableCrashReporting) {
-  ::Argv0 = Argv0;
+  // If ::Argv0 is non-empty, then this function has already been called and
+  // there's no need to initialize the error handling again.
+  if (!::Argv0.empty())
+    return;
 
   AddSignalHandler(PrintStackTraceSignalHandler, nullptr);
 
Index: lldb/source/API/SystemInitializerFull.cpp
===================================================================
--- lldb/source/API/SystemInitializerFull.cpp
+++ lldb/source/API/SystemInitializerFull.cpp
@@ -18,6 +18,7 @@
 #include "lldb/Utility/Reproducer.h"
 #include "lldb/Utility/Timer.h"
 #include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Signals.h"
 #include "llvm/Support/TargetSelect.h"
 
 #pragma clang diagnostic push
@@ -53,6 +54,12 @@
   if (error)
     return error;
 
+  // On Windows certain functions from Signals.h require that the global state
+  // is initialized. For LLDB driver the initialization happens in the `main`
+  // function via the `llvm::InitLLVM` helper, but for LLDB dynamic library
+  // (liblldb) that doesn't happen.
+  llvm::sys::PrintStackTraceOnErrorSignal(/*Argv0=*/{});
+
   // Initialize LLVM and Clang
   llvm::InitializeAllTargets();
   llvm::InitializeAllAsmPrinters();
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to