From 76ef9b5c2b00cb982ad9676b880c3b76ecb15e72 Mon Sep 17 00:00:00 2001 From: Scott Graham Date: Wed, 2 Nov 2016 14:24:21 -0700 Subject: [PATCH 01/10] win: Address failure-to-start-handler case for async startup Second follow up to https://chromium-review.googlesource.com/c/400015/ The ideal would be that if we fail to start the handler, then we don't end up passing through our unhandled exception filter at all. In the case of the non-initial client (i.e. renderers) we can do this by not setting our UnhandledExceptionFilter until after we know we've connected successfully (because those connections are synchronous from its point of view). We also change WaitForNamedPipe in the connection message to block forever, so as long as the precreated pipe exists, they'll wait to connect. After the initial client has passed the server side of that pipe to the handler, the handler has the only handle to it. So, if the handler has disappeared for whatever reason, pipe-connecting clients will fail with FILE_NOT_FOUND, and will not stick around in the connection loop. This means non-initial clients do not need additional logic to avoid getting stuck in our UnhandledExceptionFilter. For the initial client, it would be ideal to avoid passing through our UEF too, but none of the 3 options are great: 1. Block until we find out if we started, and then install the filter. We don't want to do that, because we don't want to wait. 2. Restore the old filter if it turns out we failed to start. We can't do that because Chrome disables ::SetUnhandledExceptionFilter() immediately after StartHandler/SetHandlerIPCPipe returns. 3. Don't install our filter until we've successfully started. We don't want to do that because we'd miss early crashes, negating the benefit of deferred startup. So, we do need to pass through our UnhandledExceptionFilter. I don't want more Win32 API calls during the vulnerable filter function. So, at any point during async startup where there's a failure, set a global atomic that allows the filter function to abort without trying to signal a handler that's known to not exist. One further improvement we might want to look at is unexpected termination of the handler (as opposed to a failure to start) which would still result in a useless Sleep(60s). This isn't new behaviour, but now we have a clear thing to do if we detect the handler is gone. (Also a missing DWORD/size_t cast for the _x64 bots.) R=mark@chromium.org BUG=chromium:567850,chromium:656800 Change-Id: I5be831ca39bd8b2e5c962b9647c8bd469e2be878 Reviewed-on: https://chromium-review.googlesource.com/400985 Reviewed-by: Mark Mentovai --- client/crashpad_client_win.cc | 90 +++++++++++++++++++++++++-- util/win/exception_handler_server.cc | 16 ++++- util/win/registration_protocol_win.cc | 13 ++-- util/win/registration_protocol_win.h | 6 ++ 4 files changed, 112 insertions(+), 13 deletions(-) diff --git a/client/crashpad_client_win.cc b/client/crashpad_client_win.cc index 53f74b5f..20a66d59 100644 --- a/client/crashpad_client_win.cc +++ b/client/crashpad_client_win.cc @@ -22,6 +22,7 @@ #include "base/atomicops.h" #include "base/logging.h" +#include "base/macros.h" #include "base/scoped_generic.h" #include "base/strings/string16.h" #include "base/strings/stringprintf.h" @@ -67,6 +68,19 @@ base::Lock* g_non_crash_dump_lock; // dump. ExceptionInformation g_non_crash_exception_information; +enum class StartupState : int { + kNotReady = 0, // This must be value 0 because it is the initial value of a + // global AtomicWord. + kSucceeded = 1, // The CreateProcess() for the handler succeeded. + kFailed = 2, // The handler failed to start. +}; + +// This is a tri-state of type StartupState. It starts at 0 == kNotReady, and +// when the handler is known to have started successfully, or failed to start +// the value will be updated. The unhandled exception filter will not proceed +// until one of those two cases happens. +base::subtle::AtomicWord g_handler_startup_state; + // A CRITICAL_SECTION initialized with // RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO to force it to be allocated with a // valid .DebugInfo field. The address of this critical section is given to the @@ -74,7 +88,32 @@ ExceptionInformation g_non_crash_exception_information; // list, so this allows the handler to capture all of them. CRITICAL_SECTION g_critical_section_with_debug_info; +void SetHandlerStartupState(StartupState state) { + DCHECK(state == StartupState::kSucceeded || + state == StartupState::kFailed); + base::subtle::Acquire_Store(&g_handler_startup_state, + static_cast(state)); +} + LONG WINAPI UnhandledExceptionHandler(EXCEPTION_POINTERS* exception_pointers) { + // Wait until we know the handler has either succeeded or failed to start. + base::subtle::AtomicWord startup_state; + while ( + (startup_state = base::subtle::Release_Load(&g_handler_startup_state)) == + static_cast(StartupState::kNotReady)) { + Sleep(1); + } + + if (startup_state == static_cast(StartupState::kFailed)) { + // If we know for certain that the handler has failed to start, then abort + // here, rather than trying to signal to a handler that will never arrive, + // and then sleeping unnecessarily. + LOG(ERROR) << "crash server failed to launch, self-terminating"; + TerminateProcess(GetCurrentProcess(), kTerminationCodeCrashNoDump); + return EXCEPTION_CONTINUE_SEARCH; + } + // Otherwise, we know the handler startup has succeeded, and we can continue. + // Tracks whether a thread has already entered UnhandledExceptionHandler. static base::subtle::AtomicWord have_crashed; @@ -226,6 +265,7 @@ struct BackgroundHandlerStartThreadData { const std::string& url, const std::map& annotations, const std::vector& arguments, + const std::wstring& ipc_pipe, ScopedFileHANDLE ipc_pipe_handle) : handler(handler), database(database), @@ -233,6 +273,7 @@ struct BackgroundHandlerStartThreadData { url(url), annotations(annotations), arguments(arguments), + ipc_pipe(ipc_pipe), ipc_pipe_handle(std::move(ipc_pipe_handle)) {} base::FilePath handler; @@ -241,11 +282,33 @@ struct BackgroundHandlerStartThreadData { std::string url; std::map annotations; std::vector arguments; + std::wstring ipc_pipe; ScopedFileHANDLE ipc_pipe_handle; }; +// Ensures that SetHandlerStartupState() is called on scope exit. Assumes +// failure, and on success, SetSuccessful() should be called. +class ScopedCallSetHandlerStartupState { + public: + ScopedCallSetHandlerStartupState() : successful_(false) {} + + ~ScopedCallSetHandlerStartupState() { + SetHandlerStartupState(successful_ ? StartupState::kSucceeded + : StartupState::kFailed); + } + + void SetSuccessful() { successful_ = true; } + + private: + bool successful_; + + DISALLOW_COPY_AND_ASSIGN(ScopedCallSetHandlerStartupState); +}; + bool StartHandlerProcess( std::unique_ptr data) { + ScopedCallSetHandlerStartupState scoped_startup_state_caller; + std::wstring command_line; AppendCommandLineArgument(data->handler.value(), &command_line); for (const std::string& argument : data->arguments) { @@ -393,6 +456,22 @@ bool StartHandlerProcess( rv = CloseHandle(process_info.hProcess); PLOG_IF(WARNING, !rv) << "CloseHandle process"; + // It is important to close our side of the pipe here before confirming that + // we can communicate with the server. By doing so, the only remaining copy of + // the server side of the pipe belongs to the exception handler process we + // just spawned. Otherwise, the pipe will continue to exist indefinitely, so + // the connection loop will not detect that it will never be serviced. + data->ipc_pipe_handle.reset(); + + // Confirm that the server is waiting for connections before continuing. + ClientToServerMessage message = {}; + message.type = ClientToServerMessage::kPing; + ServerToClientMessage response = {}; + if (!SendToCrashHandlerServer(data->ipc_pipe, message, &response)) { + return false; + } + + scoped_startup_state_caller.SetSuccessful(); return true; } @@ -414,10 +493,6 @@ void CommonInProcessInitialization() { &g_critical_section_with_debug_info); g_non_crash_dump_lock = new base::Lock(); - - // In theory we could store the previous handler but it is not clear what - // use we have for it. - SetUnhandledExceptionFilter(&UnhandledExceptionHandler); } } // namespace @@ -456,12 +531,15 @@ bool CrashpadClient::StartHandler( CommonInProcessInitialization(); + SetUnhandledExceptionFilter(&UnhandledExceptionHandler); + auto data = new BackgroundHandlerStartThreadData(handler, database, metrics_dir, url, annotations, arguments, + ipc_pipe_, std::move(ipc_pipe_handle)); if (asynchronous_start) { @@ -478,6 +556,7 @@ bool CrashpadClient::StartHandler( nullptr)); if (!handler_start_thread_.is_valid()) { PLOG(ERROR) << "CreateThread"; + SetHandlerStartupState(StartupState::kFailed); return false; } @@ -524,6 +603,9 @@ bool CrashpadClient::SetHandlerIPCPipe(const std::wstring& ipc_pipe) { return false; } + SetHandlerStartupState(StartupState::kSucceeded); + SetUnhandledExceptionFilter(&UnhandledExceptionHandler); + // The server returns these already duplicated to be valid in this process. g_signal_exception = IntToHandle(response.registration.request_crash_dump_event); diff --git a/util/win/exception_handler_server.cc b/util/win/exception_handler_server.cc index bea1a8cf..70955c82 100644 --- a/util/win/exception_handler_server.cc +++ b/util/win/exception_handler_server.cc @@ -271,8 +271,10 @@ void ExceptionHandlerServer::InitializeWithInheritedDataForInitialClient( // TODO(scottmg): Vista+. Might need to pass through or possibly find an Nt*. size_t bytes = sizeof(wchar_t) * _MAX_PATH + sizeof(FILE_NAME_INFO); std::unique_ptr data(new uint8_t[bytes]); - if (!GetFileInformationByHandleEx( - first_pipe_instance_.get(), FileNameInfo, data.get(), bytes)) { + if (!GetFileInformationByHandleEx(first_pipe_instance_.get(), + FileNameInfo, + data.get(), + static_cast(bytes))) { PLOG(FATAL) << "GetFileInformationByHandleEx"; } FILE_NAME_INFO* file_name_info = @@ -411,6 +413,16 @@ bool ExceptionHandlerServer::ServiceClientConnection( return true; } + case ClientToServerMessage::kPing: { + // No action required, the fact that the message was processed is + // sufficient. + ServerToClientMessage shutdown_response = {}; + LoggingWriteFile(service_context.pipe(), + &shutdown_response, + sizeof(shutdown_response)); + return false; + } + case ClientToServerMessage::kRegister: // Handled below. break; diff --git a/util/win/registration_protocol_win.cc b/util/win/registration_protocol_win.cc index 5db7e41c..17638415 100644 --- a/util/win/registration_protocol_win.cc +++ b/util/win/registration_protocol_win.cc @@ -25,8 +25,8 @@ namespace crashpad { bool SendToCrashHandlerServer(const base::string16& pipe_name, - const crashpad::ClientToServerMessage& message, - crashpad::ServerToClientMessage* response) { + const ClientToServerMessage& message, + ServerToClientMessage* response) { // Retry CreateFile() in a loop. If the handler isn’t actively waiting in // ConnectNamedPipe() on a pipe instance because it’s busy doing something // else, CreateFile() will fail with ERROR_PIPE_BUSY. WaitNamedPipe() waits @@ -42,7 +42,7 @@ bool SendToCrashHandlerServer(const base::string16& pipe_name, // around the same time as its client, something external to this code must be // done to guarantee correct ordering. When the client starts the handler // itself, CrashpadClient::StartHandler() provides this synchronization. - for (int tries = 0;;) { + for (;;) { ScopedFileHANDLE pipe( CreateFile(pipe_name.c_str(), GENERIC_READ | GENERIC_WRITE, @@ -52,13 +52,12 @@ bool SendToCrashHandlerServer(const base::string16& pipe_name, SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION, nullptr)); if (!pipe.is_valid()) { - if (++tries == 5 || GetLastError() != ERROR_PIPE_BUSY) { + if (GetLastError() != ERROR_PIPE_BUSY) { PLOG(ERROR) << "CreateFile"; return false; } - if (!WaitNamedPipe(pipe_name.c_str(), 1000) && - GetLastError() != ERROR_SEM_TIMEOUT) { + if (!WaitNamedPipe(pipe_name.c_str(), NMPWAIT_WAIT_FOREVER)) { PLOG(ERROR) << "WaitNamedPipe"; return false; } @@ -75,7 +74,7 @@ bool SendToCrashHandlerServer(const base::string16& pipe_name, BOOL result = TransactNamedPipe( pipe.get(), // This is [in], but is incorrectly declared non-const. - const_cast(&message), + const_cast(&message), sizeof(message), response, sizeof(*response), diff --git a/util/win/registration_protocol_win.h b/util/win/registration_protocol_win.h index 2c552c87..12209835 100644 --- a/util/win/registration_protocol_win.h +++ b/util/win/registration_protocol_win.h @@ -82,8 +82,14 @@ struct ClientToServerMessage { enum Type : uint32_t { //! \brief For RegistrationRequest. kRegister, + //! \brief For ShutdownRequest. kShutdown, + + //! \brief An empty message sent by the initial client in asynchronous mode. + //! No data is required, this just confirms that the server is ready to + //! accept client registrations. + kPing, } type; union { From 55ba6b67801b8a38276f5473a725f390835b3ce9 Mon Sep 17 00:00:00 2001 From: Scott Graham Date: Wed, 2 Nov 2016 15:34:53 -0700 Subject: [PATCH 02/10] break; after handling --initial-client-data on command line Not surprisingly, "0x278,0x27c,0x280,0x274,0x288,0x978a70,0x978a80,0x978a90" is not a valid directory to store metrics in. Fortunately --metrics was processed before --initial-client-data in a local build, otherwise this could have lurked for a long time. :( R=mark@chromium.org BUG=655788,656800 Change-Id: I3ac3d1b487f55ddf0172bac51f8d9efc411c3329 Reviewed-on: https://chromium-review.googlesource.com/406938 Reviewed-by: Mark Mentovai --- handler/handler_main.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/handler/handler_main.cc b/handler/handler_main.cc index 7ca5ac78..29c5ddc1 100644 --- a/handler/handler_main.cc +++ b/handler/handler_main.cc @@ -267,6 +267,7 @@ int HandlerMain(int argc, char* argv[]) { me, "failed to parse --initial-client-data"); return EXIT_FAILURE; } + break; } #endif // OS_MACOSX case kOptionMetrics: { From bb7d249d65a1edd965499b77ad5da621eddffad4 Mon Sep 17 00:00:00 2001 From: Mark Mentovai Date: Wed, 2 Nov 2016 19:18:20 -0400 Subject: [PATCH 03/10] Partially port the crashpad_client library to Linux/Android MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This defines the global (per-module) CrashpadInfo structure properly on Linux/Android, located via the “crashpad_info” section name. Per the ELF specification, section names with a leading dot are reserved for the system. Reading that, I realized that the same is true of Mach-O sections with leading underscores, so this renames the section as used on Mach-O from __DATA,__crashpad_info to __DATA,crashpad_info. This change is sufficient to successfully build crashpad_client as a static library on Linux/Android, but the library is incomplete. There’s no platform-specific database implementation, no CaptureContext() or CRASHPAD_SIMULATE_CRASH() implementation, and most notably, no CrashpadClient implementation. BUG=crashpad:30 Change-Id: I29df7b0f8ee1c79bf8a19502812f59d4b1577b85 Reviewed-on: https://chromium-review.googlesource.com/406427 Reviewed-by: Robert Sesek --- client/crashpad_info.cc | 50 ++++++++++++------- snapshot/mac/mach_o_image_reader.cc | 2 +- snapshot/mac/mach_o_image_reader.h | 5 +- .../mac/process_types/crashpad_info.proctype | 2 +- snapshot/module_snapshot.h | 4 +- 5 files changed, 39 insertions(+), 24 deletions(-) diff --git a/client/crashpad_info.cc b/client/crashpad_info.cc index 9ad41a67..e8a6a9ee 100644 --- a/client/crashpad_info.cc +++ b/client/crashpad_info.cc @@ -59,33 +59,47 @@ union Compile_Assert { // This may result in a static module initializer in debug-mode builds, but // because it’s POD, no code should need to run to initialize this under // release-mode optimization. -#if defined(OS_MACOSX) +#if defined(OS_POSIX) +__attribute__(( + + // Put the structure in a well-known section name where it can be easily + // found without having to consult the symbol table. +#if defined(OS_MACOSX) + section(SEG_DATA ",crashpad_info"), +#elif defined(OS_LINUX) || defined(OS_ANDROID) + section("crashpad_info"), +#else // !defined(OS_MACOSX) && !defined(OS_LINUX) && !defined(OS_ANDROID) +#error Port +#endif // !defined(OS_MACOSX) && !defined(OS_LINUX) && !defined(OS_ANDROID) -// Put the structure in __DATA,__crashpad_info where it can be easily found -// without having to consult the symbol table. The “used” attribute prevents it -// from being dead-stripped. -__attribute__((section(SEG_DATA ",__crashpad_info"), - used, - visibility("hidden") #if __has_feature(address_sanitizer) -// AddressSanitizer would add a trailing red zone of at least 32 bytes, which -// would be reflected in the size of the custom section. This confuses -// MachOImageReader::GetCrashpadInfo(), which finds that the section’s size -// disagrees with the structure’s size_ field. By specifying an alignment -// greater than the red zone size, the red zone will be suppressed. - , - aligned(64) -#endif - )) CrashpadInfo g_crashpad_info; + // AddressSanitizer would add a trailing red zone of at least 32 bytes, + // which would be reflected in the size of the custom section. This confuses + // MachOImageReader::GetCrashpadInfo(), which finds that the section’s size + // disagrees with the structure’s size_ field. By specifying an alignment + // greater than the red zone size, the red zone will be suppressed. + aligned(64), +#endif // __has_feature(address_sanitizer) + + // The “used” attribute prevents the structure from being dead-stripped. + used, + + // There’s no need to expose this as a public symbol from the symbol table. + // All accesses from the outside can locate the well-known section name. + visibility("hidden"))) #elif defined(OS_WIN) // Put the struct in a section name CPADinfo where it can be found without the // symbol table. #pragma section("CPADinfo", read, write) -__declspec(allocate("CPADinfo")) CrashpadInfo g_crashpad_info; +__declspec(allocate("CPADinfo")) -#endif +#else // !defined(OS_POSIX) && !defined(OS_WIN) +#error Port +#endif // !defined(OS_POSIX) && !defined(OS_WIN) + +CrashpadInfo g_crashpad_info; // static CrashpadInfo* CrashpadInfo::GetCrashpadInfo() { diff --git a/snapshot/mac/mach_o_image_reader.cc b/snapshot/mac/mach_o_image_reader.cc index 3e944f73..d0b7a087 100644 --- a/snapshot/mac/mach_o_image_reader.cc +++ b/snapshot/mac/mach_o_image_reader.cc @@ -477,7 +477,7 @@ bool MachOImageReader::GetCrashpadInfo( mach_vm_address_t crashpad_info_address; const process_types::section* crashpad_info_section = - GetSectionByName(SEG_DATA, "__crashpad_info", &crashpad_info_address); + GetSectionByName(SEG_DATA, "crashpad_info", &crashpad_info_address); if (!crashpad_info_section) { return false; } diff --git a/snapshot/mac/mach_o_image_reader.h b/snapshot/mac/mach_o_image_reader.h index d211ce9c..40eddc22 100644 --- a/snapshot/mac/mach_o_image_reader.h +++ b/snapshot/mac/mach_o_image_reader.h @@ -270,8 +270,9 @@ class MachOImageReader { //! \brief Obtains the module’s CrashpadInfo structure. //! //! \return `true` on success, `false` on failure. If the module does not have - //! a `__crashpad_info` section, this will return `false` without logging - //! any messages. Other failures will result in messages being logged. + //! a `__DATA,crashpad_info` section, this will return `false` without + //! logging any messages. Other failures will result in messages being + //! logged. bool GetCrashpadInfo(process_types::CrashpadInfo* crashpad_info) const; private: diff --git a/snapshot/mac/process_types/crashpad_info.proctype b/snapshot/mac/process_types/crashpad_info.proctype index 7bae0872..713bb09d 100644 --- a/snapshot/mac/process_types/crashpad_info.proctype +++ b/snapshot/mac/process_types/crashpad_info.proctype @@ -21,7 +21,7 @@ // snapshot/mac/process_types.cc to produce process type struct definitions and // accessors. -// Client Mach-O images will contain a __DATA,__crashpad_info section formatted +// Client Mach-O images will contain a __DATA,crashpad_info section formatted // according to this structure. PROCESS_TYPE_STRUCT_BEGIN(CrashpadInfo) PROCESS_TYPE_STRUCT_MEMBER(uint32_t, signature) diff --git a/snapshot/module_snapshot.h b/snapshot/module_snapshot.h index 870eb205..5989e4ba 100644 --- a/snapshot/module_snapshot.h +++ b/snapshot/module_snapshot.h @@ -165,7 +165,7 @@ class ModuleSnapshot { //! contain multiple annotations, so they are returned in a vector. //! //! For Mac OS X snapshots, these annotations are found by interpreting the - //! module’s `__DATA, __crash_info` section as `crashreporter_annotations_t`. + //! module’s `__DATA,__crash_info` section as `crashreporter_annotations_t`. //! System libraries using the crash reporter client interface may reference //! annotations in this structure. Additional annotations messages may be //! found in other locations, which may be module-specific. The dynamic linker @@ -184,7 +184,7 @@ class ModuleSnapshot { //! keys.” //! //! For Mac OS X snapshots, these annotations are found by interpreting the - //! `__DATA, __crashpad_info` section as `CrashpadInfo`. Clients can use the + //! `__DATA,crashpad_info` section as `CrashpadInfo`. Clients can use the //! Crashpad client interface to store annotations in this structure. Most //! annotations under the client’s direct control will be retrievable by this //! method. For clients such as Chrome, this includes the process type. From 375082098deb5efd7c10f108c99fbc74860c6f72 Mon Sep 17 00:00:00 2001 From: Mark Mentovai Date: Wed, 2 Nov 2016 20:06:39 -0400 Subject: [PATCH 04/10] mac: Fix tests on 10.12.1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit crashpad_snapshot_test MachOImageAnnotationsReader.CrashDyld was failing on 10.12.1. In 10.12, dyld’s intentional crashes come through abort_with_payload(). In 10.12.1, it appears that the task port sent along with abort_with_payload() crashes is now a corpse port, which has a different port name than the task port that it originated from. https://openradar.appspot.com/29079442 TEST=crashpad_snapshot_test MachOImageAnnotationsReader.CrashDyld BUG=crashpad:137 Change-Id: I43f89c0f595dd5614fc910fa1f19f21ddf0a7c4d Reviewed-on: https://chromium-review.googlesource.com/407087 Reviewed-by: Robert Sesek --- .../mac/mach_o_image_annotations_reader_test.cc | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/snapshot/mac/mach_o_image_annotations_reader_test.cc b/snapshot/mac/mach_o_image_annotations_reader_test.cc index 5d5908d9..d25ba438 100644 --- a/snapshot/mac/mach_o_image_annotations_reader_test.cc +++ b/snapshot/mac/mach_o_image_annotations_reader_test.cc @@ -117,7 +117,18 @@ class TestMachOImageAnnotationsReader final bool* destroy_complex_request) override { *destroy_complex_request = true; - EXPECT_EQ(ChildTask(), task); + // In 10.12, dyld fatal errors as tested by test_type_ = kCrashDyld are via + // abort_with_payload(). In 10.12.1, the task port delivered in an exception + // message for this termination type is a corpse, even when the exception is + // EXC_CRASH and not EXC_CORPSE_NOTIFY. The corpse task port (here, |task|) + // is distinct from the process’ original task port (ChildTask()). This is + // filed as https://openradar.appspot.com/29079442. + // + // Instead of comparing task ports, compare PIDs. + pid_t task_pid; + kern_return_t kr = pid_for_task(task, &task_pid); + EXPECT_EQ(KERN_SUCCESS, kr) << MachErrorMessage(kr, "pid_for_task"); + EXPECT_EQ(ChildPID(), task_pid); ProcessReader process_reader; bool rv = process_reader.Initialize(task); From c4cdec3d72a2d2abad84a98bc0bcf525333b3280 Mon Sep 17 00:00:00 2001 From: Scott Graham Date: Thu, 3 Nov 2016 09:38:14 -0700 Subject: [PATCH 05/10] Handle non-crashing cases for server failure to start Follow up #4! R=mark@chromium.org BUG=chromium:567850,chromium:656800 TEST=tests added to crashpad_client_test Change-Id: I2a53f2168988e620ce240750c6c2d544ba95c8b4 Reviewed-on: https://chromium-review.googlesource.com/406741 Reviewed-by: Mark Mentovai --- client/crashpad_client_win.cc | 27 ++++-- client/crashpad_client_win_test.cc | 88 +++++++++++++++++++ handler/handler.gyp | 7 ++ .../fake_handler_that_crashes_at_startup.cc | 20 +++++ util/win/termination_codes.h | 2 +- 5 files changed, 138 insertions(+), 6 deletions(-) create mode 100644 handler/win/fake_handler_that_crashes_at_startup.cc diff --git a/client/crashpad_client_win.cc b/client/crashpad_client_win.cc index 20a66d59..235ef185 100644 --- a/client/crashpad_client_win.cc +++ b/client/crashpad_client_win.cc @@ -95,7 +95,7 @@ void SetHandlerStartupState(StartupState state) { static_cast(state)); } -LONG WINAPI UnhandledExceptionHandler(EXCEPTION_POINTERS* exception_pointers) { +StartupState BlockUntilHandlerStartedOrFailed() { // Wait until we know the handler has either succeeded or failed to start. base::subtle::AtomicWord startup_state; while ( @@ -104,7 +104,11 @@ LONG WINAPI UnhandledExceptionHandler(EXCEPTION_POINTERS* exception_pointers) { Sleep(1); } - if (startup_state == static_cast(StartupState::kFailed)) { + return static_cast(startup_state); +} + +LONG WINAPI UnhandledExceptionHandler(EXCEPTION_POINTERS* exception_pointers) { + if (BlockUntilHandlerStartedOrFailed() == StartupState::kFailed) { // If we know for certain that the handler has failed to start, then abort // here, rather than trying to signal to a handler that will never arrive, // and then sleeping unnecessarily. @@ -112,6 +116,7 @@ LONG WINAPI UnhandledExceptionHandler(EXCEPTION_POINTERS* exception_pointers) { TerminateProcess(GetCurrentProcess(), kTerminationCodeCrashNoDump); return EXCEPTION_CONTINUE_SEARCH; } + // Otherwise, we know the handler startup has succeeded, and we can continue. // Tracks whether a thread has already entered UnhandledExceptionHandler. @@ -644,7 +649,15 @@ bool CrashpadClient::WaitForHandlerStart() { void CrashpadClient::DumpWithoutCrash(const CONTEXT& context) { if (g_signal_non_crash_dump == INVALID_HANDLE_VALUE || g_non_crash_dump_done == INVALID_HANDLE_VALUE) { - LOG(ERROR) << "haven't called UseHandler()"; + LOG(ERROR) << "not connected"; + return; + } + + if (BlockUntilHandlerStartedOrFailed() == StartupState::kFailed) { + // If we know for certain that the handler has failed to start, then abort + // here, as we would otherwise wait indefinitely for the + // g_non_crash_dump_done event that would never be signalled. + LOG(ERROR) << "crash server failed to launch, no dump captured"; return; } @@ -695,11 +708,15 @@ void CrashpadClient::DumpWithoutCrash(const CONTEXT& context) { // static void CrashpadClient::DumpAndCrash(EXCEPTION_POINTERS* exception_pointers) { if (g_signal_exception == INVALID_HANDLE_VALUE) { - LOG(ERROR) << "haven't called UseHandler(), no dump captured"; - TerminateProcess(GetCurrentProcess(), kTerminationCodeUseHandlerNotCalled); + LOG(ERROR) << "not connected"; + TerminateProcess(GetCurrentProcess(), + kTerminationCodeNotConnectedToHandler); return; } + // We don't need to check for handler startup here, as + // UnhandledExceptionHandler() necessarily does that. + UnhandledExceptionHandler(exception_pointers); } diff --git a/client/crashpad_client_win_test.cc b/client/crashpad_client_win_test.cc index cd663202..94a9b0cc 100644 --- a/client/crashpad_client_win_test.cc +++ b/client/crashpad_client_win_test.cc @@ -15,10 +15,12 @@ #include "client/crashpad_client.h" #include "base/files/file_path.h" +#include "base/macros.h" #include "gtest/gtest.h" #include "test/paths.h" #include "test/scoped_temp_dir.h" #include "test/win/win_multiprocess.h" +#include "util/win/termination_codes.h" namespace crashpad { namespace test { @@ -88,6 +90,92 @@ TEST(CrashpadClient, StartWithSameStdoutStderr) { WinMultiprocess::Run(); } +void StartAndUseBrokenHandler(CrashpadClient* client) { + ScopedTempDir temp_dir; + base::FilePath handler_path = Paths::Executable().DirName().Append( + FILE_PATH_LITERAL("fake_handler_that_crashes_at_startup.exe")); + ASSERT_TRUE(client->StartHandler(handler_path, + temp_dir.path(), + base::FilePath(), + "", + std::map(), + std::vector(), + false, + true)); +} + +class HandlerLaunchFailureCrash : public WinMultiprocess { + public: + HandlerLaunchFailureCrash() : WinMultiprocess() {} + + private: + void WinMultiprocessParent() override { + SetExpectedChildExitCode(crashpad::kTerminationCodeCrashNoDump); + } + + void WinMultiprocessChild() override { + CrashpadClient client; + StartAndUseBrokenHandler(&client); + __debugbreak(); + exit(0); + } +}; + +TEST(CrashpadClient, HandlerLaunchFailureCrash) { + WinMultiprocess::Run(); +} + +class HandlerLaunchFailureDumpAndCrash : public WinMultiprocess { + public: + HandlerLaunchFailureDumpAndCrash() : WinMultiprocess() {} + + private: + void WinMultiprocessParent() override { + SetExpectedChildExitCode(crashpad::kTerminationCodeCrashNoDump); + } + + void WinMultiprocessChild() override { + CrashpadClient client; + StartAndUseBrokenHandler(&client); + // We don't need to fill this out as we're only checking that we're + // terminated with the correct failure code. + EXCEPTION_POINTERS info = {}; + client.DumpAndCrash(&info); + exit(0); + } +}; + +TEST(CrashpadClient, HandlerLaunchFailureDumpAndCrash) { + WinMultiprocess::Run(); +} + +class HandlerLaunchFailureDumpWithoutCrash : public WinMultiprocess { + public: + HandlerLaunchFailureDumpWithoutCrash() : WinMultiprocess() {} + + private: + void WinMultiprocessParent() override { + // DumpWithoutCrash() normally blocks indefinitely. There's no return value, + // but confirm that it exits cleanly because it'll return right away if the + // handler didn't start. + SetExpectedChildExitCode(0); + } + + void WinMultiprocessChild() override { + CrashpadClient client; + StartAndUseBrokenHandler(&client); + // We don't need to fill this out as we're only checking that we're + // terminated with the correct failure code. + CONTEXT context = {}; + client.DumpWithoutCrash(context); + exit(0); + } +}; + +TEST(CrashpadClient, HandlerLaunchFailureDumpWithoutCrash) { + WinMultiprocess::Run(); +} + } // namespace } // namespace test } // namespace crashpad diff --git a/handler/handler.gyp b/handler/handler.gyp index cb219fb7..d6900531 100644 --- a/handler/handler.gyp +++ b/handler/handler.gyp @@ -160,6 +160,13 @@ 'win/crash_other_program.cc', ], }, + { + 'target_name': 'fake_handler_that_crashes_at_startup', + 'type': 'executable', + 'sources': [ + 'win/fake_handler_that_crashes_at_startup.cc', + ], + }, { 'target_name': 'hanging_program', 'type': 'executable', diff --git a/handler/win/fake_handler_that_crashes_at_startup.cc b/handler/win/fake_handler_that_crashes_at_startup.cc new file mode 100644 index 00000000..028190a4 --- /dev/null +++ b/handler/win/fake_handler_that_crashes_at_startup.cc @@ -0,0 +1,20 @@ +// 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. + +// This is used to test a crashpad_handler that launches successfully, but then +// crashes before setting up. +int wmain() { + __debugbreak(); + return 0; +} diff --git a/util/win/termination_codes.h b/util/win/termination_codes.h index 1cb69b18..1bcbf5dd 100644 --- a/util/win/termination_codes.h +++ b/util/win/termination_codes.h @@ -29,7 +29,7 @@ enum TerminationCodes : unsigned int { //! \brief A dump was requested for a client that was never registered with //! the crash handler. - kTerminationCodeUseHandlerNotCalled = 0xffff7003, + kTerminationCodeNotConnectedToHandler = 0xffff7003, }; } // namespace crashpad From b47bf6c250c6b825dee1c5fbad9152c2c962e828 Mon Sep 17 00:00:00 2001 From: Scott Graham Date: Thu, 3 Nov 2016 11:35:19 -0700 Subject: [PATCH 06/10] Fix tests when running on Win10 The Windows 10 loader starts a few extra threads before main(). In a few of the test cases, the tests were relying on thread ordering (generally, the test thread being at index #1). Instead, use other signals to find the correct thread to verify. R=mark@chromium.org Change-Id: Icb1f5a8fdf3a0ea6d82ab65960dbcb650965f269 Reviewed-on: https://chromium-review.googlesource.com/407073 Reviewed-by: Mark Mentovai --- handler/win/crash_other_program.cc | 10 ++++----- handler/win/hanging_program.cc | 3 +++ snapshot/win/end_to_end_test.py | 35 ++++++++++++++++++++++++------ 3 files changed, 36 insertions(+), 12 deletions(-) diff --git a/handler/win/crash_other_program.cc b/handler/win/crash_other_program.cc index d1267f30..d191aac0 100644 --- a/handler/win/crash_other_program.cc +++ b/handler/win/crash_other_program.cc @@ -46,13 +46,13 @@ bool CrashAndDumpTarget(const CrashpadClient& client, HANDLE process) { return false; } - int thread_count = 0; do { if (te32.th32OwnerProcessID == target_pid) { - thread_count++; - if (thread_count == 2) { - // Nominate this lucky thread as our blamee, and dump it. This will be - // "Thread1" in the child. + // We set the thread priority of "Thread1" to a non-default value before + // going to sleep. Dump and blame this thread. For an explanation of + // "9", see + // https://msdn.microsoft.com/en-us/library/windows/desktop/ms685100.aspx. + if (te32.tpBasePri == 9) { ScopedKernelHANDLE thread( OpenThread(kXPThreadAllAccess, false, te32.th32ThreadID)); if (!client.DumpAndCrashTargetProcess( diff --git a/handler/win/hanging_program.cc b/handler/win/hanging_program.cc index 5befba19..63876634 100644 --- a/handler/win/hanging_program.cc +++ b/handler/win/hanging_program.cc @@ -22,6 +22,9 @@ #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; } diff --git a/snapshot/win/end_to_end_test.py b/snapshot/win/end_to_end_test.py index c57a3e61..f469bcf4 100755 --- a/snapshot/win/end_to_end_test.py +++ b/snapshot/win/end_to_end_test.py @@ -185,6 +185,14 @@ class CdbRun(object): global g_had_failures g_had_failures = True + def Find(self, pattern, re_flags=0): + match_obj = re.search(pattern, self.out, re_flags) + if match_obj: + # Matched. Consume up to end of match. + self.out = self.out[match_obj.end(0):] + return match_obj + return None + def RunTests(cdb_path, dump_path, @@ -267,9 +275,15 @@ def RunTests(cdb_path, r'FreeOwnStackAndBreak.*\nquit:', 'at correct location, no additional stack entries') - # Switch to the other thread after jumping to the exception, and examine - # memory. - out = CdbRun(cdb_path, dump_path, '.ecxr; ~1s; db /c14 edi') + # Dump memory pointed to be EDI on the background suspended thread. We don't + # know the index of the thread because the system may have started other + # threads, so first do a run to extract the thread index that's suspended, and + # then another run to dump the data pointed to by EDI for that thread. + out = CdbRun(cdb_path, dump_path, '.ecxr;~') + match_obj = out.Find(r'(\d+)\s+Id: [0-9a-f.]+ Suspend: 1 Teb:') + if match_obj: + thread = match_obj.group(1) + out = CdbRun(cdb_path, dump_path, '.ecxr;~' + thread + 's;db /c14 edi') out.Check(r'63 62 61 60 5f 5e 5d 5c-5b 5a 59 58 57 56 55 54 53 52 51 50', 'data pointed to by registers captured') @@ -330,10 +344,17 @@ def RunTests(cdb_path, 'other program dump exception code') out.Check('!Sleep', 'other program reasonable location') out.Check('hanging_program!Thread1', 'other program dump right thread') - out.Check('\. 1 Id.*Suspend: 0 ', - 'other program exception on correct thread and correct suspend') - out.Check(' 4 Id.*Suspend: 0 ', - 'other program injection thread correct suspend') + count = 0 + while True: + match_obj = out.Find(r'Id.*Suspend: (\d+) ') + if match_obj: + if match_obj.group(1) != '0': + out.Check(r'FAILED', 'all suspend counts should be 0') + else: + count += 1 + else: + break + assert count > 2 out = CdbRun(cdb_path, other_program_no_exception_path, '.ecxr;k') out.Check('Unknown exception - code 0cca11ed', From 0c41b154966787390bdf2e4ac13699a30ee6355e Mon Sep 17 00:00:00 2001 From: Mark Mentovai Date: Fri, 4 Nov 2016 17:10:36 -0400 Subject: [PATCH 07/10] Convert AsciiDoc documentation to Markdown MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Most of the world, including the Chromium universe, seems to be standardizing on Markdown for documentation. Markdown provides the benefit of automatic rendering on Gitiles (Gerrit), and on GitHub mirrors as well. Crashpad should fit in with its surroundings. There are two quirks that I was unable to resolve. - Markdown does not allow **emphasis** within a ```code fence``` region. In blocks showing interactive examples, the AsciiDoc documentation used this to highlight what the user was expected to type. - Markdown does not have a “definition list” (
). This would have been nice in man pages for the Options and Exit Status sections. In its place, I used unnumbered lists. This is a little ugly, but it’s not the end of the world. The new Markdown-formatted documentation is largely identical to the AsciiDoc that it replaces. Minor editorial revisions were made. References to Mac OS X now mention macOS, and tool man pages describing tools that that access task ports now mention System Integrity Protection (SIP). The AppEngine-based https://crashpad.chromium.org/ app in doc/appengine is still necessary to serve Doxygen-generated documentation. This app is updated to redirect existing generated-HTML URLs to Gitiles’ automatic Markdown rendering. Scripts in doc/support are updated to adapt to this change. All AsciiDoc support files in doc/support have been removed. BUG=crashpad:138 Change-Id: I15ad423d5b7aa1b7aa2ed1d2cb72639eec7c81aa Reviewed-on: https://chromium-review.googlesource.com/408256 Reviewed-by: Robert Sesek Reviewed-by: Scott Graham --- README.md | 41 ++++ doc/appengine/README | 4 +- doc/appengine/main.go | 46 ++-- doc/developing.ad | 323 ---------------------------- doc/developing.md | 310 ++++++++++++++++++++++++++ doc/index.ad | 42 ---- doc/status.ad | 42 ---- doc/status.md | 41 ++++ doc/support/asciidoc.conf | 58 ----- doc/support/asciidoc.css | 20 -- doc/support/generate.sh | 56 +++-- doc/support/generate_asciidoc.sh | 111 ---------- doc/support/man_footer.ad | 40 ---- handler/crashpad_handler.ad | 183 ---------------- handler/crashpad_handler.md | 223 +++++++++++++++++++ navbar.md | 21 ++ tools/crashpad_database_util.ad | 163 -------------- tools/crashpad_database_util.md | 207 ++++++++++++++++++ tools/generate_dump.ad | 96 --------- tools/generate_dump.md | 127 +++++++++++ tools/mac/catch_exception_tool.ad | 117 ---------- tools/mac/catch_exception_tool.md | 140 ++++++++++++ tools/mac/exception_port_tool.ad | 188 ---------------- tools/mac/exception_port_tool.md | 234 ++++++++++++++++++++ tools/mac/on_demand_service_tool.ad | 102 --------- tools/mac/on_demand_service_tool.md | 133 ++++++++++++ tools/mac/run_with_crashpad.ad | 112 ---------- tools/mac/run_with_crashpad.md | 147 +++++++++++++ 28 files changed, 1692 insertions(+), 1635 deletions(-) create mode 100644 README.md delete mode 100644 doc/developing.ad create mode 100644 doc/developing.md delete mode 100644 doc/index.ad delete mode 100644 doc/status.ad create mode 100644 doc/status.md delete mode 100644 doc/support/asciidoc.conf delete mode 100644 doc/support/asciidoc.css delete mode 100755 doc/support/generate_asciidoc.sh delete mode 100644 doc/support/man_footer.ad delete mode 100644 handler/crashpad_handler.ad create mode 100644 handler/crashpad_handler.md create mode 100644 navbar.md delete mode 100644 tools/crashpad_database_util.ad create mode 100644 tools/crashpad_database_util.md delete mode 100644 tools/generate_dump.ad create mode 100644 tools/generate_dump.md delete mode 100644 tools/mac/catch_exception_tool.ad create mode 100644 tools/mac/catch_exception_tool.md delete mode 100644 tools/mac/exception_port_tool.ad create mode 100644 tools/mac/exception_port_tool.md delete mode 100644 tools/mac/on_demand_service_tool.ad create mode 100644 tools/mac/on_demand_service_tool.md delete mode 100644 tools/mac/run_with_crashpad.ad create mode 100644 tools/mac/run_with_crashpad.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..c7be545e --- /dev/null +++ b/README.md @@ -0,0 +1,41 @@ + + +# Crashpad + +[Crashpad](https://crashpad.chromium.org/) is a crash-reporting system. + +## Documentation + + * [Project status](doc/status.md) + * [Developing Crashpad](doc/developing.md): instructions for getting the source + code, building, testing, and contributing to the project. + * [Crashpad interface documentation](https://crashpad.chromium.org/doxygen/) + * [Crashpad tool man pages](https://crashpad.chromium.org/man/) + +## Source Code + +Crashpad’s source code is hosted in a Git repository at +https://chromium.googlesource.com/crashpad/crashpad. + +## Other Links + + * Bugs can be reported at the [Crashpad issue + tracker](https://crashpad.chromium.org/bug/). + * The [Crashpad Buildbot](https://build.chromium.org/p/client.crashpad) + performs automated builds and tests. + * [crashpad-dev](https://groups.google.com/a/chromium.org/group/crashpad-dev) + is the Crashpad developers’ mailing list. diff --git a/doc/appengine/README b/doc/appengine/README index 00a7f761..b92e311b 100644 --- a/doc/appengine/README +++ b/doc/appengine/README @@ -1,7 +1,7 @@ This is the App Engine app that serves https://crashpad.chromium.org/. To work on this app, obtain the App Engine SDK for Go from -https://cloud.google.com/appengine/downloads. Unpacking it produces a +https://cloud.google.com/appengine/docs/go/download. Unpacking it produces a go_appengine directory. This may be added to your $PATH for convenience, although it is not necessary. @@ -19,7 +19,7 @@ $ GOROOT=…/go_appengine/goroot GOPATH=…/go_appengine/gopath go get -d To test locally: -$ goapp serve +$ …/go_appengine/goapp serve Look for the “Starting module "default" running at: http://localhost:8080” line, which tells you the URL of the local running instance of the app. diff --git a/doc/appengine/main.go b/doc/appengine/main.go index e05870f5..adcf6716 100644 --- a/doc/appengine/main.go +++ b/doc/appengine/main.go @@ -37,31 +37,49 @@ func init() { func handler(w http.ResponseWriter, r *http.Request) { const ( - baseURL = "https://chromium.googlesource.com/crashpad/crashpad/+/doc/doc/generated/?format=TEXT" - bugBaseURL = "https://bugs.chromium.org/p/crashpad/" + baseURL = "https://chromium.googlesource.com/crashpad/crashpad/+/" + masterBaseURL = baseURL + "master/" + generatedDocBaseURL = baseURL + "doc/doc/generated/?format=TEXT" + bugBaseURL = "https://bugs.chromium.org/p/crashpad/" ) + redirectMap := map[string]string{ + "/": masterBaseURL + "README.md", + "/bug": bugBaseURL, + "/bug/": bugBaseURL, + "/bug/new": bugBaseURL + "issues/entry", + "/doc/developing.html": masterBaseURL + "/doc/developing.md", + "/doc/status.html": masterBaseURL + "/doc/status.md", + "/man/catch_exception_tool.html": masterBaseURL + "tools/mac/catch_exception_tool.md", + "/man/crashpad_database_util.html": masterBaseURL + "tools/crashpad_database_util.md", + "/man/crashpad_handler.html": masterBaseURL + "handler/crashpad_handler.md", + "/man/exception_port_tool.html": masterBaseURL + "tools/mac/exception_port_tool.md", + "/man/generate_dump.html": masterBaseURL + "tools/generate_dump.md", + "/man/on_demand_service_tool.html": masterBaseURL + "tools/mac/on_demand_service_tool.md", + "/man/run_with_crashpad.html": masterBaseURL + "tools/mac/run_with_crashpad.md", + } + ctx := appengine.NewContext(r) client := urlfetch.Client(ctx) + destinationURL, exists := redirectMap[r.URL.Path] + if exists { + http.Redirect(w, r, destinationURL, http.StatusFound) + return + } + + if strings.HasPrefix(r.URL.Path, "/bug/") { + http.Redirect(w, r, bugBaseURL+"issues/detail?id="+r.URL.Path[5:], http.StatusFound) + return + } + // Don’t show dotfiles. if strings.HasPrefix(path.Base(r.URL.Path), ".") { http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) return } - if r.URL.Path == "/bug" || r.URL.Path == "/bug/" { - http.Redirect(w, r, bugBaseURL, http.StatusFound) - return - } else if r.URL.Path == "/bug/new" { - http.Redirect(w, r, bugBaseURL+"issues/entry", http.StatusFound) - return - } else if strings.HasPrefix(r.URL.Path, "/bug/") { - http.Redirect(w, r, bugBaseURL+"issues/detail?id="+r.URL.Path[5:], http.StatusFound) - return - } - - u, err := url.Parse(baseURL) + u, err := url.Parse(generatedDocBaseURL) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return diff --git a/doc/developing.ad b/doc/developing.ad deleted file mode 100644 index a8aafcf1..00000000 --- a/doc/developing.ad +++ /dev/null @@ -1,323 +0,0 @@ -// 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. - -:doctype: article - -= Developing Crashpad - -== Status - -link:status.html[Project status] information has moved to its own page. - -== Introduction - -Crashpad is a https://dev.chromium.org/Home[Chromium project]. Most of -its development practices follow Chromium’s. In order to function on its -own in other projects, Crashpad uses -https://chromium.googlesource.com/chromium/mini_chromium/[mini_chromium], -a small, self-contained library that provides many of Chromium’s useful -low-level base routines. -https://chromium.googlesource.com/chromium/mini_chromium/+/master/README[mini_chromium’s -README] provides more detail. - -== Prerequisites - -To develop Crashpad, the following tools are necessary, and must be -present in the `$PATH` environment variable: - - * Chromium’s - https://dev.chromium.org/developers/how-tos/depottools[depot_tools]. - * https://git-scm.com/[Git]. This is provided by Xcode on Mac OS X and by - depot_tools on Windows. - * https://www.python.org/[Python]. This is provided by the operating system on - Mac OS X, and by depot_tools on Windows. - * Appropriate development tools. For Mac OS X, this is - https://developer.apple.com/xcode/[Xcode], and for Windows, it’s - https://www.visualstudio.com/[Visual Studio]. - -== Getting the Source Code - -The main source code repository is a Git repository hosted at -https://chromium.googlesource.com/crashpad/crashpad. Although it is possible to -check out this repository directly with `git clone`, Crashpad’s dependencies are -managed by -https://dev.chromium.org/developers/how-tos/depottools#TOC-gclient[`gclient`] -instead of Git submodules, so to work on Crashpad, it is best to use `fetch` to -get the source code. - -`fetch` and `gclient` are part of the -https://dev.chromium.org/developers/how-tos/depottools[depot_tools]. There’s no -need to install them separately. - -=== Initial Checkout - -[subs="verbatim,quotes"] ----- -$ *mkdir \~/crashpad* -$ *cd ~/crashpad* -$ *fetch crashpad* ----- - -`fetch crashpad` performs the initial `git clone` and `gclient sync`, -establishing a fully-functional local checkout. - -=== Subsequent Checkouts - -[subs="verbatim,quotes"] ----- -$ *cd ~/crashpad/crashpad* -$ *git pull -r* -$ *gclient sync* ----- - -== Building - -Crashpad uses https://gyp.gsrc.io/[GYP] to generate -https://ninja-build.org/[Ninja] build files. The build is described by `.gyp` -files throughout the Crashpad source code tree. The `build/gyp_crashpad.py` -script runs GYP properly for Crashpad, and is also called when you run `fetch -crashpad`, `gclient sync`, or `gclient runhooks`. - -The Ninja build files and build output are in the `out` directory. Both debug- -and release-mode configurations are available. The examples below show the debug -configuration. To build and test the release configuration, substitute `Release` -for `Debug`. - -[subs="verbatim,quotes"] ----- -$ *cd ~/crashpad/crashpad* -$ *ninja -C out/Debug* ----- - -Ninja is part of the -https://dev.chromium.org/developers/how-tos/depottools[depot_tools]. There’s no -need to install it separately. - -=== Android - -Crashpad’s Android port is in its early stages. This build relies on -cross-compilation. It’s possible to develop Crashpad for Android on any platform -that the https://developer.android.com/ndk/[Android NDK (Native Development -Kit)] runs on. - -If it’s not already present on your system, -https://developer.android.com/ndk/downloads/[download the NDK package for your -system] and expand it to a suitable location. These instructions assume that -it’s been expanded to `~/android-ndk-r13`. - -To build Crashpad, portions of the NDK must be reassembled into a -https://developer.android.com/ndk/guides/standalone_toolchain.html[standalone -toolchain]. This is a repackaged subset of the NDK suitable for cross-compiling -for a single Android architecture (such as `arm`, `arm64`, `x86`, and `x86_64`) -targeting a specific -https://source.android.com/source/build-numbers.html[Android API level]. The -standalone toolchain only needs to be built from the NDK one time for each set -of options desired. To build a standalone toolchain targeting 64-bit ARM and API -level 21 (Android 5.0 “Lollipop”), run: - -[subs="verbatim,quotes"] ----- -$ *cd ~* -$ *python android-ndk-r13/build/tools/make_standalone_toolchain.py \ - --arch=arm64 --api=21 --install-dir=android-ndk-r13_arm64_api21* ----- - -Note that Chrome uses Android API level 21 for 64-bit platforms and 16 for -32-bit platforms. See Chrome’s -https://chromium.googlesource.com/chromium/src/+/master/build/config/android/config.gni[`build/config/android/config.gni`] -which sets `_android_api_level` and `_android64_api_level`. - -To configure a Crashpad build for Android using this standalone toolchain, -set several environment variables directing the build to the standalone -toolchain, along with GYP options to identify an Android build. This must be -done after any `gclient sync`, or instead of any `gclient runhooks` operation. -The environment variables only need to be set for this `gyp_crashpad.py` -invocation, and need not be permanent. - -[subs="verbatim,quotes"] ----- -$ *cd \~/crashpad/crashpad* -$ *CC_target=\~/android-ndk-r13_arm64_api21/bin/clang \ - CXX_target=\~/android-ndk-r13_arm64_api21/bin/clang++ \ - AR_target=\~/android-ndk-r13_arm64_api21/bin/aarch64-linux-android-ar \ - NM_target=\~/android-ndk-r13_arm64_api21/bin/aarch64-linux-android-nm \ - READELF_target=~/android-ndk-r13_arm64_api21/bin/aarch64-linux-android-readelf \ - python build/gyp_crashpad.py \ - -DOS=android -Dtarget_arch=arm64 -Dclang=1 \ - --generator-output=out_android_arm64_api21 -f ninja-android* ----- - -Target “triplets” to use for `ar`, `nm`, and `readelf` are: - -[width="40%",cols="1,3",frame="topbot"] -|=== -|`arm` |`arm-linux-androideabi` -|`arm64` |`aarch64-linux-android` -|`x86` |`i686-linux-android` -|`x86_64` |`x86_64-linux-android` -|=== - -The port is incomplete, but targets known to be working include `crashpad_util`, -`crashpad_test`, and `crashpad_test_test`. This list will grow over time. To -build, direct `ninja` to the specific `out` directory chosen by -`--generator-output` above. - -[subs="verbatim,quotes"] ----- -$ *ninja -C out_android_arm64_api21/out/Debug crashpad_test_test* ----- - -== Testing - -Crashpad uses https://github.com/google/googletest/[Google Test] as its -unit-testing framework, and some tests use -https://github.com/google/googletest/tree/master/googlemock/[Google Mock] as -well. Its tests are currently split up into several test executables, each -dedicated to testing a different component. This may change in the future. After -a successful build, the test executables will be found at -`out/Debug/crashpad_*_test`. - -[subs="verbatim,quotes"] ----- -$ *cd ~/crashpad/crashpad* -$ *out/Debug/crashpad_minidump_test* -$ *out/Debug/crashpad_util_test* ----- - -A script is provided to run all of Crashpad’s tests. It accepts a single -argument that tells it which configuration to test. - -[subs="verbatim,quotes"] ----- -$ *cd ~/crashpad/crashpad* -$ *python build/run_tests.py Debug* ----- - -=== Android - -To test on Android, use -https://developer.android.com/studio/command-line/adb.html[ADB (Android Debug -Bridge)] to `adb push` test executables and test data to a device or emulator, -then use `adb shell` to get a shell to run the test executables from. ADB is -part of the https://developer.android.com/sdk/[Android SDK]. Note that it is -sufficient to install just the command-line tools. The entire Android Studio IDE -is not necessary to obtain ADB. - -This example runs `crashpad_test_test` on a device. This test executable has a -run-time dependency on a second executable and a test data file, which are also -transferred to the device prior to running the test. - -[subs="verbatim,quotes"] ----- -$ *cd ~/crashpad/crashpad* -$ *adb push out_android_arm64_api21/out/Debug/crashpad_test_test /data/local/tmp/* -[100%] /data/local/tmp/crashpad_test_test -$ *adb push \ - out_android_arm64_api21/out/Debug/crashpad_test_test_multiprocess_exec_test_child \ - /data/local/tmp/* -[100%] /data/local/tmp/crashpad_test_test_multiprocess_exec_test_child -$ *adb shell mkdir -p /data/local/tmp/crashpad_test_data_root/test* -$ *adb push test/paths_test_data_root.txt \ - /data/local/tmp/crashpad_test_data_root/test/* -[100%] /data/local/tmp/crashpad_test_data_root/test/paths_test_data_root.txt -$ *adb shell* -device:/ $ *cd /data/local/tmp* -device:/data/local/tmp $ *CRASHPAD_TEST_DATA_ROOT=crashpad_test_data_root \ - ./crashpad_test_test* ----- - -== Contributing - -Crashpad’s contribution process is very similar to -https://dev.chromium.org/developers/contributing-code[Chromium’s contribution -process]. - -=== Code Review - -A code review must be conducted for every change to Crashpad’s source code. Code -review is conducted on https://chromium-review.googlesource.com/[Chromium’s -Gerrit] system, and all code reviews must be sent to an appropriate reviewer, -with a Cc sent to -https://groups.google.com/a/chromium.org/group/crashpad-dev[crashpad-dev]. The -https://chromium.googlesource.com/crashpad/crashpad/+/master/codereview.settings[`codereview.settings`] -file specifies this environment to `git-cl`. - -`git-cl` is part of the -https://dev.chromium.org/developers/how-tos/depottools[depot_tools]. There’s no -need to install it separately. - -[subs="verbatim,quotes"] ----- -$ *cd ~/crashpad/crashpad* -$ *git checkout -b work_branch origin/master* -_…do some work…_ -$ *git add …* -$ *git commit* -$ *git cl upload* ----- - -The https://polygerrit.appspot.com/[PolyGerrit interface] to Gerrit, undergoing -active development, is recommended. To switch from the classic GWT-based Gerrit -UI to PolyGerrit, click the PolyGerrit link in a Gerrit review page’s footer. - -Uploading a patch to Gerrit does not automatically request a review. You must -select a reviewer on the Gerrit review page after running `git cl upload`. This -action notifies your reviewer of the code review request. If you have lost track -of the review page, `git cl issue` will remind you of its URL. Alternatively, -you can request review when uploading to Gerrit by using `git cl upload ---send-mail`. - -Git branches maintain their association with Gerrit reviews, so if you need to -make changes based on review feedback, you can do so on the correct Git branch, -committing your changes locally with `git commit`. You can then upload a new -patch set with `git cl upload` and let your reviewer know you’ve addressed the -feedback. - -=== Landing Changes - -After code review is complete and “Code-Review: +1” has been received from all -reviewers, project members can commit the patch themselves: - -[subs="verbatim,quotes"] ----- -$ *cd ~/crashpad/crashpad* -$ *git checkout work_branch* -$ *git cl land* ----- - -Alternatively, patches can be committed by clicking the “Submit” button in the -Gerrit UI. - -Crashpad does not currently have a -https://dev.chromium.org/developers/testing/commit-queue[commit queue], so -contributors who are not project members will have to ask a project member to -commit the patch for them. Project members can commit changes on behalf of -external contributors by clicking the “Submit” button in the Gerrit UI. - -=== External Contributions - -Copyright holders must complete the -https://developers.google.com/open-source/cla/individual[Individual Contributor -License Agreement] or -https://developers.google.com/open-source/cla/corporate[Corporate Contributor -License Agreement] as appropriate before any submission can be accepted, and -must be listed in the `AUTHORS` file. Contributors may be listed in the -`CONTRIBUTORS` file. - -== Buildbot - -The https://build.chromium.org/p/client.crashpad/[Crashpad Buildbot] performs -automated builds and tests of Crashpad. Before checking out or updating the -Crashpad source code, and after checking in a new change, it is prudent to check -the Buildbot to ensure that “the tree is green.” diff --git a/doc/developing.md b/doc/developing.md new file mode 100644 index 00000000..71e10404 --- /dev/null +++ b/doc/developing.md @@ -0,0 +1,310 @@ + + +# Developing Crashpad + +## Status + +[Project status](status.md) information has moved to its own page. + +## Introduction + +Crashpad is a [Chromium project](https://dev.chromium.org/Home). Most of its +development practices follow Chromium’s. In order to function on its own in +other projects, Crashpad uses +[mini_chromium](https://chromium.googlesource.com/chromium/mini_chromium/), a +small, self-contained library that provides many of Chromium’s useful low-level +base routines. [mini_chromium’s +README](https://chromium.googlesource.com/chromium/mini_chromium/+/master/README) +provides more detail. + +## Prerequisites + +To develop Crashpad, the following tools are necessary, and must be +present in the `$PATH` environment variable: + + * Chromium’s + [depot_tools](https://dev.chromium.org/developers/how-tos/depottools). + * [Git](https://git-scm.com/). This is provided by Xcode on macOS and by + depot_tools on Windows. + * [Python](https://www.python.org/). This is provided by the operating system + on macOS, and by depot_tools on Windows. + * Appropriate development tools. For macOS, this is + [Xcode](https://developer.apple.com/xcode/) and for Windows, it’s [Visual + Studio](https://www.visualstudio.com/). + +## Getting the Source Code + +The main source code repository is a Git repository hosted at +https://chromium.googlesource.com/crashpad/crashpad. Although it is possible to +check out this repository directly with `git clone`, Crashpad’s dependencies are +managed by +[`gclient`](https://dev.chromium.org/developers/how-tos/depottools#TOC-gclient) +instead of Git submodules, so to work on Crashpad, it is best to use `fetch` to +get the source code. + +`fetch` and `gclient` are part of the +[depot_tools](https://dev.chromium.org/developers/how-tos/depottools). There’s +no need to install them separately. + +### Initial Checkout + +``` +$ mkdir ~/crashpad +$ cd ~/crashpad +$ fetch crashpad +``` + +`fetch crashpad` performs the initial `git clone` and `gclient sync`, +establishing a fully-functional local checkout. + +### Subsequent Checkouts + +``` +$ cd ~/crashpad/crashpad +$ git pull -r +$ gclient sync +``` + +## Building + +Crashpad uses [GYP](https://gyp.gsrc.io/) to generate +[Ninja](https://ninja-build.org/) build files. The build is described by `.gyp` +files throughout the Crashpad source code tree. The +[`build/gyp_crashpad.py`](https://chromium.googlesource.com/crashpad/crashpad/+/master/build/gyp_crashpad.py) +script runs GYP properly for Crashpad, and is also called when you run `fetch +crashpad`, `gclient sync`, or `gclient runhooks`. + +The Ninja build files and build output are in the `out` directory. Both debug- +and release-mode configurations are available. The examples below show the debug +configuration. To build and test the release configuration, substitute `Release` +for `Debug`. + +``` +$ cd ~/crashpad/crashpad +$ ninja -C out/Debug +``` + +Ninja is part of the +[depot_tools](https://dev.chromium.org/developers/how-tos/depottools). There’s +no need to install it separately. + +### Android + +Crashpad’s Android port is in its early stages. This build relies on +cross-compilation. It’s possible to develop Crashpad for Android on any platform +that the [Android NDK (Native Development +Kit)](https://developer.android.com/ndk/) runs on. + +If it’s not already present on your system, [download the NDK package for your +system](https://developer.android.com/ndk/downloads/) and expand it to a +suitable location. These instructions assume that it’s been expanded to +`~/android-ndk-r13`. + +To build Crashpad, portions of the NDK must be reassembled into a [standalone +toolchain](https://developer.android.com/ndk/guides/standalone_toolchain.html). +This is a repackaged subset of the NDK suitable for cross-compiling for a single +Android architecture (such as `arm`, `arm64`, `x86`, and `x86_64`) targeting a +specific [Android API +level](https://source.android.com/source/build-numbers.html). The standalone +toolchain only needs to be built from the NDK one time for each set of options +desired. To build a standalone toolchain targeting 64-bit ARM and API level 21 +(Android 5.0 “Lollipop”), run: + +``` +$ cd ~ +$ python android-ndk-r13/build/tools/make_standalone_toolchain.py \ + --arch=arm64 --api=21 --install-dir=android-ndk-r13_arm64_api21 +``` + +Note that Chrome uses Android API level 21 for 64-bit platforms and 16 for +32-bit platforms. See Chrome’s +[`build/config/android/config.gni`](https://chromium.googlesource.com/chromium/src/+/master/build/config/android/config.gni) +which sets `_android_api_level` and `_android64_api_level`. + +To configure a Crashpad build for Android using this standalone toolchain, set +several environment variables directing the build to the standalone toolchain, +along with GYP options to identify an Android build. This must be done after any +`gclient sync`, or instead of any `gclient runhooks` operation. The environment +variables only need to be set for this `gyp_crashpad.py` invocation, and need +not be permanent. + +``` +$ cd ~/crashpad/crashpad +$ CC_target=~/android-ndk-r13_arm64_api21/bin/clang \ + CXX_target=~/android-ndk-r13_arm64_api21/bin/clang++ \ + AR_target=~/android-ndk-r13_arm64_api21/bin/aarch64-linux-android-ar \ + NM_target=~/android-ndk-r13_arm64_api21/bin/aarch64-linux-android-nm \ + READELF_target=~/android-ndk-r13_arm64_api21/bin/aarch64-linux-android-readelf \ + python build/gyp_crashpad.py \ + -DOS=android -Dtarget_arch=arm64 -Dclang=1 \ + --generator-output=out_android_arm64_api21 -f ninja-android +``` + +Target “triplets” to use for `ar`, `nm`, and `readelf` are: + +| Architecture | Target “triplet” | +|:-------------|:------------------------| +| `arm` | `arm-linux-androideabi` | +| `arm64` | `aarch64-linux-android` | +| `x86` | `i686-linux-android` | +| `x86_64` | `x86_64-linux-android` | + +The port is incomplete, but targets known to be working include `crashpad_util`, +`crashpad_test`, and `crashpad_test_test`. This list will grow over time. To +build, direct `ninja` to the specific `out` directory chosen by +`--generator-output` above. + +``` +$ ninja -C out_android_arm64_api21/out/Debug crashpad_test_test +``` + +## Testing + +Crashpad uses [Google Test](https://github.com/google/googletest/) as its +unit-testing framework, and some tests use [Google +Mock](https://github.com/google/googletest/tree/master/googlemock/) as well. Its +tests are currently split up into several test executables, each dedicated to +testing a different component. This may change in the future. After a successful +build, the test executables will be found at `out/Debug/crashpad_*_test`. + +``` +$ cd ~/crashpad/crashpad +$ out/Debug/crashpad_minidump_test +$ out/Debug/crashpad_util_test +``` + +A script is provided to run all of Crashpad’s tests. It accepts a single +argument that tells it which configuration to test. + +``` +$ cd ~/crashpad/crashpad +$ python build/run_tests.py Debug +``` + +### Android + +To test on Android, use [ADB (Android Debug +Bridge)](https://developer.android.com/studio/command-line/adb.html) to `adb +push` test executables and test data to a device or emulator, then use `adb +shell` to get a shell to run the test executables from. ADB is part of the +[Android SDK](https://developer.android.com/sdk/). Note that it is sufficient to +install just the command-line tools. The entire Android Studio IDE is not +necessary to obtain ADB. + +This example runs `crashpad_test_test` on a device. This test executable has a +run-time dependency on a second executable and a test data file, which are also +transferred to the device prior to running the test. + +``` +$ cd ~/crashpad/crashpad +$ adb push out_android_arm64_api21/out/Debug/crashpad_test_test /data/local/tmp/ +[100%] /data/local/tmp/crashpad_test_test +$ adb push \ + out_android_arm64_api21/out/Debug/crashpad_test_test_multiprocess_exec_test_child \ + /data/local/tmp/ +[100%] /data/local/tmp/crashpad_test_test_multiprocess_exec_test_child +$ adb shell mkdir -p /data/local/tmp/crashpad_test_data_root/test +$ adb push test/paths_test_data_root.txt \ + /data/local/tmp/crashpad_test_data_root/test/ +[100%] /data/local/tmp/crashpad_test_data_root/test/paths_test_data_root.txt +$ adb shell +device:/ $ cd /data/local/tmp +device:/data/local/tmp $ CRASHPAD_TEST_DATA_ROOT=crashpad_test_data_root \ + ./crashpad_test_test +``` + +## Contributing + +Crashpad’s contribution process is very similar to [Chromium’s contribution +process](https://dev.chromium.org/developers/contributing-code). + +### Code Review + +A code review must be conducted for every change to Crashpad’s source code. Code +review is conducted on [Chromium’s +Gerrit](https://chromium-review.googlesource.com/) system, and all code reviews +must be sent to an appropriate reviewer, with a Cc sent to +[crashpad-dev](https://groups.google.com/a/chromium.org/group/crashpad-dev). The +[`codereview.settings`](https://chromium.googlesource.com/crashpad/crashpad/+/master/codereview.settings) +file specifies this environment to `git-cl`. + +`git-cl` is part of the +[depot_tools](https://dev.chromium.org/developers/how-tos/depottools). There’s +no need to install it separately. + +``` +$ cd ~/crashpad/crashpad +$ git checkout -b work_branch origin/master +…do some work… +$ git add … +$ git commit +$ git cl upload +``` + +The [PolyGerrit interface](https://polygerrit.appspot.com/) to Gerrit, +undergoing active development, is recommended. To switch from the classic +GWT-based Gerrit UI to PolyGerrit, click the PolyGerrit link in a Gerrit review +page’s footer. + +Uploading a patch to Gerrit does not automatically request a review. You must +select a reviewer on the Gerrit review page after running `git cl upload`. This +action notifies your reviewer of the code review request. If you have lost track +of the review page, `git cl issue` will remind you of its URL. Alternatively, +you can request review when uploading to Gerrit by using `git cl upload +--send-mail`. + +Git branches maintain their association with Gerrit reviews, so if you need to +make changes based on review feedback, you can do so on the correct Git branch, +committing your changes locally with `git commit`. You can then upload a new +patch set with `git cl upload` and let your reviewer know you’ve addressed the +feedback. + +### Landing Changes + +After code review is complete and “Code-Review: +1” has been received from all +reviewers, project members can commit the patch themselves: + +``` +$ cd ~/crashpad/crashpad +$ git checkout work_branch +$ git cl land +``` + +Alternatively, patches can be committed by clicking the “Submit” button in the +Gerrit UI. + +Crashpad does not currently have a [commit +queue](https://dev.chromium.org/developers/testing/commit-queue), so +contributors who are not project members will have to ask a project member to +commit the patch for them. Project members can commit changes on behalf of +external contributors by clicking the “Submit” button in the Gerrit UI. + +### External Contributions + +Copyright holders must complete the [Individual Contributor License +Agreement](https://developers.google.com/open-source/cla/individual) or +[Corporate Contributor License +Agreement](https://developers.google.com/open-source/cla/corporate) as +appropriate before any submission can be accepted, and must be listed in the +`AUTHORS` file. Contributors may be listed in the `CONTRIBUTORS` file. + +## Buildbot + +The [Crashpad Buildbot](https://build.chromium.org/p/client.crashpad/) performs +automated builds and tests of Crashpad. Before checking out or updating the +Crashpad source code, and after checking in a new change, it is prudent to check +the Buildbot to ensure that “the tree is green.” diff --git a/doc/index.ad b/doc/index.ad deleted file mode 100644 index 3b06292e..00000000 --- a/doc/index.ad +++ /dev/null @@ -1,42 +0,0 @@ -// 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. - -:doctype: article - -= Crashpad - -https://crashpad.chromium.org/[Crashpad] is a crash-reporting system. - -== Documentation - - * link:status.html[Project status] - * link:developing.html[Developing Crashpad]: instructions for getting the - source code, building, testing, and contributing to the project. - * https://crashpad.chromium.org/doxygen/index.html[Crashpad interface - documentation] - * https://crashpad.chromium.org/man/index.html[Crashpad tool man pages] - -== Source Code - -Crashpad’s source code is hosted in a Git repository at -https://chromium.googlesource.com/crashpad/crashpad. - -== Other Links - - * Bugs can be reported at the https://crashpad.chromium.org/bug/[Crashpad issue - tracker]. - * The https://build.chromium.org/p/client.crashpad[Crashpad Buildbot] performs - automated builds and tests. - * https://groups.google.com/a/chromium.org/group/crashpad-dev[crashpad-dev] is - the Crashpad developers’ mailing list. diff --git a/doc/status.ad b/doc/status.ad deleted file mode 100644 index 6d45dd45..00000000 --- a/doc/status.ad +++ /dev/null @@ -1,42 +0,0 @@ -// 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. - -:doctype: article - -= Project Status - -== Completed - -Crashpad currently consists of a crash-reporting client and some related tools -for Mac OS X and Windows. The core client work for both platforms is -substantially complete. Crashpad became the crash reporter client for -https://dev.chromium.org/Home[Chromium] on Mac OS X as of -https://chromium.googlesource.com/chromium/src/\+/d413b2dcb54d523811d386f1ff4084f677a6d089[March -2015], and on Windows as of -https://chromium.googlesource.com/chromium/src/\+/cfa5b01bb1d06bf96967bd37e21a44752801948c[November -2015]. - -== In Progress - -Initial work on a Crashpad client for -https://crashpad.chromium.org/bug/30[Android] has begun. This is currently in -the early implementation phase. - -== Future - -There are plans to bring Crashpad clients to other operating systems in the -future, including a more generic non-Android Linux implementation. There are -also plans to implement a https://crashpad.chromium.org/bug/29[crash report -processor] as part of Crashpad. No timeline for completing this work has been -set yet. diff --git a/doc/status.md b/doc/status.md new file mode 100644 index 00000000..be4503a1 --- /dev/null +++ b/doc/status.md @@ -0,0 +1,41 @@ + + +# Project Status + +## Completed + +Crashpad currently consists of a crash-reporting client and some related tools +for macOS and Windows. The core client work for both platforms is substantially +complete. Crashpad became the crash reporter client for +[Chromium](https://dev.chromium.org/Home) on macOS as of [March +2015](https://chromium.googlesource.com/chromium/src/\+/d413b2dcb54d523811d386f1ff4084f677a6d089), +and on Windows as of [November +2015](https://chromium.googlesource.com/chromium/src/\+/cfa5b01bb1d06bf96967bd37e21a44752801948c). + +## In Progress + +Initial work on a Crashpad client for +[Android](https://crashpad.chromium.org/bug/30) has begun. This is currently in +the early implementation phase. + +## Future + +There are plans to bring Crashpad clients to other operating systems in the +future, including a more generic non-Android Linux implementation. There are +also plans to implement a [crash report +processor](https://crashpad.chromium.org/bug/29) as part of Crashpad. No +timeline for completing this work has been set yet. diff --git a/doc/support/asciidoc.conf b/doc/support/asciidoc.conf deleted file mode 100644 index a4ab2c4c..00000000 --- a/doc/support/asciidoc.conf +++ /dev/null @@ -1,58 +0,0 @@ -# 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. - -[miscellaneous] -# AsciiDoc uses \r\n by default. -newline=\n - -# The default AsciiDoc lang-en.conf uses docdate and doctime for the -# last-updated line in footer-text. These attributes are taken from the file’s -# mtime and cannot be overridden. For a git-based project, the date of the last -# revision is desirable, so change this to use git_date, an attribute that can -# be computed and passed in by the script that runs AsciiDoc. For man pages, use -# the mansource and manversion attributes instead of the hard-coded “Version” -# string and revnumber attribute, so that the version will appear as “Crashpad -# 0.7.0” as it does in “man” output. -ifdef::basebackend-html[] -[footer-text] -ifdef::doctype-manpage[] -{mansource=Version} {manversion={revnumber}}{basebackend-xhtml11?
}{basebackend-xhtml11=
} -endif::doctype-manpage[] -ifndef::doctype-manpage[] -Version {revnumber}{basebackend-xhtml11?
}{basebackend-xhtml11=
} -endif::doctype-manpage[] -Last updated {git_date} -endif::basebackend-html[] - -# The man_link macro was inspired by git’s linkgit macro. See -# https://github.com/git/git/blob/master/Documentation/asciidoc.conf. -ifdef::doctype-manpage[] - -[macros] -(?su)[\\]?(?Pman_link):(?P\S*?)\[(?P.*?)\]= - -ifdef::backend-docbook[] -[man_link-inlinemacro] -{0%{target}} -{0#} -{0#{target}{0}} -{0#} -endif::backend-docbook[] - -ifdef::basebackend-html[] -[man_link-inlinemacro] -{target}{0?({0})} -endif::basebackend-html[] - -endif::doctype-manpage[] diff --git a/doc/support/asciidoc.css b/doc/support/asciidoc.css deleted file mode 100644 index 9808c216..00000000 --- a/doc/support/asciidoc.css +++ /dev/null @@ -1,20 +0,0 @@ -/* 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. */ - -/* The default AsciiDoc asciidoc.css specifies fuchsia as the visited link - * color. This has a dated appearance. Replace it with blue, the same color used - * for unvisited links. */ -a:visited { - color: blue; -} diff --git a/doc/support/generate.sh b/doc/support/generate.sh index 0a2be484..0f77a4a8 100755 --- a/doc/support/generate.sh +++ b/doc/support/generate.sh @@ -29,31 +29,44 @@ cd "$(dirname "${0}")/../.." source doc/support/compat.sh doc/support/generate_doxygen.sh -doc/support/generate_asciidoc.sh output_dir=doc/generated maybe_mkdir "${output_dir}" -for subdir in doc doxygen man ; do - output_subdir="${output_dir}/${subdir}" - maybe_mkdir "${output_subdir}" - rsync -Ilr --delete --exclude .git "out/doc/${subdir}/html/" \ - "${output_subdir}/" -done +maybe_mkdir "${output_dir}/doxygen" +rsync -Ilr --delete --exclude .git "out/doc/doxygen/html/" \ + "${output_dir}/doxygen" -# Move doc/index.html to index.html, adjusting relative paths to other files in -# doc. -base_url=https://crashpad.chromium.org/ -${sed_ext} -e 's%%%g' \ - -e 's%%%g' \ - -e 's% "${output_dir}/index.html" -rm "${output_dir}/doc/index.html" +# Remove old things that used to be present +rm -rf "${output_dir}/doc" +rm -rf "${output_dir}/man" +rm -f "${output_dir}/index.html" # Ensure a favicon exists at the root since the browser will always request it. cp doc/favicon.ico "${output_dir}/" -# Create man/index.html +# Create man/index.html. Do this in two steps so that the built-up list of man +# pages can be sorted according to the basename, not the entire path. +list_file=$(mktemp) +for man_path in $(find . -name '*.md' | + ${sed_ext} -e 's%^\./%%' | + grep -Ev '^(README.md$|(third_party|doc)/)'); do + # These should show up in all man pages, but probably not all together in any + # other Markdown documents. + if ! (grep -q '^## Name$' "${man_path}" && + grep -q '^## Synopsis$' "${man_path}" && + grep -q '^## Description$' "${man_path}"); then + continue + fi + + man_basename=$(${sed_ext} -e 's/\.md$//' <<< $(basename "${man_path}")) + cat >> "${list_file}" << __EOF__ +${man_basename} +__EOF__ +done + +maybe_mkdir "${output_dir}/man" + cd "${output_dir}/man" cat > index.html << __EOF__ @@ -62,18 +75,17 @@ cat > index.html << __EOF__
    __EOF__ -for html_file in *.html; do - if [[ "${html_file}" = "index.html" ]]; then - continue - fi - basename=$(${sed_ext} -e 's/\.html$//' <<< "${html_file}") +sort "${list_file}" | while read line; do + line=$(${sed_ext} -e 's/^//' <<< "${line}") cat >> index.html << __EOF__
  • - ${basename} +${line}
  • __EOF__ done +rm -f "${list_file}" + cat >> index.html << __EOF__
