// Copyright 2017 The Crashpad Authors // // 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. #ifndef CRASHPAD_TEST_MAC_EXCEPTION_SWALLOWER_H_ #define CRASHPAD_TEST_MAC_EXCEPTION_SWALLOWER_H_ #include namespace crashpad { namespace test { //! \brief Swallows `EXC_CRASH` and `EXC_CORPSE_NOTIFY` exceptions in test child //! processes. //! //! This class is intended to be used by test code that crashes intentionally. //! //! On macOS, the system’s crash reporter normally saves crash reports for all //! crashes in test code, by virtue of being set as the `EXC_CRASH` or //! `EXC_CORPSE_NOTIFY` handler. This litters the user’s //! `~/Library/Logs/DiagnosticReports` directory and can be time-consuming. //! Reports generated for code that crashes intentionally have no value, and //! many Crashpad tests do crash intentionally. //! //! Instantiate an ExceptionSwallower object in a parent test process (a process //! where `TEST()`, `TEST_F()`, and `TEST_P()` execute) to create an exception //! swallower server running on a dedicated thread. A service mapping for this //! server will be published with the bootstrap server and made available in the //! `CRASHPAD_EXCEPTION_SWALLOWER_SERVICE` environment variable. In a child //! process, call SwallowExceptions() to look up this service and set it as the //! `EXC_CRASH` and `EXC_CORPSE_NOTIFY` handler. When these exceptions are //! raised in the child process, they’ll be handled by the exception swallower //! server, which performs no action but reports that exceptions were //! successfully handled so that the system’s crash reporter, ReportCrash, will //! not be invoked. //! //! At most one ExceptionSwallower may be instantiated in a process at a time. //! If `CRASHPAD_EXCEPTION_SWALLOWER_SERVICE` is already set, ExceptionSwallower //! leaves it in place and takes no additional action. //! //! Crashpad’s ASSERT_DEATH_CRASH(), EXPECT_DEATH_CRASH(), ASSERT_DEATH_CHECK(), //! and EXPECT_DEATH_CHECK() macros make use of this class on macOS, as does the //! Multiprocess test interface. class ExceptionSwallower { public: ExceptionSwallower(); ExceptionSwallower(const ExceptionSwallower&) = delete; ExceptionSwallower& operator=(const ExceptionSwallower&) = delete; ~ExceptionSwallower(); //! \brief In a test child process, arranges to swallow `EXC_CRASH` and //! `EXC_CORPSE_NOTIFY` exceptions. //! //! This must be called in a test child process. It must not be called from a //! parent test process directly. Parent test processes are those that execute //! `TEST()`, `TEST_F()`, and `TEST_P()`. Test child processes execute //! ASSERT_DEATH_CRASH(), EXPECT_DEATH_CRASH(), ASSERT_DEATH_CHECK(), //! EXPECT_DEATH_CHECK(), and Multiprocess::RunChild(). //! //! It is an error to call this in a test child process without having first //! instantiated an ExceptionSwallower object in a parent test project. It is //! also an error to call this in a parent test process. static void SwallowExceptions(); private: class ExceptionSwallowerThread; std::unique_ptr exception_swallower_thread_; }; } // namespace test } // namespace crashpad #endif // CRASHPAD_TEST_MAC_EXCEPTION_SWALLOWER_H_