// Copyright 2016 The Crashpad Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include #include #include "base/debug/alias.h" #include "base/logging.h" #include "base/macros.h" #include "client/crashpad_client.h" #include "client/crashpad_info.h" DWORD WINAPI Thread1(LPVOID dummy) { // We set the thread priority up by one as a hacky way to signal to the other // test program that this is the thread we want to dump. SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL); Sleep(INFINITE); return 0; } DWORD WINAPI Thread2(LPVOID dummy) { Sleep(INFINITE); return 0; } DWORD WINAPI Thread3(LPVOID dummy) { HMODULE dll = LoadLibrary(L"loader_lock_dll.dll"); if (!dll) PLOG(ERROR) << "LoadLibrary"; // This call is not expected to return. if (!FreeLibrary(dll)) PLOG(ERROR) << "FreeLibrary"; return 0; } int wmain(int argc, wchar_t* argv[]) { crashpad::CrashpadClient client; if (argc == 2) { if (!client.SetHandlerIPCPipe(argv[1])) { LOG(ERROR) << "SetHandler"; return EXIT_FAILURE; } } else { fprintf(stderr, "Usage: %ls \n", argv[0]); return EXIT_FAILURE; } // Make sure this module has a CrashpadInfo structure. crashpad::CrashpadInfo* crashpad_info = crashpad::CrashpadInfo::GetCrashpadInfo(); base::debug::Alias(crashpad_info); HANDLE threads[3]; threads[0] = CreateThread(nullptr, 0, Thread1, nullptr, 0, nullptr); threads[1] = CreateThread(nullptr, 0, Thread2, nullptr, 0, nullptr); threads[2] = CreateThread(nullptr, 0, Thread3, nullptr, 0, nullptr); // Our whole process is going to hang when the loaded DLL hangs in its // DllMain(), so we can't signal to our parent that we're "ready". So, use a // hokey delay of 1s after we spawn the threads, and hope that we make it to // the FreeLibrary call by then. Sleep(1000); fprintf(stdout, " "); fflush(stdout); WaitForMultipleObjects(ARRAYSIZE(threads), threads, true, INFINITE); return 0; }