__EOF__ diff --git a/doc/support/generate_asciidoc.sh b/doc/support/generate_asciidoc.sh deleted file mode 100755 index 54a57349..00000000 --- a/doc/support/generate_asciidoc.sh +++ /dev/null @@ -1,111 +0,0 @@ -#!/bin/bash - -# 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. - -set -e - -# Generating AsciiDoc documentation requires AsciiDoc, -# http://www.methods.co.nz/asciidoc/. For “man” and PDF output, a DocBook -# toolchain including docbook-xml and docbook-xsl is also required. - -# Run from the Crashpad project root directory. -cd "$(dirname "${0}")/../.." - -source doc/support/compat.sh - -output_dir=out/doc - -rm -rf \ - "${output_dir}/doc" \ - "${output_dir}/man" -mkdir -p \ - "${output_dir}/doc/html" \ - "${output_dir}/man/html" \ - "${output_dir}/man/man" - -# Get the version from package.h. -version=$(${sed_ext} -n -e 's/^#define PACKAGE_VERSION "(.*)"$/\1/p' package.h) - -generate() { - input="$1" - type="$2" - - case "${type}" in - doc) - doctype="article" - ;; - man) - doctype="manpage" - ;; - *) - echo "${0}: unknown type ${type}" >& 2 - exit 1 - ;; - esac - - echo "${input}" - - base=$(${sed_ext} -e 's%^.*/([^/]+)\.ad$%\1%' <<< "${input}") - - # Get the last-modified date of $input according to Git, in UTC. - git_time_t="$(git log -1 --format=%at "${input}")" - git_date="$(LC_ALL=C ${date_time_t}"${git_time_t}" -u '+%B %-d, %Y')" - - # Create HTML output. - asciidoc \ - --attribute mansource=Crashpad \ - --attribute manversion="${version}" \ - --attribute manmanual="Crashpad Manual" \ - --attribute git_date="${git_date}" \ - --conf-file doc/support/asciidoc.conf \ - --doctype "${doctype}" \ - --backend html5 \ - --attribute stylesheet="${PWD}/doc/support/asciidoc.css" \ - --out-file "${output_dir}/${type}/html/${base}.html" \ - "${input}" - - if [[ "${type}" = "man" ]]; then - # Create “man” output. - # - # AsciiDoc 8.6.9 produces harmless incorrect warnings each time this is run: - # “a2x: WARNING: --destination-dir option is only applicable to HTML based - # outputs”. https://github.com/asciidoc/asciidoc/issues/44 - a2x \ - --attribute mansource=Crashpad \ - --attribute manversion="${version}" \ - --attribute manmanual="Crashpad Manual" \ - --attribute git_date="${git_date}" \ - --asciidoc-opts=--conf-file=doc/support/asciidoc.conf \ - --doctype "${doctype}" \ - --format manpage \ - --destination-dir "${output_dir}/${type}/man" \ - "${input}" - fi - - # For PDF output, use an a2x command like the one above, with these options: - # --format pdf --fop --destination-dir "${output_dir}/${type}/pdf" -} - -for input in \ - doc/*.ad; do - generate "${input}" "doc" -done - -for input in \ - handler/crashpad_handler.ad \ - tools/*.ad \ - tools/mac/*.ad; do - generate "${input}" "man" -done diff --git a/doc/support/man_footer.ad b/doc/support/man_footer.ad deleted file mode 100644 index 2dd84fcc..00000000 --- a/doc/support/man_footer.ad +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2014 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. - -== Resources - -Crashpad home page: https://crashpad.chromium.org/. - -Report bugs at https://crashpad.chromium.org/bug/new. - -== Copyright - -Copyright 2016 -https://chromium.googlesource.com/crashpad/crashpad/+/master/AUTHORS[The -Crashpad Authors]. - -== License - -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 - -[subs="macros"] - 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. diff --git a/handler/crashpad_handler.ad b/handler/crashpad_handler.ad deleted file mode 100644 index a4918d6f..00000000 --- a/handler/crashpad_handler.ad +++ /dev/null @@ -1,183 +0,0 @@ -// Copyright 2014 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. - -:doctype: manpage - -= crashpad_handler(8) - -== Name - -crashpad_handler - Crashpad’s exception handler server - -== Synopsis - -[verse] -*crashpad_handler* ['OPTION…'] - -== Description - -This program is Crashpad’s main exception-handling server. It is responsible for -catching exceptions, writing crash reports, and uploading them to a crash report -collection server. Uploads are disabled by default, and can only be enabled by a -Crashpad client using the Crashpad client library, typically in response to a -user requesting this behavior. - -On OS X, this server may be started by its initial client, in which case it -performs a handshake with this client via a pipe established by the client that -is inherited by the server, referenced by the *--handshake-fd* argument. During -the handshake, the server furnishes the client with a send right that the client -may use as an exception port. The server retains the corresponding receive -right, which it monitors for exception messages. When the receive right loses -all senders, the server exits after allowing any upload in progress to complete. - -Alternatively, on OS X, this server may be started from launchd(8), where it -receives the Mach service name in a *--mach-service* argument. It checks in with -the bootstrap server under this service name, and clients may look it up with -the bootstrap server under this service name. It monitors this service for -exception messages. Upon receipt of +SIGTERM+, the server exits after allowing -any upload in progress to complete. +SIGTERM+ is normally sent by launchd(8) -when it determines that the server should exit. - -On Windows, clients register with this server by communicating with it via the -named pipe identified by the *--pipe-name* argument. Alternatively, the server -can inherit an already-created pipe from a parent process by using the -*--initial-client-data* mechanism. That argument also takes all of the arguments -that would normally be passed in a registration message, and so constitutes -registration of the first client. Subsequent clients may then register by -communicating with the server via the pipe. During registration, a client -provides the server with an OS event object that it will signal should it crash. -The server obtains the client’s process handle and waits on the crash event -object for a crash, as well as the client’s process handle for the client to -exit cleanly without crashing. When a server started via the -*--initial-client-data* mechanism loses all of its clients, it exits after -allowing any upload in progress to complete. - -On Windows, this executable is built by default as a Windows GUI app, so no -console will appear in normal usage. This is the version that will typically be -used. A second copy is also made with a +.com+ extension, rather than +.exe+. In -this second copy, the PE header is modified to indicate that it's a console app. -This is useful because the +.com+ is found in the path before the +.exe+, so -when run normally from a shell using only the basename (without an explicit -+.com+ or +.exe+ extension), the +.com+ console version will be chosen, and so -stdio will be hooked up as expected to the parent console so that logging output -will be visible. - -It is not normally appropriate to invoke this program directly. Usually, it will -be invoked by a Crashpad client using the Crashpad client library, or started by -another system service. On OS X, arbitrary programs may be run with a Crashpad -handler by using man_link:run_with_crashpad[1] to establish the Crashpad client -environment before running a program. - -== Options -*--annotation*='KEY=VALUE':: -Sets a process-level annotation mapping 'KEY' to 'VALUE' in each crash report -that is written. This option may appear zero, one, or multiple times. -+ -Most annotations should be provided by the Crashpad client as module-level -annotations instead of process-level annotations. Module-level annotations are -more flexible in that they can be modified and cleared during the client -program’s lifetime. Module-level annotations can be set via the Crashpad client -library. Process-level annotations are useful for annotations that the -collection server requires be present, that have fixed values, and for cases -where a program that does not use the Crashpad client library is being -monitored. -+ -Breakpad-type collection servers only require the +"prod"+ and +"ver"+ -annotations, which should be set to the product name or identifier and product -version, respectively. It is unusual to specify other annotations as -process-level annotations via this argument. - -*--database*='PATH':: -Use 'PATH' as the path to the Crashpad crash report database. This option is -required. Crash reports are written to this database, and if uploads are -enabled, uploaded from this database to a crash report collection server. If the -database does not exist, it will be created, provided that the parent directory -of 'PATH' exists. - -*--handshake-fd*='FD':: -Perform the handshake with the initial client on the file descriptor at 'FD'. -Either this option or *--mach-service*, but not both, is required. This option -is only valid on OS X. - -*--initial-client-data*='HANDLE_request_crash_dump','HANDLE_request_non_crash_dump','HANDLE_non_crash_dump_completed','HANDLE_first_pipe_instance','HANDLE_client_process','Address_crash_exception_information','Address_non_crash_exception_information','Address_debug_critical_section':: -Register the initial client using the inherited handles and data provided. For -more information on the arguments, see the implementations of +CrashpadClient+ -and +ExceptionHandlerServer+. Either this option or *--pipe-name*, but not both, -is required. This option is only valid on Windows. -+ -When this option is present, the server creates a new named pipe at a random -name and informs its client of the name. The server waits for at least one -client to register, and exits when all clients have exited, after waiting for -any uploads in progress to complete. - -*--mach-service*='SERVICE':: -Check in with the bootstrap server under the name 'SERVICE'. Either this option -or *--handshake-fd*, but not both, is required. This option is only valid on OS -X. -+ -'SERVICE' may already be reserved with the bootstrap server in cases where this -tool is started by launchd(8) as a result of a message being sent to a service -declared in a job’s +MachServices+ dictionary (see launchd.plist(5)). The -service name may also be completely unknown to the system. - -*--no-rate-limit*:: -Do not rate limit the upload of crash reports. By default uploads are throttled -to one per hour. Using this option disables that behavior, and Crashpad will -attempt to upload all captured reports. - -*--pipe-name*='PIPE':: -Listen on the given pipe name for connections from clients. 'PIPE' must be of -the form +\\.\pipe\+. Either this option or *--initial-client-data*, -but not both, is required. This option is only valid on Windows. -+ -When this option is present, the server creates a named pipe at 'PIPE', a name -known to both the server and its clients. The server continues running even -after all clients have exited. - -*--reset-own-crash-exception-port-to-system-default*:: -Causes the exception handler server to set its own crash handler to the system -default before beginning operation. This is only expected to be useful in cases -where the server inherits an inappropriate crash handler from its parent -process. This option is only valid on OS X. Use of this option is discouraged. -It should not be used absent extraordinary circumstances. - -*--url*='URL':: -If uploads are enabled, sends crash reports to the Breakpad-type crash report -collection server at 'URL'. Uploads are disabled by default, and can only be -enabled for a database by a Crashpad client using the Crashpad client library, -typically in response to a user requesting this behavior. If this option is not -specified, this program will behave as if uploads are disabled. - -*--help*:: -Display help and exit. - -*--version*:: -Output version information and exit. - -== Exit Status - -*0*:: -Success. - -*1*:: -Failure, with a message printed to the standard error stream. - -== See Also - -man_link:catch_exception_tool[1], -man_link:crashpad_database_util[1], -man_link:generate_dump[1], -man_link:run_with_crashpad[1] - -include::../doc/support/man_footer.ad[] diff --git a/handler/crashpad_handler.md b/handler/crashpad_handler.md new file mode 100644 index 00000000..914d7be4 --- /dev/null +++ b/handler/crashpad_handler.md @@ -0,0 +1,223 @@ + + +# crashpad_handler(8) + +## Name + +crashpad_handler—Crashpad’s exception handler server + +## Synopsis + +**crashpad_handler** [_OPTION…_] + +## Description + +This program is Crashpad’s main exception-handling server. It is responsible for +catching exceptions, writing crash reports, and uploading them to a crash report +collection server. Uploads are disabled by default, and can only be enabled by a +Crashpad client using the Crashpad client library, typically in response to a +user requesting this behavior. + +On macOS, this server may be started by its initial client, in which case it +performs a handshake with this client via a pipe established by the client that +is inherited by the server, referenced by the **--handshake-fd** argument. +During the handshake, the server furnishes the client with a send right that the +client may use as an exception port. The server retains the corresponding +receive right, which it monitors for exception messages. When the receive right +loses all senders, the server exits after allowing any upload in progress to +complete. + +Alternatively, on macOS, this server may be started from launchd(8), where it +receives the Mach service name in a **--mach-service** argument. It checks in +with the bootstrap server under this service name, and clients may look it up +with the bootstrap server under this service name. It monitors this service for +exception messages. Upon receipt of `SIGTERM`, the server exits after allowing +any upload in progress to complete. `SIGTERM` is normally sent by launchd(8) +when it determines that the server should exit. + +On Windows, clients register with this server by communicating with it via the +named pipe identified by the **--pipe-name** argument. Alternatively, the server +can inherit an already-created pipe from a parent process by using the +**--initial-client-data** mechanism. That argument also takes all of the +arguments that would normally be passed in a registration message, and so +constitutes registration of the first client. Subsequent clients may then +register by communicating with the server via the pipe. During registration, a +client provides the server with an OS event object that it will signal should it +crash. The server obtains the client’s process handle and waits on the crash +event object for a crash, as well as the client’s process handle for the client +to exit cleanly without crashing. When a server started via the +**--initial-client-data** mechanism loses all of its clients, it exits after +allowing any upload in progress to complete. + +On Windows, this executable is built by default as a Windows GUI app, so no +console will appear in normal usage. This is the version that will typically be +used. A second copy is also made with a `.com` extension, rather than `.exe`. In +this second copy, the PE header is modified to indicate that it's a console app. +This is useful because the `.com` is found in the path before the `.exe`, so +when run normally from a shell using only the basename (without an explicit +`.com` or `.exe` extension), the `.com` console version will be chosen, and so +stdio will be hooked up as expected to the parent console so that logging output +will be visible. + +It is not normally appropriate to invoke this program directly. Usually, it will +be invoked by a Crashpad client using the Crashpad client library, or started by +another system service. On macOS, arbitrary programs may be run with a Crashpad +handler by using [run_with_crashpad(1)](../tools/mac/run_with_crashpad.md) to +establish the Crashpad client environment before running a program. + +## Options + + * **--annotation**=_KEY_=_VALUE_ + + Sets a process-level annotation mapping _KEY_ to _VALUE_ in each crash report + that is written. This option may appear zero, one, or multiple times. + + Most annotations should be provided by the Crashpad client as module-level + annotations instead of process-level annotations. Module-level annotations + are more flexible in that they can be modified and cleared during the client + program’s lifetime. Module-level annotations can be set via the Crashpad + client library. Process-level annotations are useful for annotations that the + collection server requires be present, that have fixed values, and for cases + where a program that does not use the Crashpad client library is being + monitored. + + Breakpad-type collection servers only require the `"prod"` and `"ver"` + annotations, which should be set to the product name or identifier and + product version, respectively. It is unusual to specify other annotations as + process-level annotations via this argument. + + * **--database**=_PATH_ + + Use _PATH_ as the path to the Crashpad crash report database. This option is + required. Crash reports are written to this database, and if uploads are + enabled, uploaded from this database to a crash report collection server. If + the database does not exist, it will be created, provided that the parent + directory of _PATH_ exists. + + * **--handshake-fd**=_FD_ + + Perform the handshake with the initial client on the file descriptor at _FD_. + Either this option or **--mach-service**, but not both, is required. This + option is only valid on macOS. + + * **--initial-client-data**=*HANDLE_request_crash_dump*, +*HANDLE_request_non_crash_dump_*,*HANDLE_non_crash_dump_completed*,*HANDLE_first_pipe_instance*,*HANDLE_client_process*,*Address_crash_exception_information*,*Address_non_crash_exception_information*,*Address_debug_critical_section* + + Register the initial client using the inherited handles and data provided. + For more information on the arguments, see the implementations of + `CrashpadClient` and `ExceptionHandlerServer`. Either this option or + **--pipe-name**, but not both, is required. This option is only valid on + Windows. + + When this option is present, the server creates a new named pipe at a random + name and informs its client of the name. The server waits for at least one + client to register, and exits when all clients have exited, after waiting for + any uploads in progress to complete. + + * **--mach-service**=_SERVICE_ + + Check in with the bootstrap server under the name _SERVICE_. Either this + option or **--handshake-fd**, but not both, is required. This option is only + valid on macOS. + + _SERVICE_ may already be reserved with the bootstrap server in cases where + this tool is started by launchd(8) as a result of a message being sent to a + service declared in a job’s `MachServices` dictionary (see launchd.plist(5)). + The service name may also be completely unknown to the system. + + * **--no-rate-limit** + + Do not rate limit the upload of crash reports. By default uploads are + throttled to one per hour. Using this option disables that behavior, and + Crashpad will attempt to upload all captured reports. + + * **--pipe-name**=_PIPE_ + + Listen on the given pipe name for connections from clients. _PIPE_ must be of + the form `\\.\pipe\`. Either this option or + **--initial-client-data**, but not both, is required. This option is only + valid on Windows. + + When this option is present, the server creates a named pipe at _PIPE_, a + name known to both the server and its clients. The server continues running + even after all clients have exited. + + * **--reset-own-crash-exception-port-to-system-default** + + Causes the exception handler server to set its own crash handler to the + system default before beginning operation. This is only expected to be useful + in cases where the server inherits an inappropriate crash handler from its + parent process. This option is only valid on macOS. Use of this option is + discouraged. It should not be used absent extraordinary circumstances. + + * **--url**=_URL_ + + If uploads are enabled, sends crash reports to the Breakpad-type crash report + collection server at _URL_. Uploads are disabled by default, and can only be + enabled for a database by a Crashpad client using the Crashpad client + library, typically in response to a user requesting this behavior. If this + option is not specified, this program will behave as if uploads are disabled. + + * **--help** + + Display help and exit. + + * **--version** + + Output version information and exit. + +## Exit Status + + * **0** + + Success. + + * **1** + + Failure, with a message printed to the standard error stream. + +## See Also + +[catch_exception_tool(1)](../tools/mac/catch_exception_tool.md), +[crashpad_database_util(1)](../tools/crashpad_database_util.md), +[generate_dump(1)](../tools/generate_dump.md), +[run_with_crashpad(1)](../tools/mac/run_with_crashpad.md) + +## Resources + +Crashpad home page: https://crashpad.chromium.org/. + +Report bugs at https://crashpad.chromium.org/bug/new. + +## Copyright + +Copyright 2014 [The Crashpad +Authors](https://chromium.googlesource.com/crashpad/crashpad/+/master/AUTHORS). + +## License + +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. diff --git a/navbar.md b/navbar.md new file mode 100644 index 00000000..e3c3d97b --- /dev/null +++ b/navbar.md @@ -0,0 +1,21 @@ + + +* [Home](/README.md) +* [Developing](/doc/developing.md) +* [Doxygen](https://crashpad.chromium.org/doxygen/) +* [Man Pages](https://crashpad.chromium.org/man/) +* [Source Code](https://chromium.googlesource.com/crashpad/crashpad/) diff --git a/tools/crashpad_database_util.ad b/tools/crashpad_database_util.ad deleted file mode 100644 index 78107ee3..00000000 --- a/tools/crashpad_database_util.ad +++ /dev/null @@ -1,163 +0,0 @@ -// 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. - -:doctype: manpage - -= crashpad_database_util(1) - -== Name - -crashpad_database_util - Operate on Crashpad crash report databases - -== Synopsis - -[verse] -*crashpad_database_util* ['OPTION…'] - -== Description - -Operates on Crashpad crash report databases. The database’s settings can be -queried and modified, and information about crash reports stored in the -database can be displayed. - -When this program is requested to both show and set information in a single -invocation, all “show” operations will be completed prior to beginning any “set” -operation. - -Programs that use the Crashpad client library directly will not normally use -this tool, but may use the database through the programmatic interfaces in the -client library. This tool exists to allow developers to manipulate a Crashpad -database. - -== Options -*--create*:: -Creates the database identified by *--database* if it does not exist, provided -that the parent directory of 'PATH' exists. - -*-d*, *--database*='PATH':: -Use 'PATH' as the path to the Crashpad crash report database. This option is -required. The database must already exist unless *--create* is also specified. - -*--show-client-id*:: -Show the client ID stored in the database’s settings. The client ID is formatted -as a UUID. The client ID is set when the database is created. -man_link:crashpad_handler[8] retrieves the client ID and stores it in crash -reports as they are written. - -*--show-uploads-enabled*:: -Show the status of the uploads-enabled bit stored in the database’s settings. -man_link:crashpad_handler[8] does not upload reports when this bit is false. -This bit is false when a database is created, and is under an application’s -control via the Crashpad client library interface. -+ -See also *--set-uploads-enabled*. - -*--show-last-upload-attempt-time*:: -Show the last-upload-attempt time stored in the database’s settings. This value -is +0+, meaning “never,” when the database is created. -man_link:crashpad_handler[8] consults this value before attempting an upload to -implement its rate-limiting behavior. The database updates this value whenever -an upload is attempted. -+ -See also *--set-last-upload-attempt-time*. - -*--show-pending-reports*:: -Show reports eligible for upload. - -*--show-completed-reports*:: -Show reports not eligible for upload. A report is moved from the “pending” state -to the “completed” state by man_link:crashpad_handler[8]. This may happen when a -report is successfully uploaded, when a report is not uploaded because uploads -are disabled, or when a report upload attempt fails and will not be retried. - -*--show-all-report-info*:: -With *--show-pending-reports* or *--show-completed-reports*, show all metadata -for each report displayed. Without this option, only report IDs will be shown. - -*--show-report*='UUID':: -Show a report from the database looked up by its identifier, 'UUID', which must -be formatted in string representation per RFC 4122 §3. All metadata for each -report found via a *--show-report* option will be shown. If 'UUID' is not found, -the string +"not found"+ will be printed. If this program is only requested to -show a single report and it is not found, it will treat this as a failure for -the purposes of determining its exit status. This option may appear multiple -times. - -*--set-report-uploads-enabled*='BOOL':: -Enable or disable report upload in the database’s settings. 'BOOL' is a string -representation of a boolean value, such as +"0"+ or +"true"+. -+ -See also *--show-uploads-enabled*. - -*--set-last-upload-attempt-time*='TIME':: -Set the last-upload-attempt time in the database’s settings. 'TIME' is a string -representation of a time, which may be in 'yyyy-mm-dd hh:mm:ss' format, a -numeric +time_t+ value, or the special string +"never"+. -+ -See also *--show-last-upload-attempt-time*. - -*--new-report*='PATH':: -Submit a new report located at 'PATH' to the database. If 'PATH' is +"-"+, the -new report will be read from standard input. The new report will be in the -“pending” state. The UUID assigned to the new report will be printed. This -option may appear multiple times. - -*--utc*:: -When showing times, do so in UTC as opposed to the local time zone. When setting -times, interpret ambiguous time strings in UTC as opposed to the local time -zone. - -*--help*:: -Display help and exit. - -*--version*:: -Output version information and exit. - -== Examples - -Shows all crash reports in a crash report database that are in the “completed” -state. -[subs="quotes"] ----- -$ *crashpad_database_util --database /tmp/crashpad_database \ - --show-completed-reports* -23f9512b-63e1-4ead-9dcd-e2e21fbccc68 -4bfca440-039f-4bc6-bbd4-6933cef5efd4 -56caeff8-b61a-43b2-832d-9e796e6e4a50 ----- - -Disables report upload in a crash report database’s settings, and then verifies -that the change was made. -[subs="quotes"] ----- -$ *crashpad_database_util --database /tmp/crashpad_database \ - --set-uploads-enabled false* -$ *crashpad_database_util --database /tmp/crashpad_database \ - --show-uploads-enabled* -false ----- - -== Exit Status - -*0*:: -Success. - -*1*:: -Failure, with a message printed to the standard error stream. - -== See Also - -man_link:crashpad_handler[8] - -include::../doc/support/man_footer.ad[] diff --git a/tools/crashpad_database_util.md b/tools/crashpad_database_util.md new file mode 100644 index 00000000..610731dd --- /dev/null +++ b/tools/crashpad_database_util.md @@ -0,0 +1,207 @@ + + +# crashpad_database_util(1) + +## Name + +crashpad_database_util—Operate on Crashpad crash report databases + +## Synopsis + +**crashpad_database_util** [_OPTION…_] + +## Description + +Operates on Crashpad crash report databases. The database’s settings can be +queried and modified, and information about crash reports stored in the database +can be displayed. + +When this program is requested to both show and set information in a single +invocation, all “show” operations will be completed prior to beginning any “set” +operation. + +Programs that use the Crashpad client library directly will not normally use +this tool, but may use the database through the programmatic interfaces in the +client library. This tool exists to allow developers to manipulate a Crashpad +database. + +## Options + + * **--create** + + Creates the database identified by **--database** if it does not exist, + provided that the parent directory of _PATH_ exists. + + * **-d**, **--database**=_PATH_ + + Use _PATH_ as the path to the Crashpad crash report database. This option is + required. The database must already exist unless **--create** is also + specified. + + * **--show-client-id** + + Show the client ID stored in the database’s settings. The client ID is + formatted as a UUID. The client ID is set when the database is created. + [crashpad_handler(8)](../handler/crashpad_handler.md) retrieves the client ID + and stores it in crash reports as they are written. + + * **--show-uploads-enabled** + + Show the status of the uploads-enabled bit stored in the database’s settings. + [crashpad_handler(8)](../handler/crashpad_handler.md) does not upload reports + when this bit is false. This bit is false when a database is created, and is + under an application’s control via the Crashpad client library interface. + + See also **--set-uploads-enabled**. + + * **--show-last-upload-attempt-time** + + Show the last-upload-attempt time stored in the database’s settings. This + value is `0`, meaning “never,” when the database is created. + [crashpad_handler(8)](../handler/crashpad_handler.md) consults this value + before attempting an upload to implement its rate-limiting behavior. The + database updates this value whenever an upload is attempted. + + See also **--set-last-upload-attempt-time**. + + * **--show-pending-reports** + + Show reports eligible for upload. + + * **--show-completed-reports** + + Show reports not eligible for upload. A report is moved from the “pending” + state to the “completed” state by + [crashpad_handler(8)](../handler/crashpad_handler.md). This may happen when a + report is successfully uploaded, when a report is not uploaded because + uploads are disabled, or when a report upload attempt fails and will not be + retried. + + * **--show-all-report-info** + + With **--show-pending-reports** or **--show-completed-reports**, show all + metadata for each report displayed. Without this option, only report IDs will + be shown. + + * **--show-report**=_UUID_ + + Show a report from the database looked up by its identifier, _UUID_, which + must be formatted in string representation per RFC 4122 §3. All metadata for + each report found via a **--show-report** option will be shown. If _UUID_ is + not found, the string `"not found"` will be printed. If this program is only + requested to show a single report and it is not found, it will treat this as + a failure for the purposes of determining its exit status. This option may + appear multiple times. + + * **--set-report-uploads-enabled**=_BOOL_ + + Enable or disable report upload in the database’s settings. _BOOL_ is a + string representation of a boolean value, such as `"0"` or `"true"`. + + See also **--show-uploads-enabled**. + + * **--set-last-upload-attempt-time**=_TIME_ + + Set the last-upload-attempt time in the database’s settings. _TIME_ is a + string representation of a time, which may be in _yyyy-mm-dd hh:mm:ss_ + format, a numeric `time_t` value, or the special string `"never"`. + + See also **--show-last-upload-attempt-time**. + + * **--new-report**=_PATH_ + + Submit a new report located at _PATH_ to the database. If _PATH_ is `"-"`, + the new report will be read from standard input. The new report will be in + the “pending” state. The UUID assigned to the new report will be printed. + This option may appear multiple times. + + * **--utc** + + When showing times, do so in UTC as opposed to the local time zone. When + setting times, interpret ambiguous time strings in UTC as opposed to the + local time zone. + + * **--help** + + Display help and exit. + + * **--version** + + Output version information and exit. + +## Examples + +Shows all crash reports in a crash report database that are in the “completed” +state. + +``` +$ crashpad_database_util --database /tmp/crashpad_database \ + --show-completed-reports +23f9512b-63e1-4ead-9dcd-e2e21fbccc68 +4bfca440-039f-4bc6-bbd4-6933cef5efd4 +56caeff8-b61a-43b2-832d-9e796e6e4a50 +``` + +Disables report upload in a crash report database’s settings, and then verifies +that the change was made. + +``` +$ crashpad_database_util --database /tmp/crashpad_database \ + --set-uploads-enabled false +$ crashpad_database_util --database /tmp/crashpad_database \ + --show-uploads-enabled +false +``` + +## Exit Status + + * **0** + + Success. + + * **1** + + Failure, with a message printed to the standard error stream. + +## See Also + +[crashpad_handler(8)](../handler/crashpad_handler.md) + +## Resources + +Crashpad home page: https://crashpad.chromium.org/. + +Report bugs at https://crashpad.chromium.org/bug/new. + +## Copyright + +Copyright 2015 [The Crashpad +Authors](https://chromium.googlesource.com/crashpad/crashpad/+/master/AUTHORS). + +## License + +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. diff --git a/tools/generate_dump.ad b/tools/generate_dump.ad deleted file mode 100644 index d8a53c8d..00000000 --- a/tools/generate_dump.ad +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright 2014 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. - -:doctype: manpage - -= generate_dump(1) - -== Name - -generate_dump - Generate a minidump file containing a snapshot of a running -process - -== Synopsis - -[verse] -*generate_dump* ['OPTION…'] 'PID' - -== Description - -Generates a minidump file containing a snapshot of a running process whose -process identifier is 'PID'. By default, the target process will be suspended -while the minidump is generated, and the minidump file will be written to -+minidump.PID+. After the minidump file is generated, the target process resumes -running. - -The minidump file will contain information about the process, its threads, its -modules, and the system. It will not contain any exception information because -it will be generated from a live running process, not as a result of an -exception occurring. - -This program uses +task_for_pid()+ to access the process’ task port. This -operation may be restricted to use by the superuser, executables signed by an -authority trusted by the system, and processes otherwise permitted by -taskgated(8). Consequently, this program must normally either be signed or be -invoked by root. It is possible to install this program as a setuid root -executable to overcome this limitation. - -This program is similar to the gcore(1) program available on some operating -systems. - -== Options - -*-r*, *--no-suspend*:: -The target process will continue running while the minidump file is generated. -Normally, the target process is suspended during this operation, which -guarantees that the minidump file will contain an atomic snapshot of the -process. -+ -This option may be useful when attempting to generate a minidump from a process -that dump generation has an interprocess dependency on, such as a system server -like launchd(8) or opendirectoryd(8). Deadlock could occur if any portion of the -dump generation operation blocks while waiting for a response from one of these -servers while they are suspended. - -*-o*, *--output*='FILE':: -The minidump will be written to 'FILE' instead of +minidump.PID+. - -*--help*:: -Display help and exit. - -*--version*:: -Output version information and exit. - -== Examples - -Generate a minidump file in +/tmp/minidump+ containing a snapshot of the process -with PID 1234. -[subs="quotes"] ----- -$ *generate_dump --output=/tmp/minidump 1234* ----- - -== Exit Status - -*0*:: -Success. - -*1*:: -Failure, with a message printed to the standard error stream. - -== See Also - -man_link:catch_exception_tool[1] - -include::../doc/support/man_footer.ad[] diff --git a/tools/generate_dump.md b/tools/generate_dump.md new file mode 100644 index 00000000..c58ecbc3 --- /dev/null +++ b/tools/generate_dump.md @@ -0,0 +1,127 @@ + + +# generate_dump(1) + +## Name + +generate_dump—Generate a minidump file containing a snapshot of a running +process + +## Synopsis + +**generate_dump** [_OPTION…_] _PID_ + +## Description + +Generates a minidump file containing a snapshot of a running process whose +process identifier is _PID_. By default, the target process will be suspended +while the minidump is generated, and the minidump file will be written to +`minidump.PID`. After the minidump file is generated, the target process resumes +running. + +The minidump file will contain information about the process, its threads, its +modules, and the system. It will not contain any exception information because +it will be generated from a live running process, not as a result of an +exception occurring. + +On macOS, this program uses `task_for_pid()` to access the process’ task port. +This operation may be restricted to use by the superuser, executables signed by +an authority trusted by the system, and processes otherwise permitted by +taskgated(8). Consequently, this program must normally either be signed or be +invoked by root. It is possible to install this program as a setuid root +executable to overcome this limitation, although it will remain impossible to +generate dumps for processes protected by [System Integrity Protection +(SIP)](https://support.apple.com/HT204899), including those whose “restrict” +codesign(1) option is respected. + +This program is similar to the gcore(1) program available on some operating +systems. + +## Options + + * **-r**, **--no-suspend** + + The target process will continue running while the minidump file is + generated. Normally, the target process is suspended during this operation, + which guarantees that the minidump file will contain an atomic snapshot of + the process. + + This option may be useful when attempting to generate a minidump from a + process that dump generation has an interprocess dependency on, such as a + system server like launchd(8) or opendirectoryd(8) on macOS. Deadlock could + occur if any portion of the dump generation operation blocks while waiting + for a response from one of these servers while they are suspended. + + * **-o**, **--output**=_FILE_ + + The minidump will be written to _FILE_ instead of `minidump.PID`. + + * **--help** + + Display help and exit. + + * **--version** + + Output version information and exit. + +## Examples + +Generate a minidump file in `/tmp/minidump` containing a snapshot of the process +with PID 1234. + +``` +$ generate_dump --output=/tmp/minidump 1234 +``` + +## Exit Status + + * **0** + + Success. + + * **1** + + Failure, with a message printed to the standard error stream. + +## See Also + +[catch_exception_tool(1)](mac/catch_exception_tool.md) + +## Resources + +Crashpad home page: https://crashpad.chromium.org/. + +Report bugs at https://crashpad.chromium.org/bug/new. + +## Copyright + +Copyright 2014 [The Crashpad +Authors](https://chromium.googlesource.com/crashpad/crashpad/+/master/AUTHORS). + +## License + +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. diff --git a/tools/mac/catch_exception_tool.ad b/tools/mac/catch_exception_tool.ad deleted file mode 100644 index a639de4c..00000000 --- a/tools/mac/catch_exception_tool.ad +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright 2014 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. - -:doctype: manpage - -= catch_exception_tool(1) - -== Name - -catch_exception_tool - Catch Mach exceptions and display information about them - -== Synopsis - -[verse] -*catch_exception_tool* *-m* 'SERVICE' ['OPTION…'] - -== Description - -Runs a Mach exception server registered with the bootstrap server under the name -'SERVICE'. The exception server is capable of receiving exceptions for -“behavior” values of +EXCEPTION_DEFAULT+, +EXCEPTION_STATE+, and -+EXCEPTION_STATE_IDENTITY+, with or without +MACH_EXCEPTION_CODES+ set. - -== Options - -*-f*, *--file*='FILE':: -Information about the exception will be appended to 'FILE' instead of the -standard output stream. - -*-m*, *--mach-service*='SERVICE':: -Check in with the bootstrap server under the name 'SERVICE'. This service name -may already be reserved with the bootstrap server in cases where this tool is -started by launchd(8) as a result of a message being sent to a service declared -in a job’s +MachServices+ dictionary (see launchd.plist(5)). The service name -may also be completely unknown to the system. - -*-p*, *--persistent*:: -Continue processing exceptions after the first one. The default mode is -one-shot, where this tool exits after processing the first exception. - -*-t*, *--timeout*='TIMEOUT':: -Run for a maximum of 'TIMEOUT' seconds. Specify +0+ to request non-blocking -operation, in which the tool exits immediately if no exception is received. In -*--persistent* mode, 'TIMEOUT' applies to the overall duration that this tool -will run, not to the processing of individual exceptions. When *--timeout* is -not specified, this tool will block indefinitely while waiting for an exception. - -*--help*:: -Display help and exit. - -*--version*:: -Output version information and exit. - -== Examples - -Run a one-shot blocking exception server registered with the bootstrap server -under the name +svc+: -[subs="quotes"] ----- -$ *catch_exception_tool --mach-service=svc --file=out &* -[1] 1233 -$ *exception_port_tool --set-handler=handler=bootstrap:svc crasher* -Illegal instruction: 4 -[1]+ Done catch_exception_tool --mach-service=svc --file=out -$ *cat out* -catch_exception_tool: -behavior EXCEPTION_DEFAULT|MACH_EXCEPTION_CODES, -pid 1234, thread 56789, exception EXC_CRASH, codes[2] 0x4200001, 0, -original exception EXC_BAD_INSTRUCTION, original code[0] 1, -signal SIGILL ----- - -Run an on-demand exception server started by launchd(5) available via the -bootstrap server under the name +svc+: -[subs="quotes"] ----- -$ *on_demand_service_tool --load --label=catch_exception \ - --mach-service=svc \ - $(which catch_exception_tool) --mach-service=svc \ - --file=/tmp/out --persistent --timeout=0* -$ *exception_port_tool --set-handler=handler=bootstrap:svc crasher* -Illegal instruction: 4 -$ *on_demand_service_tool --unload --label=catch_exception* -$ *cat /tmp/out* -catch_exception_tool: -behavior EXCEPTION_DEFAULT|MACH_EXCEPTION_CODES, -pid 2468, thread 13579, exception EXC_CRASH, codes[2] 0x4200001, 0, -original exception EXC_BAD_INSTRUCTION, original code[0] 1, -signal SIGILL ----- - -== Exit Status - -*0*:: -Success. In *--persistent* mode with a *--timeout* set, it is considered -successful if at least one exception was caught when the timer expires. - -*1*:: -Failure, with a message printed to the standard error stream. - -== See Also - -man_link:exception_port_tool[1], -man_link:on_demand_service_tool[1] - -include::../../doc/support/man_footer.ad[] diff --git a/tools/mac/catch_exception_tool.md b/tools/mac/catch_exception_tool.md new file mode 100644 index 00000000..fc357dc6 --- /dev/null +++ b/tools/mac/catch_exception_tool.md @@ -0,0 +1,140 @@ + + +# catch_exception_tool(1) + +## Name + +catch_exception_tool—Catch Mach exceptions and display information about them + +## Synopsis + +**catch_exception_tool** **-m** _SERVICE_ [_OPTION…_] + +## Description + +Runs a Mach exception server registered with the bootstrap server under the name +_SERVICE_. The exception server is capable of receiving exceptions for +“behavior” values of `EXCEPTION_DEFAULT`, `EXCEPTION_STATE`, and +`EXCEPTION_STATE_IDENTITY`, with or without `MACH_EXCEPTION_CODES` set. + +## Options + + * **-f**, **--file**=_FILE_ + + Information about the exception will be appended to _FILE_ instead of the + standard output stream. + + * **-m**, **--mach-service**=_SERVICE_ + + Check in with the bootstrap server under the name _SERVICE_. This service + name may already be reserved with the bootstrap server in cases where this + tool is started by launchd(8) as a result of a message being sent to a + service declared in a job’s `MachServices` dictionary (see launchd.plist(5)). + The service name may also be completely unknown to the system. + + * **-p**, **--persistent** + + Continue processing exceptions after the first one. The default mode is + one-shot, where this tool exits after processing the first exception. + + * **-t**, **--timeout**=_TIMEOUT_ + + Run for a maximum of _TIMEOUT_ seconds. Specify `0` to request non-blocking + operation, in which the tool exits immediately if no exception is received. + In **--persistent** mode, _TIMEOUT_ applies to the overall duration that this + tool will run, not to the processing of individual exceptions. When + **--timeout** is not specified, this tool will block indefinitely while + waiting for an exception. + + * **--help** + + Display help and exit. + + * **--version** + + Output version information and exit. + +## Examples + +Run a one-shot blocking exception server registered with the bootstrap server +under the name `svc`: + +``` +$ catch_exception_tool --mach-service=svc --file=out & +[1] 1233 +$ exception_port_tool --set-handler=handler=bootstrap:svc crasher +Illegal instruction: 4 +[1]+ Done catch_exception_tool --mach-service=svc --file=out +$ cat out +catch_exception_tool: behavior EXCEPTION_DEFAULT|MACH_EXCEPTION_CODES, pid 1234, thread 56789, exception EXC_CRASH, codes[2] 0x4200001, 0, original exception EXC_BAD_INSTRUCTION, original code[0] 1, signal SIGILL +``` + +Run an on-demand exception server started by launchd(5) available via the +bootstrap server under the name `svc`: + +``` +$ `on_demand_service_tool --load --label=catch_exception \ + --mach-service=svc \ + $(which catch_exception_tool) --mach-service=svc \ + --file=/tmp/out --persistent --timeout=0 +$ exception_port_tool --set-handler=handler=bootstrap:svc crasher +Illegal instruction: 4 +$ on_demand_service_tool --unload --label=catch_exception +$ cat /tmp/out +catch_exception_tool: behavior EXCEPTION_DEFAULT|MACH_EXCEPTION_CODES, pid 2468, thread 13579, exception EXC_CRASH, codes[2] 0x4200001, 0, original exception EXC_BAD_INSTRUCTION, original code[0] 1, signal SIGILL +``` + +## Exit Status + + * **0** + + Success. In **--persistent** mode with a **--timeout** set, it is considered + successful if at least one exception was caught when the timer expires. + + * **1** + + Failure, with a message printed to the standard error stream. + +## See Also + +[exception_port_tool(1)](exception_port_tool.md), +[exception_port_tool(1)](on_demand_service_tool.md) + +## Resources + +Crashpad home page: https://crashpad.chromium.org/. + +Report bugs at https://crashpad.chromium.org/bug/new. + +## Copyright + +Copyright 2014 [The Crashpad +Authors](https://chromium.googlesource.com/crashpad/crashpad/+/master/AUTHORS). + +## License + +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. diff --git a/tools/mac/exception_port_tool.ad b/tools/mac/exception_port_tool.ad deleted file mode 100644 index e102cc00..00000000 --- a/tools/mac/exception_port_tool.ad +++ /dev/null @@ -1,188 +0,0 @@ -// Copyright 2014 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. - -:doctype: manpage - -= exception_port_tool(1) - -== Name - -exception_port_tool - Show and change Mach exception ports - -== Synopsis - -[verse] -*exception_port_tool* ['OPTION…'] ['COMMAND' ['ARG…']] - -== Description - -Shows Mach exception ports registered for a thread, task, or host target with a -*--show-** option, changes Mach exception ports with *--set-handler*, shows -changes with a *--show-new-** option, and executes 'COMMAND' along with any -arguments specified ('ARG…') with the changed exception ports in effect. - -== Options -*-s*, *--set-handler*='DESCRIPTION':: -Set an exception port to 'DESCRIPTION'. This option may appear zero, one, or -more times. -+ -'DESCRIPTION' is formatted as a comma-separated sequence of tokens, where each -token consists of a key and value separated by an equals sign. These keys are -recognized: -+ -*target*='TARGET'::: -'TARGET' defines which target’s exception ports to set: *host*, *task*, or -*thread*. The default value of 'TARGET' is *task*. Operations on *host* are -restricted to the superuser. -+ -*mask*='MASK'::: -'MASK' defines the mask of exception types to handle, from -++. This can be *BAD_ACCESS*, *BAD_INSTRUCTION*, -*ARITHMETIC*, *EMULATION*, *SOFTWARE*, *BREAKPOINT*, *SYSCALL*, *MACH_SYSCALL*, -*RPC_ALERT*, *CRASH*, *RESOURCE*, *GUARD*, or *CORPSE_NOTIFY*. Different -exception types may be combined by combining them with pipe characters (*|*). -The special value *ALL* includes each exception type except for *CRASH*. To -truly specify all exception types including *CRASH*, use *ALL|CRASH*. The -default value of 'MASK' is *CRASH*. -+ -*behavior*='BEHAVIOR'::: -'BEHAVIOR' defines the specific exception handler routine to be called when an -exception occurs. This can be *DEFAULT*, *STATE*, or *STATE_IDENTITY*. *MACH* -may also be specified by combining them with pipe characters (*|*). The most -complete set of exception information is provided with *STATE_IDENTITY|MACH*. -Not all exception servers implement all possible behaviors. The default value of -'BEHAVIOR' is *DEFAULT|MACH*. -+ -*flavor*='FLAVOR'::: -For state-carrying values of 'BEHAVIOR' (those including *STATE* or -*STATE_IDENTITY*), 'FLAVOR' specifies the architecture-specific thread state -flavor to be provided to the exception handler. For the x86 family, this can be -*THREAD*, *THREAD32*, *THREAD64*, *FLOAT*, *FLOAT32*, *FLOAT64*, *DEBUG*, -*DEBUG32*, or *DEBUG64*. The default value of 'FLAVOR' is *NONE*, which is not -valid for state-carrying values of 'BEHAVIOR'. -+ -*handler*='HANDLER'::: -'HANDLER' defines the exception handler. *NULL* indicates that any existing -exception port should be cleared. 'HANDLER' may also take the form -*bootstrap*:__SERVICE__, which will look 'SERVICE' up with the bootstrap server -and set that service as the exception handler. The default value of 'HANDLER' is -*NULL*. - -*--show-bootstrap*='SERVICE':: -Looks up 'SERVICE' with the bootstrap server and shows it. Normally, the handler -port values displayed by the other *--show-** options are meaningless -handles, but by comparing them to the port values for known bootstrap services, -it is possible to verify that they are set as intended. - -*-p*, *--pid*='PID':: -For operations on the task target, including *--set-handler* with 'TARGET' set -to *task*, *--show-task*, and *--show-new-task*, operates on the task associated -with process id 'PID' instead of the current task associated with the tool. When -this option is supplied, 'COMMAND' must not be specified. -+ -This option uses +task_for_pid()+ to access the process’ task port. This -operation may be restricted to use by the superuser, executables signed by an -authority trusted by the system, and processes otherwise permitted by -taskgated(8). Consequently, this program must normally either be signed or be -invoked by root to use this option. It is possible to install this program as a -setuid root executable to overcome this limitation. - -*-h*, *--show-host*:: -Shows the original host exception ports before making any changes requested by -*--set-handler*. This option is restricted to the superuser. - -*-t*, *--show-task*:: -Shows the original task exception ports before making any changes requested by -*--set-handler*. - -*--show-thread*:: -Shows the original thread exception ports before making any changes requested by -*--set-handler*. - -*-H*, *--show-new-host*:: -Shows the modified host exception ports after making any changes requested by -*--set-handler*. This option is restricted to the superuser. - -*-T*, *--show-new-task*:: -Shows the modified task exception ports after making any changes requested by -*--set-handler*. - -*--show-new-thread*:: -Shows the modified thread exception ports after making any changes requested by -*--set-handler*. - -*-n*, *--numeric*:: -For *--show-** options, all values will be displayed numerically only. The -default is to decode numeric values and display them symbolically as well. - -*--help*:: -Display help and exit. - -*--version*:: -Output version information and exit. - -== Examples - -Sets a new task-level exception handler for +EXC_CRASH+-type exceptions to the -handler registered with the bootstrap server as +svc+, showing the task-level -exception ports before and after the change. The old and new exception handlers -are verified by their service names as registered with the bootstrap server. -With the new task-level exception ports in effect, a program is run. -[subs="quotes"] ----- -$ *exception_port_tool --show-task --show-new-task \ - --show-bootstrap=com.apple.ReportCrash --show-bootstrap=svc \ - --set-handler=behavior=DEFAULT,handler=bootstrap:svc crash* -service com.apple.ReportCrash 0xe03 -service svc 0x1003 -task exception port 0, mask 0x400 (CRASH), port 0xe03, -behavior 0x80000003 (STATE_IDENTITY|MACH), flavor 7 (THREAD) -new task exception port 0, mask 0x400 (CRASH), port 0x1003, -behavior 0x1 (DEFAULT), flavor 13 (NONE) -Illegal instruction: 4 ----- - -Shows the task-level exception ports for the process with PID 1234. This -requires superuser permissions or the approval of taskgated(8). -[subs="quotes"] ----- -# *exception_port_tool --pid=1234 --show-task* -task exception port 0, mask 0x4e -(BAD_ACCESS|BAD_INSTRUCTION|ARITHMETIC|BREAKPOINT), port 0x1503, -behavior 0x1 (DEFAULT), flavor 13 (NONE) -task exception port 1, mask 0x1c00 (CRASH|RESOURCE|GUARD), -port 0x1403, behavior 0x80000003 (STATE_IDENTITY|MACH), -flavor 7 (THREAD) ----- - -== Exit Status - -*0*:: -Success. - -*125*:: -Failure, with a message printed to the standard error stream. - -*126*:: -The program specified by 'COMMAND' was found, but could not be invoked. - -*127*:: -The program specified by 'COMMAND' could not be found. - -== See Also - -man_link:catch_exception_tool[1], -man_link:on_demand_service_tool[1] - -include::../../doc/support/man_footer.ad[] diff --git a/tools/mac/exception_port_tool.md b/tools/mac/exception_port_tool.md new file mode 100644 index 00000000..37cbb265 --- /dev/null +++ b/tools/mac/exception_port_tool.md @@ -0,0 +1,234 @@ + + +# exception_port_tool(1) + +## Name + +exception_port_tool—Show and change Mach exception ports + +## Synopsis + +**exception_port_tool** [_OPTION…_] [_COMMAND_ [_ARG…_]] + +## Description + +Shows Mach exception ports registered for a thread, task, or host target with a +__--show-*__ option, changes Mach exception ports with **--set-handler**, shows +changes with a __--show-new-*__ option, and executes _COMMAND_ along with any +arguments specified (_ARG…_) with the changed exception ports in effect. + +## Options + + * **-s**, **--set-handler**=_DESCRIPTION_ + + Set an exception port to _DESCRIPTION_. This option may appear zero, one, or + more times. + + _DESCRIPTION_ is formatted as a comma-separated sequence of tokens, where + each token consists of a key and value separated by an equals sign. These + keys are recognized: + + * **target**=_TARGET_ + + _TARGET_ defines which target’s exception ports to set: **host**, + **task**, or **thread**. The default value of _TARGET_ is **task**. + Operations on **host** are restricted to the superuser. + + * **mask**=_MASK_ + + _MASK_ defines the mask of exception types to handle, from + ``. This can be **BAD_ACCESS**, + **BAD_INSTRUCTION**, **ARITHMETIC**, **EMULATION**, **SOFTWARE**, + **BREAKPOINT**, **SYSCALL**, **MACH_SYSCALL**, **RPC_ALERT**, **CRASH**, + **RESOURCE**, **GUARD**, or **CORPSE_NOTIFY**. Different exception types + may be combined by combining them with pipe characters (**|**). The + special value **ALL** includes each exception type except for **CRASH** + and **CORPSE_NOTIFY**. To truly specify all exception types including + these, use **ALL|CRASH|CORPSE_NOTIFY**. The default value of _MASK_ is + **CRASH**. + + * **behavior**=_BEHAVIOR_ + + _BEHAVIOR_ defines the specific exception handler routine to be called + when an exception occurs. This can be **DEFAULT**, **STATE**, or + **STATE_IDENTITY**. **MACH** may also be specified by combining them with + pipe characters (**|**). The most complete set of exception information is + provided with **STATE_IDENTITY|MACH**. Not all exception servers implement + all possible behaviors. The default value of _BEHAVIOR_ is + **DEFAULT|MACH**. + + * **flavor**=_FLAVOR_ + + For state-carrying values of _BEHAVIOR_ (those including **STATE** or + **STATE_IDENTITY**), _FLAVOR_ specifies the architecture-specific thread + state flavor to be provided to the exception handler. For the x86 family, + this can be **THREAD**, **THREAD32**, **THREAD64**, **FLOAT**, + **FLOAT32**, **FLOAT64**, **DEBUG**, **DEBUG32**, or **DEBUG64**. The + default value of _FLAVOR_ is **NONE**, which is not valid for + state-carrying values of _BEHAVIOR_. + + * **handler**=_HANDLER_ + + _HANDLER_ defines the exception handler. **NULL** indicates that any + existing exception port should be cleared. _HANDLER_ may also take the + form **bootstrap**:_SERVICE_, which will look _SERVICE_ up with the + bootstrap server and set that service as the exception handler. The + default value of _HANDLER_ is **NULL**. + + * **--show-bootstrap**=_SERVICE_ + + Looks up _SERVICE_ with the bootstrap server and shows it. Normally, the + handler port values displayed by the other __--show-*__ options are + meaningless handles, but by comparing them to the port values for known + bootstrap services, it is possible to verify that they are set as intended. + + * **-p**, **--pid**=_PID_ + + For operations on the task target, including **--set-handler** with _TARGET_ + set to **task**, **--show-task**, and **--show-new-task**, operates on the + task associated with process id _PID_ instead of the current task associated + with the tool. When this option is supplied, _COMMAND_ must not be specified. + + This option uses `task_for_pid()` to access the process’ task port. This + operation may be restricted to use by the superuser, executables signed by an + authority trusted by the system, and processes otherwise permitted by + taskgated(8). Consequently, this program must normally either be signed or be + invoked by root to use this option. It is possible to install this program as + a setuid root executable to overcome this limitation. However, it is not + possible to use this option to operate on processes protected by [System + Integrity Protection (SIP)](https://support.apple.com/HT204899), including + those whose “restrict” codesign(1) option is respected. + + * **-h**, **--show-host** + + Shows the original host exception ports before making any changes requested + by **--set-handler**. This option is restricted to the superuser. + + * **-t**, **--show-task** + + Shows the original task exception ports before making any changes requested + by **--set-handler**. + + * **--show-thread** + + Shows the original thread exception ports before making any changes requested + by **--set-handler**. + + * **-H**, **--show-new-host** + + Shows the modified host exception ports after making any changes requested by + **--set-handler**. This option is restricted to the superuser. + + * **-T**, **--show-new-task** + + Shows the modified task exception ports after making any changes requested by + **--set-handler**. + + * **--show-new-thread** + + Shows the modified thread exception ports after making any changes requested + by **--set-handler** + + * **-n**, **--numeric** + + For __--show-*__ options, all values will be displayed numerically only. The + default is to decode numeric values and display them symbolically as well. + + * **--help** + + Display help and exit. + + * **--version** + + Output version information and exit. + +## Examples + +Sets a new task-level exception handler for `EXC_CRASH`-type exceptions to the +handler registered with the bootstrap server as `svc`, showing the task-level +exception ports before and after the change. The old and new exception handlers +are verified by their service names as registered with the bootstrap server. +With the new task-level exception ports in effect, a program is run. + +``` +$ exception_port_tool --show-task --show-new-task \ + --show-bootstrap=com.apple.ReportCrash --show-bootstrap=svc \ + --set-handler=behavior=DEFAULT,handler=bootstrap:svc crash +service com.apple.ReportCrash 0xe03 +service svc 0x1003 +task exception port 0, mask 0x400 (CRASH), port 0xe03, behavior 0x80000003 (STATE_IDENTITY|MACH), flavor 7 (THREAD) +new task exception port 0, mask 0x400 (CRASH), port 0x1003, behavior 0x1 (DEFAULT), flavor 13 (NONE) +Illegal instruction: 4 +``` + +Shows the task-level exception ports for the process with PID 1234. This +requires superuser permissions or the approval of taskgated(8), and the process +must not be SIP-protected. + +``` +# exception_port_tool --pid=1234 --show-task +task exception port 0, mask 0x4e (BAD_ACCESS|BAD_INSTRUCTION|ARITHMETIC|BREAKPOINT), port 0x1503, behavior 0x1 (DEFAULT), flavor 13 (NONE) +task exception port 1, mask 0x1c00 (CRASH|RESOURCE|GUARD), port 0x1403, behavior 0x80000003 (STATE_IDENTITY|MACH), flavor 7 (THREAD) +``` + +## Exit Status + + * **0** + + Success. + + * **125** + + Failure, with a message printed to the standard error stream. + + * **126** + + The program specified by _COMMAND_ was found, but could not be invoked. + + * **127** + + The program specified by _COMMAND_ could not be found. + +## See Also + +[catch_exception_tool(1)](catch_exception_tool.md), +[on_demand_service_tool(1)](on_demand_service_tool.md), + +## Resources + +Crashpad home page: https://crashpad.chromium.org/. + +Report bugs at https://crashpad.chromium.org/bug/new. + +## Copyright + +Copyright 2014 [The Crashpad +Authors](https://chromium.googlesource.com/crashpad/crashpad/+/master/AUTHORS). + +## License + +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. diff --git a/tools/mac/on_demand_service_tool.ad b/tools/mac/on_demand_service_tool.ad deleted file mode 100644 index 5db4713f..00000000 --- a/tools/mac/on_demand_service_tool.ad +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright 2014 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. - -:doctype: manpage - -= on_demand_service_tool(1) - -== Name - -on_demand_service_tool - Load and unload on-demand Mach services registered with -launchd(8) - -== Synopsis - -[verse] -*on_demand_service_tool* *-L* *-l* 'LABEL' ['OPTION…'] 'COMMAND' ['ARG…'] -*on_demand_service_tool* *-U* *-l* 'LABEL' - -== Description - -On-demand services may be registered with launchd(8) by using the *--load* form. -One or more service names may be registered with the bootstrap server by -specifying *--mach-service*. When a Mach message is sent to any of these -services, launchd(8) will invoke 'COMMAND' along with any arguments specified -('ARG…'). 'COMMAND' must be an absolute pathname. - -The *--unload* form unregisters jobs registered with launchd(8). - -== Options - -*-L*, *--load*:: -Registers a job with launchd(8). *--label*='LABEL' and 'COMMAND' are required. -This operation may also be referred to as “load” or “submit”. - -*-U*, *--unload*:: -Unregisters a job with launchd(8). *--label*='LABEL' is required. This operation -may also be referred to as “unload” or “remove”. - -*-l*, *--label*='LABEL':: -'LABEL' is used as the job label to identify the job to launchd(8). 'LABEL' must -be unique within a launchd(8) context. - -*-m*, *--mach-service*='SERVICE':: -In conjunction with *--load*, registers 'SERVICE' with the bootstrap server. -Clients will be able to obtain a send right by looking up the 'SERVICE' name -with the bootstrap server. When a message is sent to such a Mach port, -launchd(8) will invoke 'COMMAND' along with any arguments specified ('ARG…') if -it is not running. This forms the “on-demand” nature referenced by this tool’s -name. This option may appear zero, one, or more times. 'SERVICE' must be unique -within a bootstrap context. - -*--help*:: -Display help and exit. - -*--version*:: -Output version information and exit. - -== Examples - -Registers an on-demand server that will execute man_link:catch_exception_tool[1] -when a Mach message is sent to a Mach port obtained from the bootstrap server by -looking up the name +svc+: -[subs="quotes"] ----- -$ *on_demand_service_tool --load --label=catch_exception \ - --mach-service=svc \ - $(which catch_exception_tool) --mach-service=svc \ - --file=/tmp/out --persistent --timeout=0* ----- - -Unregisters the on-demand server installed above: -[subs="quotes"] ----- -$ *on_demand_service_tool --unload --label=catch_exception* ----- - -== Exit Status - -*0*:: -Success. - -*1*:: -Failure, with a message printed to the standard error stream. - -== See Also - -man_link:catch_exception_tool[1], -man_link:exception_port_tool[1], -launchctl(1) - -include::../../doc/support/man_footer.ad[] diff --git a/tools/mac/on_demand_service_tool.md b/tools/mac/on_demand_service_tool.md new file mode 100644 index 00000000..5a850352 --- /dev/null +++ b/tools/mac/on_demand_service_tool.md @@ -0,0 +1,133 @@ + + +# on_demand_service_tool(1) + +## Name + +on_demand_service_tool—Load and unload on-demand Mach services registered with +launchd(8) + +## Synopsis + +**on_demand_service_tool** **-L** **-l** _LABEL_ [_OPTION…_] _COMMAND_ +[_ARG…_]
+**on_demand_service_tool** **-U** **-l** _LABEL_ + +## Description + +On-demand services may be registered with launchd(8) by using the **--load** +form. One or more service names may be registered with the bootstrap server by +specifying **--mach-service**. When a Mach message is sent to any of these +services, launchd(8) will invoke _COMMAND_ along with any arguments specified +(_ARG…_). _COMMAND_ must be an absolute pathname. + +The **--unload** form unregisters jobs registered with launchd(8). + +## Options + + * **-L**, **--load** + + Registers a job with launchd(8). **--label**=_LABEL_ and _COMMAND_ are + required. This operation may also be referred to as “load” or “submit”. + + * **-U**, **--unload** + + Unregisters a job with launchd(8). **--label**=_LABEL_ is required. This + operation may also be referred to as “unload” or “remove”. + + * **-l**, **--label**=_LABEL_ + + _LABEL_ is used as the job label to identify the job to launchd(8). _LABEL_ + must be unique within a launchd(8) context. + + * **-m**, **--mach-service**=_SERVICE_ + + In conjunction with **--load**, registers _SERVICE_ with the bootstrap + server. Clients will be able to obtain a send right by looking up the + _SERVICE_ name with the bootstrap server. When a message is sent to such a + Mach port, launchd(8) will invoke _COMMAND_ along with any arguments + specified (_ARG…_) if it is not running. This forms the “on-demand” nature + referenced by this tool’s name. This option may appear zero, one, or more + times. _SERVICE_ must be unique within a bootstrap context. + + * **--help** + + Display help and exit. + + * **--version** + + Output version information and exit. + +## Examples + +Registers an on-demand server that will execute +[catch_exception_tool(1)](catch_exception_tool.md) when a Mach message is sent +to a Mach port obtained from the bootstrap server by looking up the name `svc`: + +``` +$ on_demand_service_tool --load --label=catch_exception \ + --mach-service=svc \ + $(which catch_exception_tool) --mach-service=svc \ + --file=/tmp/out --persistent --timeout=0 +``` + +Unregisters the on-demand server installed above: + +``` +$ on_demand_service_tool --unload --label=catch_exception +``` + +## Exit Status + + * **0** + + Success. + + * **1** + + Failure, with a message printed to the standard error stream. + +## See Also + +[catch_exception_tool(1)](catch_exception_tool.md), +[exception_port_tool(1)](exception_port_tool.md), +launchctl(1) + +## Resources + +Crashpad home page: https://crashpad.chromium.org/. + +Report bugs at https://crashpad.chromium.org/bug/new. + +## Copyright + +Copyright 2014 [The Crashpad +Authors](https://chromium.googlesource.com/crashpad/crashpad/+/master/AUTHORS). + +## License + +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. diff --git a/tools/mac/run_with_crashpad.ad b/tools/mac/run_with_crashpad.ad deleted file mode 100644 index 129488a3..00000000 --- a/tools/mac/run_with_crashpad.ad +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright 2014 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. - -:doctype: manpage - -= run_with_crashpad(1) - -== Name - -run_with_crashpad - Run a program with a Crashpad exception handler - -== Synopsis - -[verse] -*run_with_crashpad* ['OPTION…'] 'COMMAND' ['ARG…'] - -== Description - -Starts a Crashpad exception handler server such as crashpad_handler(8) and -becomes its client, setting an exception port referencing the handler. Then, -executes 'COMMAND' along with any arguments specified ('ARG…') with the new -exception port in effect. - -The exception port is configured to receive exceptions of type +EXC_CRASH+, -+EXC_RESOURCE+, and +EXC_GUARD+. The exception behavior is configured as -+EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES+. The thread state flavor is -set to +MACHINE_THREAD_STATE+. - -Programs that use the Crashpad client library directly will not normally use -this tool. This tool exists to allow programs that are unaware of Crashpad to be -run with a Crashpad exception handler. - -== Options -*-h*, *--handler*='HANDLER':: -Invoke 'HANDLER' as the Crashpad handler program instead of the default, -*crashpad_handler*. - -*--annotation*='KEY=VALUE':: -Passed to the Crashpad handler program as an *--annotation* argument. - -*--database*='PATH':: -Passed to the Crashpad handler program as its *--database* argument. - -*--url*='URL':: -Passed to the Crashpad handler program as its *--url* argument. - -*-a*, *--argument*='ARGUMENT':: -Invokes the Crashpad handler program with 'ARGUMENT' as one of its arguments. -This option may appear zero, one, or more times. If this program has a specific -option such as *--database* matching the desired Crashpad handler program -option, the specific option should be used in preference to *--argument*. -Regardless of this option’s presence, the handler will always be invoked with -the necessary arguments to perform a handshake. - -*--help*:: -Display help and exit. - -*--version*:: -Output version information and exit. - -== Examples - -Starts a Crashpad exception handler server by its default name, -*crashpad_handler*, and runs a program with this handler in effect. -[subs="quotes"] ----- -$ *run_with_crashpad --database=/tmp/crashpad_database crash* -Illegal instruction: 4 ----- - -Starts a Crashpad exception handler server at a nonstandard path, and runs -man_link:exception_port_tool[1] to show the task-level exception ports. -[subs="quotes"] ----- -$ *run_with_crashpad --handler=/tmp/crashpad_handler \ - --database=/tmp/crashpad_database exception_port_tool \ - --show-task* -task exception port 0, mask 0x1c00 (CRASH|RESOURCE|GUARD), port -0x30b, behavior 0x80000003 (STATE_IDENTITY|MACH), flavor 7 (THREAD) ----- - -== Exit Status - -*0*:: -Success. - -*125*:: -Failure, with a message printed to the standard error stream. - -*126*:: -The program specified by 'COMMAND' was found, but could not be invoked. - -*127*:: -The program specified by 'COMMAND' could not be found. - -== See Also - -man_link:crashpad_handler[8], -man_link:exception_port_tool[1] - -include::../../doc/support/man_footer.ad[] diff --git a/tools/mac/run_with_crashpad.md b/tools/mac/run_with_crashpad.md new file mode 100644 index 00000000..0efcc371 --- /dev/null +++ b/tools/mac/run_with_crashpad.md @@ -0,0 +1,147 @@ + + +# run_with_crashpad(1) + +## Name + +run_with_crashpad—Run a program with a Crashpad exception handler + +## Synopsis + +**run_with_crashpad** [_OPTION…_] _COMMAND_ [_ARG…_] + +## Description + +Starts a Crashpad exception handler server such as +[crashpad_handler(8)](../../handler/crashpad_handler.md) and becomes its client, +setting an exception port referencing the handler. Then, executes _COMMAND_ +along with any arguments specified (_ARG…_) with the new exception port in +effect. + +The exception port is configured to receive exceptions of type `EXC_CRASH`, +`EXC_RESOURCE`, and `EXC_GUARD`. The exception behavior is configured as +`EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES`. The thread state flavor is +set to `MACHINE_THREAD_STATE`. + +Programs that use the Crashpad client library directly will not normally use +this tool. This tool exists to allow programs that are unaware of Crashpad to be +run with a Crashpad exception handler. + +## Options + + * **-h**, **--handler**=_HANDLER_ + + Invoke 'HANDLER' as the Crashpad handler program instead of the default, + **crashpad_handler**. + + * **--annotation**=_KEY=VALUE_ + + Passed to the Crashpad handler program as an **--annotation** argument. + + * **--database**=_PATH_ + + Passed to the Crashpad handler program as its **--database** argument. + + * **--url**=_URL_ + + Passed to the Crashpad handler program as its **--url** argument. + + * **-a**, **--argument**=_ARGUMENT_ + + Invokes the Crashpad handler program with _ARGUMENT_ as one of its arguments. + This option may appear zero, one, or more times. If this program has a + specific option such as **--database** matching the desired Crashpad handler + program option, the specific option should be used in preference to + **--argument**. Regardless of this option’s presence, the handler will always + be invoked with the necessary arguments to perform a handshake. + + * **--help** + + Display help and exit. + + * **--version** + + Output version information and exit. + +## Examples + +Starts a Crashpad exception handler server by its default name, +**crashpad_handler**, and runs a program with this handler in effect. + +``` +$ run_with_crashpad --database=/tmp/crashpad_database crasher +Illegal instruction: 4 +``` + +Starts a Crashpad exception handler server at a nonstandard path, and runs +[exception_port_tool(1)](exception_port_tool.md) to show the task-level +exception ports. + +``` +$ run_with_crashpad --handler=/tmp/crashpad_handler \ + --database=/tmp/crashpad_database exception_port_tool \ + --show-task +task exception port 0, mask 0x1c00 (CRASH|RESOURCE|GUARD), port 0x30b, behavior 0x80000003 (STATE_IDENTITY|MACH), flavor 7 (THREAD) +``` + +## Exit Status + + * **0** + + Success. + + * **125** + + Failure, with a message printed to the standard error stream. + + * **126** + + The program specified by 'COMMAND' was found, but could not be invoked. + + * **127** + + The program specified by 'COMMAND' could not be found. + +## See Also + +[crashpad_handler(8)](../../handler/crashpad_handler.md), +[exception_port_tool(1)](exception_port_tool.md) + +## Resources + +Crashpad home page: https://crashpad.chromium.org/. + +Report bugs at https://crashpad.chromium.org/bug/new. + +## Copyright + +Copyright 2014 [The Crashpad +Authors](https://chromium.googlesource.com/crashpad/crashpad/+/master/AUTHORS). + +## License + +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. From 3830e4e5c145d316ce1228066c72b84c886b3f42 Mon Sep 17 00:00:00 2001 From: Mark Mentovai Date: Fri, 4 Nov 2016 17:50:01 -0400 Subject: [PATCH 08/10] =?UTF-8?q?Update=20the=20link=20to=20mini=5Fchromiu?= =?UTF-8?q?m=E2=80=99s=20README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also, update mini_chromium to 414d59602ac38e24f1e93929fda3d79d72cea139 7bfe6cd9579b README→README.md; convert plain text to Markdown 414d59602ac3 Fix mailto: link in README.md BUG=crashpad:138 Change-Id: Ibd3c054a3e7f08a740fe6aca408cf23797d992ae Reviewed-on: https://chromium-review.googlesource.com/408316 Reviewed-by: Robert Sesek --- DEPS | 2 +- doc/developing.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DEPS b/DEPS index 79677f35..7a9be6d3 100644 --- a/DEPS +++ b/DEPS @@ -25,7 +25,7 @@ deps = { '93cc6e2c23e4d5ebd179f388e67aa907d0dfd43d', 'crashpad/third_party/mini_chromium/mini_chromium': Var('chromium_git') + '/chromium/mini_chromium@' + - '8e8d3cc9a245f1bf63296e97fb6ac1c90f6d86f5', + '414d59602ac38e24f1e93929fda3d79d72cea139', 'buildtools': Var('chromium_git') + '/chromium/buildtools.git@' + 'f8fc76ea5ce4a60cda2fa5d7df3d4a62935b3113', diff --git a/doc/developing.md b/doc/developing.md index 71e10404..737f819f 100644 --- a/doc/developing.md +++ b/doc/developing.md @@ -28,7 +28,7 @@ other projects, Crashpad uses [mini_chromium](https://chromium.googlesource.com/chromium/mini_chromium/), a small, self-contained library that provides many of Chromium’s useful low-level base routines. [mini_chromium’s -README](https://chromium.googlesource.com/chromium/mini_chromium/+/master/README) +README](https://chromium.googlesource.com/chromium/mini_chromium/+/master/README.md) provides more detail. ## Prerequisites From 6753ba5a5a9a5b09938a1fb2b39d7edebef1a25a Mon Sep 17 00:00:00 2001 From: Mark Mentovai Date: Fri, 4 Nov 2016 18:12:47 -0400 Subject: [PATCH 09/10] catch_exception_tool.md: fix on_demand_service_tool link text BUG=crashpad:138 Change-Id: Id0b8c99a065475181bb9484c4ecf23255d6311f8 Reviewed-on: https://chromium-review.googlesource.com/408356 Reviewed-by: Robert Sesek --- tools/mac/catch_exception_tool.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/mac/catch_exception_tool.md b/tools/mac/catch_exception_tool.md index fc357dc6..3c71decf 100644 --- a/tools/mac/catch_exception_tool.md +++ b/tools/mac/catch_exception_tool.md @@ -112,7 +112,7 @@ catch_exception_tool: behavior EXCEPTION_DEFAULT|MACH_EXCEPTION_CODES, pid 2468, ## See Also [exception_port_tool(1)](exception_port_tool.md), -[exception_port_tool(1)](on_demand_service_tool.md) +[on_demand_service_tool(1)](on_demand_service_tool.md) ## Resources From 05c89beaae4e983a33015cbc0eb4586d1d5c2ef3 Mon Sep 17 00:00:00 2001 From: Mark Mentovai Date: Fri, 4 Nov 2016 18:15:17 -0400 Subject: [PATCH 10/10] doc: Another silly follow-up BUG=crashpad:138 Change-Id: I5ed157b4521cc86fbc75208c3778314535d97ddf Reviewed-on: https://chromium-review.googlesource.com/408376 Reviewed-by: Robert Sesek --- tools/mac/exception_port_tool.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/mac/exception_port_tool.md b/tools/mac/exception_port_tool.md index 37cbb265..1743e420 100644 --- a/tools/mac/exception_port_tool.md +++ b/tools/mac/exception_port_tool.md @@ -206,7 +206,7 @@ task exception port 1, mask 0x1c00 (CRASH|RESOURCE|GUARD), port 0x1403, behavior ## See Also [catch_exception_tool(1)](catch_exception_tool.md), -[on_demand_service_tool(1)](on_demand_service_tool.md), +[on_demand_service_tool(1)](on_demand_service_tool.md) ## Resources