[llvm] 3df88ec - [Support] Don't print stacktrace if DbgHelp.dll hasn't been loaded yet
Andy Yankovsky via llvm-commits
llvm-commits at lists.llvm.org
Tue Feb 8 08:38:06 PST 2022
Author: Andy Yankovsky
Date: 2022-02-08T16:37:36Z
New Revision: 3df88ec335da7c3ed1625014d6f9b05fd5b54f31
URL: https://github.com/llvm/llvm-project/commit/3df88ec335da7c3ed1625014d6f9b05fd5b54f31
DIFF: https://github.com/llvm/llvm-project/commit/3df88ec335da7c3ed1625014d6f9b05fd5b54f31.diff
LOG: [Support] Don't print stacktrace if DbgHelp.dll hasn't been loaded yet
On Windows certain function from `Signals.h` require that `DbgHelp.dll` is loaded. This typically happens when the main program calls `llvm::InitLLVM`, however in some cases main program doesn't do that (e.g. when the application is using LLDB via `liblldb.dll`). This patch adds a safe guard to prevent crashes. More discussion in
https://reviews.llvm.org/D119009.
Reviewed By: aganea
Differential Revision: https://reviews.llvm.org/D119181
Added:
Modified:
llvm/lib/Support/Windows/Signals.inc
llvm/unittests/Support/ProgramTest.cpp
llvm/utils/unittest/UnitTestMain/TestMain.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Support/Windows/Signals.inc b/llvm/lib/Support/Windows/Signals.inc
index 32186bbe51607..fab3886f46dfc 100644
--- a/llvm/lib/Support/Windows/Signals.inc
+++ b/llvm/lib/Support/Windows/Signals.inc
@@ -159,6 +159,10 @@ static fpSymInitialize fSymInitialize;
typedef BOOL (WINAPI *fpEnumerateLoadedModules)(HANDLE,PENUMLOADED_MODULES_CALLBACK64,PVOID);
static fpEnumerateLoadedModules fEnumerateLoadedModules;
+static bool isDebugHelpInitialized() {
+ return fStackWalk64 && fSymInitialize && fSymSetOptions && fMiniDumpWriteDump;
+}
+
static bool load64BitDebugHelp(void) {
HMODULE hLib = ::LoadLibraryW(L"Dbghelp.dll");
if (hLib) {
@@ -181,7 +185,7 @@ static bool load64BitDebugHelp(void) {
fEnumerateLoadedModules = (fpEnumerateLoadedModules)
::GetProcAddress(hLib, "EnumerateLoadedModules64");
}
- return fStackWalk64 && fSymInitialize && fSymSetOptions && fMiniDumpWriteDump;
+ return isDebugHelpInitialized();
}
using namespace llvm;
@@ -296,6 +300,12 @@ static bool findModulesAndOffsets(void **StackTrace, int Depth,
static void PrintStackTraceForThread(llvm::raw_ostream &OS, HANDLE hProcess,
HANDLE hThread, STACKFRAME64 &StackFrame,
CONTEXT *Context) {
+ // It's possible that DbgHelp.dll hasn't been loaded yet (e.g. if this
+ // function is called before the main program called `llvm::InitLLVM`).
+ // In this case just return, not stacktrace will be printed.
+ if (!isDebugHelpInitialized())
+ return;
+
// Initialize the symbol handler.
fSymSetOptions(SYMOPT_DEFERRED_LOADS | SYMOPT_LOAD_LINES);
fSymInitialize(hProcess, NULL, TRUE);
diff --git a/llvm/unittests/Support/ProgramTest.cpp b/llvm/unittests/Support/ProgramTest.cpp
index fbbcd847e3c7a..fdd0478f70515 100644
--- a/llvm/unittests/Support/ProgramTest.cpp
+++ b/llvm/unittests/Support/ProgramTest.cpp
@@ -12,6 +12,7 @@
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/Signals.h"
#include "gtest/gtest.h"
#include <stdlib.h>
#include <thread>
@@ -426,4 +427,28 @@ TEST_F(ProgramEnvTest, TestLockFile) {
sys::fs::remove(LockedFile);
}
+TEST_F(ProgramEnvTest, TestExecuteWithNoStacktraceHandler) {
+ using namespace llvm::sys;
+
+ if (getenv("LLVM_PROGRAM_TEST_NO_STACKTRACE_HANDLER")) {
+ sys::PrintStackTrace(errs());
+ exit(0);
+ }
+
+ std::string Executable =
+ sys::fs::getMainExecutable(TestMainArgv0, &ProgramTestStringArg1);
+ StringRef argv[] = {
+ Executable,
+ "--gtest_filter=ProgramEnvTest.TestExecuteWithNoStacktraceHandler"};
+
+ addEnvVar("LLVM_PROGRAM_TEST_NO_STACKTRACE_HANDLER=1");
+
+ std::string Error;
+ bool ExecutionFailed;
+ int RetCode = ExecuteAndWait(Executable, argv, getEnviron(), {}, 0, 0, &Error,
+ &ExecutionFailed);
+ EXPECT_FALSE(ExecutionFailed) << Error;
+ ASSERT_EQ(0, RetCode);
+}
+
} // end anonymous namespace
diff --git a/llvm/utils/unittest/UnitTestMain/TestMain.cpp b/llvm/utils/unittest/UnitTestMain/TestMain.cpp
index 1be819fab72e6..35ba72ba3fcd3 100644
--- a/llvm/utils/unittest/UnitTestMain/TestMain.cpp
+++ b/llvm/utils/unittest/UnitTestMain/TestMain.cpp
@@ -10,6 +10,7 @@
#include "llvm/Support/Signals.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include <stdlib.h>
#if defined(_WIN32)
# include <windows.h>
@@ -21,8 +22,12 @@
const char *TestMainArgv0;
int main(int argc, char **argv) {
- llvm::sys::PrintStackTraceOnErrorSignal(argv[0],
- true /* Disable crash reporting */);
+ // Skip setting up signal handlers for tests that need to test things without
+ // them configured.
+ if (!getenv("LLVM_PROGRAM_TEST_NO_STACKTRACE_HANDLER")) {
+ llvm::sys::PrintStackTraceOnErrorSignal(argv[0],
+ true /* Disable crash reporting */);
+ }
// Initialize both gmock and gtest.
testing::InitGoogleMock(&argc, argv);
More information about the llvm-commits
mailing list