Chromium Code Reviews| Index: handler/win/self_destroying_test_program.cc |
| diff --git a/handler/win/self_destroying_test_program.cc b/handler/win/self_destroying_test_program.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..b24ce697868f897f070aff626015c2e5da75adf0 |
| --- /dev/null |
| +++ b/handler/win/self_destroying_test_program.cc |
| @@ -0,0 +1,94 @@ |
| +// Copyright 2015 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 <malloc.h> |
| +#include <windows.h> |
| +#include <winternl.h> |
| + |
| +#include "base/logging.h" |
| +#include "base/strings/stringprintf.h" |
| +#include "client/crashpad_client.h" |
| +#include "snapshot/win/process_reader_win.h" |
| +#include "tools/tool_support.h" |
| + |
| +namespace crashpad { |
| +namespace { |
| + |
| +// We VirtualFree a region in ourselves (the stack) to confirm that the |
| +// exception reporter captures as much as possible in the minidump and doesn't |
| +// abort. __debugbreak() immediately after doing so because the process is |
| +// clearly in a very broken state at this point. |
| +bool FreeOwnStackAndBreak() { |
| + ProcessReaderWin process_reader; |
| + if (!process_reader.Initialize(GetCurrentProcess(), |
| + ProcessSuspensionState::kRunning)) { |
|
Mark Mentovai
2015/10/21 22:49:29
Align
scottmg
2015/10/21 22:58:08
Done.
|
| + LOG(ERROR) << "ProcessReaderWin Initialize"; |
| + return false; |
| + } |
| + |
| + const std::vector<ProcessReaderWin::Thread> threads = |
| + process_reader.Threads(); |
| + if (threads.empty()) { |
| + LOG(ERROR) << "no threads"; |
| + return false; |
| + } |
| + |
| + // Push the stack up a bit so that hopefully the crash handler can succeed, |
| + // but won't be able to read the base of the stack. |
| + _alloca(16384); |
| + |
| + // We can't succeed at MEM_RELEASEing this memory, but MEM_DECOMMIT is good |
| + // enough to make it inaccessible. |
| + if (!VirtualFree(reinterpret_cast<void*>(threads[0].stack_region_address), |
| + 100, |
| + MEM_DECOMMIT)) { |
| + PLOG(ERROR) << "VirtualFree"; |
| + return false; |
| + } |
| + |
| + // If the VirtualFree() succeeds, we may have already crashed. __debugbreak() |
| + // just to be sure. |
| + __debugbreak(); |
| + |
| + return true; |
| +} |
| + |
| +int SelfDestroyingMain(int argc, char* argv[]) { |
| + if (argc != 2) { |
| + fprintf(stderr, "Usage: %s <server_pipe_name>\n", argv[0]); |
| + return 1; |
|
Mark Mentovai
2015/10/21 22:49:29
<stdlib.h> EXIT_FAILURE, EXIT_SUCCESS
scottmg
2015/10/21 22:58:08
Done.
|
| + } |
| + |
| + CrashpadClient client; |
| + if (!client.SetHandler(argv[1])) { |
| + LOG(ERROR) << "SetHandler"; |
| + return 1; |
| + } |
| + if (!client.UseHandler()) { |
| + LOG(ERROR) << "UseHandler"; |
| + return 1; |
| + } |
| + |
| + if (!FreeOwnStackAndBreak()) |
| + return 1; |
| + |
| + return 0; |
|
Mark Mentovai
2015/10/21 22:49:28
Comment that this is not reached.
scottmg
2015/10/21 22:58:08
Done.
|
| +} |
| + |
| +} // namespace |
| +} // namespace crashpad |
| + |
| +int wmain(int argc, wchar_t* argv[]) { |
| + return crashpad::ToolSupport::Wmain(argc, argv, crashpad::SelfDestroyingMain); |
| +} |