| // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | |
| // for details. All rights reserved. Use of this source code is governed by a | |
| // BSD-style license that can be found in the LICENSE file. | |
| #include "bin/crashpad.h" | |
| #if defined(DART_USE_CRASHPAD) | |
| #include <map> | |
| #include <string> | |
| #include <vector> | |
| #include "crashpad/client/crashpad_client.h" | |
| #include "crashpad/client/crashpad_info.h" | |
| #endif | |
| #include "bin/error_exit.h" | |
| #include "bin/platform.h" | |
| #include "platform/syslog.h" | |
| namespace dart { | |
| namespace bin { | |
| #if defined(DART_USE_CRASHPAD) | |
| #if !defined(DART_HOST_OS_WINDOWS) | |
| #error "Currently we only support Crashpad on Windows" | |
| #endif | |
| void InitializeCrashpadClient() { | |
| // DART_CRASHPAD_HANDLER and DART_CRASHPAD_CRASHES_DIR are set by the | |
| // testing framework. | |
| wchar_t* handler = _wgetenv(L"DART_CRASHPAD_HANDLER"); | |
| wchar_t* crashes_dir = _wgetenv(L"DART_CRASHPAD_CRASHES_DIR"); | |
| if (handler == nullptr || crashes_dir == nullptr || wcslen(handler) == 0 || | |
| wcslen(crashes_dir) == 0) { | |
| return; | |
| } | |
| // Crashpad uses STL so we use it here too even though in general we | |
| // avoid it. | |
| const base::FilePath handler_path{std::wstring(handler)}; | |
| const base::FilePath crashes_dir_path{std::wstring(crashes_dir)}; | |
| const std::string url(""); | |
| std::map<std::string, std::string> annotations; | |
| char* test_name = getenv("DART_TEST_NAME"); | |
| if (test_name != nullptr) { | |
| annotations["dart_test_name"] = test_name; | |
| } | |
| std::vector<std::string> arguments; | |
| crashpad::CrashpadClient client; | |
| // Prevent crashpad_handler from inheriting our standard output and error | |
| // handles. Otherwise we would not be able to close them ourselves making | |
| // tests that rely on that fail. | |
| HANDLE original_stdout = GetStdHandle(STD_OUTPUT_HANDLE); | |
| HANDLE original_stderr = GetStdHandle(STD_ERROR_HANDLE); | |
| SetStdHandle(STD_OUTPUT_HANDLE, INVALID_HANDLE_VALUE); | |
| SetStdHandle(STD_ERROR_HANDLE, INVALID_HANDLE_VALUE); | |
| const bool success = | |
| client.StartHandler(handler_path, crashes_dir_path, crashes_dir_path, url, | |
| annotations, arguments, | |
| /*restartable=*/true, | |
| /*asynchronous_start=*/false); | |
| SetStdHandle(STD_OUTPUT_HANDLE, original_stdout); | |
| SetStdHandle(STD_ERROR_HANDLE, original_stderr); | |
| if (!success) { | |
| Syslog::PrintErr("Failed to start the crash handler!\n"); | |
| Platform::Exit(kErrorExitCode); | |
| } | |
| crashpad::CrashpadInfo::GetCrashpadInfo() | |
| ->set_gather_indirectly_referenced_memory(crashpad::TriState::kEnabled, | |
| /*limit=*/500 * MB); | |
| } | |
| #else | |
| void InitializeCrashpadClient() {} | |
| #endif // DART_USE_CRASHPAD | |
| } // namespace bin | |
| } // namespace dart |