summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/Support/Windows
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Support/Windows')
-rw-r--r--contrib/llvm/lib/Support/Windows/COM.inc2
-rw-r--r--contrib/llvm/lib/Support/Windows/DynamicLibrary.inc4
-rw-r--r--contrib/llvm/lib/Support/Windows/Memory.inc4
-rw-r--r--contrib/llvm/lib/Support/Windows/Path.inc107
-rw-r--r--contrib/llvm/lib/Support/Windows/Process.inc11
-rw-r--r--contrib/llvm/lib/Support/Windows/Program.inc25
-rw-r--r--contrib/llvm/lib/Support/Windows/Signals.inc129
-rw-r--r--contrib/llvm/lib/Support/Windows/WindowsSupport.h18
8 files changed, 220 insertions, 80 deletions
diff --git a/contrib/llvm/lib/Support/Windows/COM.inc b/contrib/llvm/lib/Support/Windows/COM.inc
index 0c50d6f..54f3ecf 100644
--- a/contrib/llvm/lib/Support/Windows/COM.inc
+++ b/contrib/llvm/lib/Support/Windows/COM.inc
@@ -1,4 +1,4 @@
-//===- llvm/Support/Windows/COM.inc - Windows COM Implementation *- C++ -*-===//
+//==- llvm/Support/Windows/COM.inc - Windows COM Implementation -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
diff --git a/contrib/llvm/lib/Support/Windows/DynamicLibrary.inc b/contrib/llvm/lib/Support/Windows/DynamicLibrary.inc
index d38f197..17418b0 100644
--- a/contrib/llvm/lib/Support/Windows/DynamicLibrary.inc
+++ b/contrib/llvm/lib/Support/Windows/DynamicLibrary.inc
@@ -76,14 +76,14 @@ DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename,
SmallVector<wchar_t, MAX_PATH> filenameUnicode;
if (std::error_code ec = windows::UTF8ToUTF16(filename, filenameUnicode)) {
SetLastError(ec.value());
- MakeErrMsg(errMsg, std::string(filename) + ": Can't convert to UTF-16: ");
+ MakeErrMsg(errMsg, std::string(filename) + ": Can't convert to UTF-16");
return DynamicLibrary();
}
HMODULE a_handle = LoadLibraryW(filenameUnicode.data());
if (a_handle == 0) {
- MakeErrMsg(errMsg, std::string(filename) + ": Can't open : ");
+ MakeErrMsg(errMsg, std::string(filename) + ": Can't open");
return DynamicLibrary();
}
diff --git a/contrib/llvm/lib/Support/Windows/Memory.inc b/contrib/llvm/lib/Support/Windows/Memory.inc
index 4b2ff2e..7eab9ff 100644
--- a/contrib/llvm/lib/Support/Windows/Memory.inc
+++ b/contrib/llvm/lib/Support/Windows/Memory.inc
@@ -192,14 +192,14 @@ static DWORD getProtection(const void *addr) {
bool Memory::setWritable(MemoryBlock &M, std::string *ErrMsg) {
if (!setRangeWritable(M.Address, M.Size)) {
- return MakeErrMsg(ErrMsg, "Cannot set memory to writeable: ");
+ return MakeErrMsg(ErrMsg, "Cannot set memory to writeable");
}
return true;
}
bool Memory::setExecutable(MemoryBlock &M, std::string *ErrMsg) {
if (!setRangeExecutable(M.Address, M.Size)) {
- return MakeErrMsg(ErrMsg, "Cannot set memory to executable: ");
+ return MakeErrMsg(ErrMsg, "Cannot set memory to executable");
}
return true;
}
diff --git a/contrib/llvm/lib/Support/Windows/Path.inc b/contrib/llvm/lib/Support/Windows/Path.inc
index 72da7c5..4e48412 100644
--- a/contrib/llvm/lib/Support/Windows/Path.inc
+++ b/contrib/llvm/lib/Support/Windows/Path.inc
@@ -182,7 +182,8 @@ std::error_code current_path(SmallVectorImpl<char> &result) {
return UTF16ToUTF8(cur_path.begin(), cur_path.size(), result);
}
-std::error_code create_directory(const Twine &path, bool IgnoreExisting) {
+std::error_code create_directory(const Twine &path, bool IgnoreExisting,
+ perms Perms) {
SmallVector<wchar_t, 128> path_utf16;
if (std::error_code ec = widenPath(path, path_utf16))
@@ -252,17 +253,34 @@ std::error_code rename(const Twine &from, const Twine &to) {
return ec;
std::error_code ec = std::error_code();
+
+ // Retry while we see ERROR_ACCESS_DENIED.
+ // System scanners (eg. indexer) might open the source file when it is written
+ // and closed.
+
for (int i = 0; i < 2000; i++) {
+ // Try ReplaceFile first, as it is able to associate a new data stream with
+ // the destination even if the destination file is currently open.
+ if (::ReplaceFileW(wide_to.begin(), wide_from.begin(), NULL, 0, NULL, NULL))
+ return std::error_code();
+
+ // We get ERROR_FILE_NOT_FOUND if the destination file is missing.
+ // MoveFileEx can handle this case.
+ DWORD ReplaceError = ::GetLastError();
+ ec = mapWindowsError(ReplaceError);
+ if (ReplaceError != ERROR_ACCESS_DENIED &&
+ ReplaceError != ERROR_FILE_NOT_FOUND &&
+ ReplaceError != ERROR_SHARING_VIOLATION)
+ break;
+
if (::MoveFileExW(wide_from.begin(), wide_to.begin(),
MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING))
return std::error_code();
- DWORD LastError = ::GetLastError();
- ec = mapWindowsError(LastError);
- if (LastError != ERROR_ACCESS_DENIED)
- break;
- // Retry MoveFile() at ACCESS_DENIED.
- // System scanners (eg. indexer) might open the source file when
- // It is written and closed.
+
+ DWORD MoveError = ::GetLastError();
+ ec = mapWindowsError(MoveError);
+ if (MoveError != ERROR_ACCESS_DENIED) break;
+
::Sleep(1);
}
@@ -301,6 +319,11 @@ std::error_code access(const Twine &Path, AccessMode Mode) {
return std::error_code();
}
+bool can_execute(const Twine &Path) {
+ return !access(Path, AccessMode::Execute) ||
+ !access(Path + ".exe", AccessMode::Execute);
+}
+
bool equivalent(file_status A, file_status B) {
assert(status_known(A) && status_known(B));
return A.FileIndexHigh == B.FileIndexHigh &&
@@ -325,10 +348,12 @@ std::error_code equivalent(const Twine &A, const Twine &B, bool &result) {
static bool isReservedName(StringRef path) {
// This list of reserved names comes from MSDN, at:
// http://msdn.microsoft.com/en-us/library/aa365247%28v=vs.85%29.aspx
- static const char *sReservedNames[] = { "nul", "con", "prn", "aux",
- "com1", "com2", "com3", "com4", "com5", "com6",
- "com7", "com8", "com9", "lpt1", "lpt2", "lpt3",
- "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9" };
+ static const char *const sReservedNames[] = { "nul", "con", "prn", "aux",
+ "com1", "com2", "com3", "com4",
+ "com5", "com6", "com7", "com8",
+ "com9", "lpt1", "lpt2", "lpt3",
+ "lpt4", "lpt5", "lpt6", "lpt7",
+ "lpt8", "lpt9" };
// First, check to see if this is a device namespace, which always
// starts with \\.\, since device namespaces are not legal file paths.
@@ -643,9 +668,10 @@ std::error_code openFileForRead(const Twine &Name, int &ResultFD) {
if (std::error_code EC = widenPath(Name, PathUTF16))
return EC;
- HANDLE H = ::CreateFileW(PathUTF16.begin(), GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
- OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ HANDLE H =
+ ::CreateFileW(PathUTF16.begin(), GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (H == INVALID_HANDLE_VALUE) {
DWORD LastError = ::GetLastError();
std::error_code EC = mapWindowsError(LastError);
@@ -728,30 +754,31 @@ std::error_code openFileForWrite(const Twine &Name, int &ResultFD,
} // end namespace fs
namespace path {
-
-bool home_directory(SmallVectorImpl<char> &result) {
- wchar_t Path[MAX_PATH];
- if (::SHGetFolderPathW(0, CSIDL_APPDATA | CSIDL_FLAG_CREATE, 0,
- /*SHGFP_TYPE_CURRENT*/0, Path) != S_OK)
+static bool getKnownFolderPath(KNOWNFOLDERID folderId,
+ SmallVectorImpl<char> &result) {
+ wchar_t *path = nullptr;
+ if (::SHGetKnownFolderPath(folderId, KF_FLAG_CREATE, nullptr, &path) != S_OK)
return false;
- if (UTF16ToUTF8(Path, ::wcslen(Path), result))
- return false;
+ bool ok = !UTF16ToUTF8(path, ::wcslen(path), result);
+ ::CoTaskMemFree(path);
+ return ok;
+}
- return true;
+bool getUserCacheDir(SmallVectorImpl<char> &Result) {
+ return getKnownFolderPath(FOLDERID_LocalAppData, Result);
}
-static bool getTempDirEnvVar(const char *Var, SmallVectorImpl<char> &Res) {
- SmallVector<wchar_t, 128> NameUTF16;
- if (windows::UTF8ToUTF16(Var, NameUTF16))
- return false;
+bool home_directory(SmallVectorImpl<char> &result) {
+ return getKnownFolderPath(FOLDERID_Profile, result);
+}
+static bool getTempDirEnvVar(const wchar_t *Var, SmallVectorImpl<char> &Res) {
SmallVector<wchar_t, 1024> Buf;
size_t Size = 1024;
do {
Buf.reserve(Size);
- Size =
- GetEnvironmentVariableW(NameUTF16.data(), Buf.data(), Buf.capacity());
+ Size = GetEnvironmentVariableW(Var, Buf.data(), Buf.capacity());
if (Size == 0)
return false;
@@ -759,14 +786,12 @@ static bool getTempDirEnvVar(const char *Var, SmallVectorImpl<char> &Res) {
} while (Size > Buf.capacity());
Buf.set_size(Size);
- if (windows::UTF16ToUTF8(Buf.data(), Size, Res))
- return false;
- return true;
+ return !windows::UTF16ToUTF8(Buf.data(), Size, Res);
}
static bool getTempDirEnvVar(SmallVectorImpl<char> &Res) {
- const char *EnvironmentVariables[] = {"TMP", "TEMP", "USERPROFILE"};
- for (const char *Env : EnvironmentVariables) {
+ const wchar_t *EnvironmentVariables[] = {L"TMP", L"TEMP", L"USERPROFILE"};
+ for (auto *Env : EnvironmentVariables) {
if (getTempDirEnvVar(Env, Res))
return true;
}
@@ -777,13 +802,19 @@ void system_temp_directory(bool ErasedOnReboot, SmallVectorImpl<char> &Result) {
(void)ErasedOnReboot;
Result.clear();
- // Check whether the temporary directory is specified by an environment
- // variable.
- if (getTempDirEnvVar(Result))
+ // Check whether the temporary directory is specified by an environment var.
+ // This matches GetTempPath logic to some degree. GetTempPath is not used
+ // directly as it cannot handle evn var longer than 130 chars on Windows 7
+ // (fixed on Windows 8).
+ if (getTempDirEnvVar(Result)) {
+ assert(!Result.empty() && "Unexpected empty path");
+ native(Result); // Some Unix-like shells use Unix path separator in $TMP.
+ fs::make_absolute(Result); // Make it absolute if not already.
return;
+ }
// Fall back to a system default.
- const char *DefaultResult = "C:\\TEMP";
+ const char *DefaultResult = "C:\\Temp";
Result.append(DefaultResult, DefaultResult + strlen(DefaultResult));
}
} // end namespace path
diff --git a/contrib/llvm/lib/Support/Windows/Process.inc b/contrib/llvm/lib/Support/Windows/Process.inc
index 8164956..dae35a8 100644
--- a/contrib/llvm/lib/Support/Windows/Process.inc
+++ b/contrib/llvm/lib/Support/Windows/Process.inc
@@ -417,16 +417,23 @@ const char *Process::ResetColor() {
return 0;
}
+// Include GetLastError() in a fatal error message.
+static void ReportLastErrorFatal(const char *Msg) {
+ std::string ErrMsg;
+ MakeErrMsg(&ErrMsg, Msg);
+ report_fatal_error(ErrMsg);
+}
+
unsigned Process::GetRandomNumber() {
HCRYPTPROV HCPC;
if (!::CryptAcquireContextW(&HCPC, NULL, NULL, PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT))
- report_fatal_error("Could not acquire a cryptographic context");
+ ReportLastErrorFatal("Could not acquire a cryptographic context");
ScopedCryptContext CryptoProvider(HCPC);
unsigned Ret;
if (!::CryptGenRandom(CryptoProvider, sizeof(Ret),
reinterpret_cast<BYTE *>(&Ret)))
- report_fatal_error("Could not generate a random number");
+ ReportLastErrorFatal("Could not generate a random number");
return Ret;
}
diff --git a/contrib/llvm/lib/Support/Windows/Program.inc b/contrib/llvm/lib/Support/Windows/Program.inc
index c29d872..d4e14dd 100644
--- a/contrib/llvm/lib/Support/Windows/Program.inc
+++ b/contrib/llvm/lib/Support/Windows/Program.inc
@@ -75,8 +75,15 @@ ErrorOr<std::string> sys::findProgramByName(StringRef Name,
do {
U16Result.reserve(Len);
- Len = ::SearchPathW(Path, c_str(U16Name),
- U16Ext.empty() ? nullptr : c_str(U16Ext),
+ // Lets attach the extension manually. That is needed for files
+ // with a point in name like aaa.bbb. SearchPathW will not add extension
+ // from its argument to such files because it thinks they already had one.
+ SmallVector<wchar_t, MAX_PATH> U16NameExt;
+ if (std::error_code EC =
+ windows::UTF8ToUTF16(Twine(Name + Ext).str(), U16NameExt))
+ return EC;
+
+ Len = ::SearchPathW(Path, c_str(U16NameExt), nullptr,
U16Result.capacity(), U16Result.data(), nullptr);
} while (Len > U16Result.capacity());
@@ -132,7 +139,7 @@ static HANDLE RedirectIO(const StringRef *path, int fd, std::string* ErrMsg) {
FILE_ATTRIBUTE_NORMAL, NULL);
if (h == INVALID_HANDLE_VALUE) {
MakeErrMsg(ErrMsg, fname + ": Can't open file for " +
- (fd ? "input: " : "output: "));
+ (fd ? "input" : "output"));
}
return h;
@@ -251,6 +258,14 @@ static bool Execute(ProcessInfo &PI, StringRef Program, const char **args,
return false;
}
+ // can_execute may succeed by looking at Program + ".exe". CreateProcessW
+ // will implicitly add the .exe if we provide a command line without an
+ // executable path, but since we use an explicit executable, we have to add
+ // ".exe" ourselves.
+ SmallString<64> ProgramStorage;
+ if (!sys::fs::exists(Program))
+ Program = Twine(Program + ".exe").toStringRef(ProgramStorage);
+
// Windows wants a command line, not an array of args, to pass to the new
// process. We have to concatenate them all, while quoting the args that
// have embedded spaces (or are empty).
@@ -416,7 +431,7 @@ ProcessInfo sys::Wait(const ProcessInfo &PI, unsigned SecondsToWait,
if (SecondsToWait) {
if (!TerminateProcess(PI.ProcessHandle, 1)) {
if (ErrMsg)
- MakeErrMsg(ErrMsg, "Failed to terminate timed-out program.");
+ MakeErrMsg(ErrMsg, "Failed to terminate timed-out program");
// -2 indicates a crash or timeout as opposed to failure to execute.
WaitResult.ReturnCode = -2;
@@ -441,7 +456,7 @@ ProcessInfo sys::Wait(const ProcessInfo &PI, unsigned SecondsToWait,
if (!rc) {
SetLastError(err);
if (ErrMsg)
- MakeErrMsg(ErrMsg, "Failed getting status for program.");
+ MakeErrMsg(ErrMsg, "Failed getting status for program");
// -2 indicates a crash or timeout as opposed to failure to execute.
WaitResult.ReturnCode = -2;
diff --git a/contrib/llvm/lib/Support/Windows/Signals.inc b/contrib/llvm/lib/Support/Windows/Signals.inc
index 5c8c239..d109a66 100644
--- a/contrib/llvm/lib/Support/Windows/Signals.inc
+++ b/contrib/llvm/lib/Support/Windows/Signals.inc
@@ -14,7 +14,6 @@
#include <algorithm>
#include <signal.h>
#include <stdio.h>
-#include <vector>
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
@@ -136,6 +135,10 @@ 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);
static fpSymFunctionTableAccess64 fSymFunctionTableAccess64;
@@ -145,6 +148,9 @@ static fpSymSetOptions fSymSetOptions;
typedef BOOL (WINAPI *fpSymInitialize)(HANDLE, PCSTR, BOOL);
static fpSymInitialize fSymInitialize;
+typedef BOOL (WINAPI *fpEnumerateLoadedModules)(HANDLE,PENUMLOADED_MODULES_CALLBACK64,PVOID);
+static fpEnumerateLoadedModules fEnumerateLoadedModules;
+
static bool load64BitDebugHelp(void) {
HMODULE hLib = ::LoadLibraryW(L"Dbghelp.dll");
if (hLib) {
@@ -156,14 +162,20 @@ static bool load64BitDebugHelp(void) {
::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");
}
return fStackWalk64 && fSymInitialize && fSymSetOptions;
}
+using namespace llvm;
+
// Forward declare.
static LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep);
static BOOL WINAPI LLVMConsoleCtrlHandler(DWORD dwCtrlType);
@@ -172,7 +184,6 @@ static BOOL WINAPI LLVMConsoleCtrlHandler(DWORD dwCtrlType);
static void (*InterruptFunction)() = 0;
static std::vector<std::string> *FilesToRemove = NULL;
-static std::vector<std::pair<void(*)(void*), void*> > *CallBacksToRun = 0;
static bool RegisteredUnhandledExceptionFilter = false;
static bool CleanupExecuted = false;
static PTOP_LEVEL_EXCEPTION_FILTER OldFilter = NULL;
@@ -183,23 +194,106 @@ static PTOP_LEVEL_EXCEPTION_FILTER OldFilter = NULL;
static CRITICAL_SECTION CriticalSection;
static bool CriticalSectionInitialized = false;
-static void PrintStackTraceForThread(llvm::raw_ostream &OS, HANDLE hProcess,
- HANDLE hThread, STACKFRAME64 &StackFrame,
- CONTEXT *Context) {
- DWORD machineType;
+enum {
#if defined(_M_X64)
- machineType = IMAGE_FILE_MACHINE_AMD64;
+ NativeMachineType = IMAGE_FILE_MACHINE_AMD64
#else
- machineType = IMAGE_FILE_MACHINE_I386;
+ NativeMachineType = IMAGE_FILE_MACHINE_I386
#endif
+};
+
+static bool printStackTraceWithLLVMSymbolizer(llvm::raw_ostream &OS,
+ HANDLE hProcess, HANDLE hThread,
+ STACKFRAME64 &StackFrameOrig,
+ CONTEXT *ContextOrig) {
+ // StackWalk64 modifies the incoming stack frame and context, so copy them.
+ STACKFRAME64 StackFrame = StackFrameOrig;
+
+ // Copy the register context so that we don't modify it while we unwind. We
+ // could use InitializeContext + CopyContext, but that's only required to get
+ // at AVX registers, which typically aren't needed by StackWalk64. Reduce the
+ // flag set to indicate that there's less data.
+ CONTEXT Context = *ContextOrig;
+ Context.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
+
+ static void *StackTrace[256];
+ size_t Depth = 0;
+ while (fStackWalk64(NativeMachineType, hProcess, hThread, &StackFrame,
+ &Context, 0, fSymFunctionTableAccess64,
+ fSymGetModuleBase64, 0)) {
+ if (StackFrame.AddrFrame.Offset == 0)
+ break;
+ StackTrace[Depth++] = (void *)(uintptr_t)StackFrame.AddrPC.Offset;
+ if (Depth >= array_lengthof(StackTrace))
+ break;
+ }
+
+ return printSymbolizedStackTrace(&StackTrace[0], Depth, OS);
+}
+
+namespace {
+struct FindModuleData {
+ void **StackTrace;
+ int Depth;
+ const char **Modules;
+ intptr_t *Offsets;
+ StringSaver *StrPool;
+};
+}
+
+static BOOL CALLBACK findModuleCallback(WIN32_ELMCB_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++) {
+ if (Data->Modules[I])
+ continue;
+ intptr_t Addr = (intptr_t)Data->StackTrace[I];
+ if (Beg <= Addr && Addr < End) {
+ Data->Modules[I] = Data->StrPool->save(ModuleName);
+ Data->Offsets[I] = Addr - Beg;
+ }
+ }
+ return TRUE;
+}
+
+static bool findModulesAndOffsets(void **StackTrace, int Depth,
+ const char **Modules, intptr_t *Offsets,
+ const char *MainExecutableName,
+ StringSaver &StrPool) {
+ if (!fEnumerateLoadedModules)
+ return false;
+ FindModuleData Data;
+ Data.StackTrace = StackTrace;
+ Data.Depth = Depth;
+ Data.Modules = Modules;
+ Data.Offsets = Offsets;
+ Data.StrPool = &StrPool;
+ fEnumerateLoadedModules(GetCurrentProcess(), findModuleCallback, &Data);
+ return true;
+}
+static void PrintStackTraceForThread(llvm::raw_ostream &OS, HANDLE hProcess,
+ HANDLE hThread, STACKFRAME64 &StackFrame,
+ CONTEXT *Context) {
// Initialize the symbol handler.
fSymSetOptions(SYMOPT_DEFERRED_LOADS | SYMOPT_LOAD_LINES);
fSymInitialize(hProcess, NULL, TRUE);
+ // Try llvm-symbolizer first. llvm-symbolizer knows how to deal with both PDBs
+ // and DWARF, so it should do a good job regardless of what debug info or
+ // linker is in use.
+ if (printStackTraceWithLLVMSymbolizer(OS, hProcess, hThread, StackFrame,
+ Context)) {
+ return;
+ }
+
while (true) {
- if (!fStackWalk64(machineType, hProcess, hThread, &StackFrame, Context, 0,
- fSymFunctionTableAccess64, fSymGetModuleBase64, 0)) {
+ if (!fStackWalk64(NativeMachineType, hProcess, hThread, &StackFrame,
+ Context, 0, fSymFunctionTableAccess64,
+ fSymGetModuleBase64, 0)) {
break;
}
@@ -311,10 +405,7 @@ static void RegisterHandler() {
// If we cannot load up the APIs (which would be unexpected as they should
// exist on every version of Windows we support), we will bail out since
// there would be nothing to report.
- if (!load64BitDebugHelp()) {
- assert(false && "These APIs should always be available");
- return;
- }
+ assert(load64BitDebugHelp() && "These APIs should always be available");
if (RegisteredUnhandledExceptionFilter) {
EnterCriticalSection(&CriticalSection);
@@ -404,7 +495,6 @@ extern "C" VOID WINAPI RtlCaptureContext(PCONTEXT ContextRecord);
#endif
void llvm::sys::PrintStackTrace(raw_ostream &OS) {
-
STACKFRAME64 StackFrame = {};
CONTEXT Context = {};
::RtlCaptureContext(&Context);
@@ -436,8 +526,6 @@ void llvm::sys::SetInterruptFunction(void (*IF)()) {
/// to the process. The handler can have a cookie passed to it to identify
/// what instance of the handler it is.
void llvm::sys::AddSignalHandler(void (*FnPtr)(void *), void *Cookie) {
- if (CallBacksToRun == 0)
- CallBacksToRun = new std::vector<std::pair<void(*)(void*), void*> >();
CallBacksToRun->push_back(std::make_pair(FnPtr, Cookie));
RegisterHandler();
LeaveCriticalSection(&CriticalSection);
@@ -454,17 +542,12 @@ static void Cleanup() {
CleanupExecuted = true;
// FIXME: open files cannot be deleted.
-
if (FilesToRemove != NULL)
while (!FilesToRemove->empty()) {
llvm::sys::fs::remove(FilesToRemove->back());
FilesToRemove->pop_back();
}
-
- if (CallBacksToRun)
- for (auto &I : *CallBacksToRun)
- I.first(I.second);
-
+ llvm::sys::RunSignalHandlers();
LeaveCriticalSection(&CriticalSection);
}
diff --git a/contrib/llvm/lib/Support/Windows/WindowsSupport.h b/contrib/llvm/lib/Support/Windows/WindowsSupport.h
index 5bb0b8d..34d961b 100644
--- a/contrib/llvm/lib/Support/Windows/WindowsSupport.h
+++ b/contrib/llvm/lib/Support/Windows/WindowsSupport.h
@@ -26,12 +26,13 @@
#undef _WIN32_WINNT
#undef _WIN32_IE
-// Require at least Windows XP(5.1) API.
-#define _WIN32_WINNT 0x0501
-#define _WIN32_IE 0x0600 // MinGW at it again.
+// Require at least Windows 7 API.
+#define _WIN32_WINNT 0x0601
+#define _WIN32_IE 0x0800 // MinGW at it again. FIXME: verify if still needed.
#define WIN32_LEAN_AND_MEAN
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Config/config.h" // Get build system configuration settings
@@ -47,13 +48,16 @@ inline bool MakeErrMsg(std::string* ErrMsg, const std::string& prefix) {
if (!ErrMsg)
return true;
char *buffer = NULL;
+ DWORD LastError = GetLastError();
DWORD R = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM,
- NULL, GetLastError(), 0, (LPSTR)&buffer, 1, NULL);
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_MAX_WIDTH_MASK,
+ NULL, LastError, 0, (LPSTR)&buffer, 1, NULL);
if (R)
- *ErrMsg = prefix + buffer;
+ *ErrMsg = prefix + ": " + buffer;
else
- *ErrMsg = prefix + "Unknown error";
+ *ErrMsg = prefix + ": Unknown error";
+ *ErrMsg += " (0x" + llvm::utohexstr(LastError) + ")";
LocalFree(buffer);
return R != 0;
OpenPOWER on IntegriCloud