bool CreateCrashDumpPath() { crashDumpLogs.Debug("Creating crash dump path: %s", CrashDumpPath()); std::error_code createDirError; FS::RawPath::CreatePathTo(FS::Path::Build(CrashDumpPath(), "x"), createDirError); bool success = createDirError == createDirError.default_error_condition(); if (!success) { #ifdef _WIN32 crashDumpLogs.Warn("Failed to create crash dump directory: %s", Win32StrError(GetLastError())); #else crashDumpLogs.Warn("Failed to create crash dump directory: %s", strerror(errno)); #endif } return success; }
intptr_t DynamicLib::InternalLoadSym(Str::StringRef sym, std::string& errorString) { #ifdef _WIN32 intptr_t p = reinterpret_cast<intptr_t>(GetProcAddress(static_cast<HMODULE>(handle), sym.c_str())); if (!p) errorString = Win32StrError(GetLastError()); return p; #else intptr_t p = reinterpret_cast<intptr_t>(dlsym(handle, sym.c_str())); if (!p) errorString = dlerror(); return p; #endif }
void GenRandomBytes(void* dest, size_t size) { #ifdef _WIN32 HCRYPTPROV prov; if (!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) Sys::Error("CryptAcquireContext failed: %s", Win32StrError(GetLastError())); if (!CryptGenRandom(prov, size, (BYTE*)dest)) Sys::Error("CryptGenRandom failed: %s", Win32StrError(GetLastError())); CryptReleaseContext(prov, 0); #elif defined(__native_client__) size_t bytes_written; if (nacl_secure_random(dest, size, &bytes_written) != 0 || bytes_written != size) Sys::Error("nacl_secure_random failed"); #else int fd = open("/dev/urandom", O_RDONLY); if (fd == -1) Sys::Error("Failed to open /dev/urandom: %s", strerror(errno)); if (read(fd, dest, size) != (ssize_t) size) Sys::Error("Failed to read from /dev/urandom: %s", strerror(errno)); close(fd); #endif }
DynamicLib DynamicLib::Open(Str::StringRef filename, std::string& errorString) { #ifdef _WIN32 void* handle = LoadLibraryW(Str::UTF8To16(filename).c_str()); if (!handle) errorString = Win32StrError(GetLastError()); #else // Handle relative paths correctly const char* dlopenFilename = filename.c_str(); std::string relativePath; if (filename.find('/') == std::string::npos) { relativePath = "./" + filename; dlopenFilename = relativePath.c_str(); } void* handle = dlopen(dlopenFilename, RTLD_NOW); if (!handle) errorString = dlerror(); #endif DynamicLib out; out.handle = handle; return out; }
static bool BreakpadInitInternal() { std::string crashDir = CrashDumpPath(); std::string executable = CrashServerPath(); std::string pipeName = GetSingletonSocketPath() + "-crash"; DWORD pid = GetCurrentProcessId(); std::string cmdLine = "\"" + executable + "\" " + pipeName + " \"" + crashDir + " \" " + std::to_string(pid); crashDumpLogs.Debug("Starting crash server with the following command line: %s", cmdLine); STARTUPINFOA startInfo{}; startInfo.cb = sizeof(startInfo); startInfo.dwFlags = 0; PROCESS_INFORMATION procInfo; if (!CreateProcessA(&executable[0], &cmdLine[0], NULL, NULL, FALSE, 0, NULL, NULL, &startInfo, &procInfo)) { crashDumpLogs.Warn("Failed to start crash logging server: %s", Win32StrError(GetLastError())); return false; } CloseHandle(procInfo.hProcess); CloseHandle(procInfo.hThread); std::wstring wPipeName = Str::UTF8To16(pipeName); crashHandler.reset(new google_breakpad::ExceptionHandler( Str::UTF8To16(crashDir), nullptr, nullptr, nullptr, google_breakpad::ExceptionHandler::HANDLER_ALL, MiniDumpNormal, wPipeName.c_str(), nullptr)); return true; }