mirror of
https://github.com/chromium/crashpad.git
synced 2025-03-27 19:12:27 +00:00
Merge master 05c89beaae4e into doc
This commit is contained in:
commit
92733e1dff
2
DEPS
2
DEPS
@ -25,7 +25,7 @@ deps = {
|
|||||||
'93cc6e2c23e4d5ebd179f388e67aa907d0dfd43d',
|
'93cc6e2c23e4d5ebd179f388e67aa907d0dfd43d',
|
||||||
'crashpad/third_party/mini_chromium/mini_chromium':
|
'crashpad/third_party/mini_chromium/mini_chromium':
|
||||||
Var('chromium_git') + '/chromium/mini_chromium@' +
|
Var('chromium_git') + '/chromium/mini_chromium@' +
|
||||||
'8e8d3cc9a245f1bf63296e97fb6ac1c90f6d86f5',
|
'414d59602ac38e24f1e93929fda3d79d72cea139',
|
||||||
'buildtools':
|
'buildtools':
|
||||||
Var('chromium_git') + '/chromium/buildtools.git@' +
|
Var('chromium_git') + '/chromium/buildtools.git@' +
|
||||||
'f8fc76ea5ce4a60cda2fa5d7df3d4a62935b3113',
|
'f8fc76ea5ce4a60cda2fa5d7df3d4a62935b3113',
|
||||||
|
41
README.md
Normal file
41
README.md
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
# 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.
|
@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#include "base/atomicops.h"
|
#include "base/atomicops.h"
|
||||||
#include "base/logging.h"
|
#include "base/logging.h"
|
||||||
|
#include "base/macros.h"
|
||||||
#include "base/scoped_generic.h"
|
#include "base/scoped_generic.h"
|
||||||
#include "base/strings/string16.h"
|
#include "base/strings/string16.h"
|
||||||
#include "base/strings/stringprintf.h"
|
#include "base/strings/stringprintf.h"
|
||||||
@ -67,6 +68,19 @@ base::Lock* g_non_crash_dump_lock;
|
|||||||
// dump.
|
// dump.
|
||||||
ExceptionInformation g_non_crash_exception_information;
|
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
|
// A CRITICAL_SECTION initialized with
|
||||||
// RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO to force it to be allocated with a
|
// 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
|
// valid .DebugInfo field. The address of this critical section is given to the
|
||||||
@ -74,7 +88,37 @@ ExceptionInformation g_non_crash_exception_information;
|
|||||||
// list, so this allows the handler to capture all of them.
|
// list, so this allows the handler to capture all of them.
|
||||||
CRITICAL_SECTION g_critical_section_with_debug_info;
|
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<base::subtle::AtomicWord>(state));
|
||||||
|
}
|
||||||
|
|
||||||
|
StartupState BlockUntilHandlerStartedOrFailed() {
|
||||||
|
// 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<int>(StartupState::kNotReady)) {
|
||||||
|
Sleep(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return static_cast<StartupState>(startup_state);
|
||||||
|
}
|
||||||
|
|
||||||
LONG WINAPI UnhandledExceptionHandler(EXCEPTION_POINTERS* exception_pointers) {
|
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.
|
||||||
|
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.
|
// Tracks whether a thread has already entered UnhandledExceptionHandler.
|
||||||
static base::subtle::AtomicWord have_crashed;
|
static base::subtle::AtomicWord have_crashed;
|
||||||
|
|
||||||
@ -226,6 +270,7 @@ struct BackgroundHandlerStartThreadData {
|
|||||||
const std::string& url,
|
const std::string& url,
|
||||||
const std::map<std::string, std::string>& annotations,
|
const std::map<std::string, std::string>& annotations,
|
||||||
const std::vector<std::string>& arguments,
|
const std::vector<std::string>& arguments,
|
||||||
|
const std::wstring& ipc_pipe,
|
||||||
ScopedFileHANDLE ipc_pipe_handle)
|
ScopedFileHANDLE ipc_pipe_handle)
|
||||||
: handler(handler),
|
: handler(handler),
|
||||||
database(database),
|
database(database),
|
||||||
@ -233,6 +278,7 @@ struct BackgroundHandlerStartThreadData {
|
|||||||
url(url),
|
url(url),
|
||||||
annotations(annotations),
|
annotations(annotations),
|
||||||
arguments(arguments),
|
arguments(arguments),
|
||||||
|
ipc_pipe(ipc_pipe),
|
||||||
ipc_pipe_handle(std::move(ipc_pipe_handle)) {}
|
ipc_pipe_handle(std::move(ipc_pipe_handle)) {}
|
||||||
|
|
||||||
base::FilePath handler;
|
base::FilePath handler;
|
||||||
@ -241,11 +287,33 @@ struct BackgroundHandlerStartThreadData {
|
|||||||
std::string url;
|
std::string url;
|
||||||
std::map<std::string, std::string> annotations;
|
std::map<std::string, std::string> annotations;
|
||||||
std::vector<std::string> arguments;
|
std::vector<std::string> arguments;
|
||||||
|
std::wstring ipc_pipe;
|
||||||
ScopedFileHANDLE ipc_pipe_handle;
|
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(
|
bool StartHandlerProcess(
|
||||||
std::unique_ptr<BackgroundHandlerStartThreadData> data) {
|
std::unique_ptr<BackgroundHandlerStartThreadData> data) {
|
||||||
|
ScopedCallSetHandlerStartupState scoped_startup_state_caller;
|
||||||
|
|
||||||
std::wstring command_line;
|
std::wstring command_line;
|
||||||
AppendCommandLineArgument(data->handler.value(), &command_line);
|
AppendCommandLineArgument(data->handler.value(), &command_line);
|
||||||
for (const std::string& argument : data->arguments) {
|
for (const std::string& argument : data->arguments) {
|
||||||
@ -393,6 +461,22 @@ bool StartHandlerProcess(
|
|||||||
rv = CloseHandle(process_info.hProcess);
|
rv = CloseHandle(process_info.hProcess);
|
||||||
PLOG_IF(WARNING, !rv) << "CloseHandle process";
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -414,10 +498,6 @@ void CommonInProcessInitialization() {
|
|||||||
&g_critical_section_with_debug_info);
|
&g_critical_section_with_debug_info);
|
||||||
|
|
||||||
g_non_crash_dump_lock = new base::Lock();
|
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
|
} // namespace
|
||||||
@ -456,12 +536,15 @@ bool CrashpadClient::StartHandler(
|
|||||||
|
|
||||||
CommonInProcessInitialization();
|
CommonInProcessInitialization();
|
||||||
|
|
||||||
|
SetUnhandledExceptionFilter(&UnhandledExceptionHandler);
|
||||||
|
|
||||||
auto data = new BackgroundHandlerStartThreadData(handler,
|
auto data = new BackgroundHandlerStartThreadData(handler,
|
||||||
database,
|
database,
|
||||||
metrics_dir,
|
metrics_dir,
|
||||||
url,
|
url,
|
||||||
annotations,
|
annotations,
|
||||||
arguments,
|
arguments,
|
||||||
|
ipc_pipe_,
|
||||||
std::move(ipc_pipe_handle));
|
std::move(ipc_pipe_handle));
|
||||||
|
|
||||||
if (asynchronous_start) {
|
if (asynchronous_start) {
|
||||||
@ -478,6 +561,7 @@ bool CrashpadClient::StartHandler(
|
|||||||
nullptr));
|
nullptr));
|
||||||
if (!handler_start_thread_.is_valid()) {
|
if (!handler_start_thread_.is_valid()) {
|
||||||
PLOG(ERROR) << "CreateThread";
|
PLOG(ERROR) << "CreateThread";
|
||||||
|
SetHandlerStartupState(StartupState::kFailed);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -524,6 +608,9 @@ bool CrashpadClient::SetHandlerIPCPipe(const std::wstring& ipc_pipe) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SetHandlerStartupState(StartupState::kSucceeded);
|
||||||
|
SetUnhandledExceptionFilter(&UnhandledExceptionHandler);
|
||||||
|
|
||||||
// The server returns these already duplicated to be valid in this process.
|
// The server returns these already duplicated to be valid in this process.
|
||||||
g_signal_exception =
|
g_signal_exception =
|
||||||
IntToHandle(response.registration.request_crash_dump_event);
|
IntToHandle(response.registration.request_crash_dump_event);
|
||||||
@ -562,7 +649,15 @@ bool CrashpadClient::WaitForHandlerStart() {
|
|||||||
void CrashpadClient::DumpWithoutCrash(const CONTEXT& context) {
|
void CrashpadClient::DumpWithoutCrash(const CONTEXT& context) {
|
||||||
if (g_signal_non_crash_dump == INVALID_HANDLE_VALUE ||
|
if (g_signal_non_crash_dump == INVALID_HANDLE_VALUE ||
|
||||||
g_non_crash_dump_done == 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -613,11 +708,15 @@ void CrashpadClient::DumpWithoutCrash(const CONTEXT& context) {
|
|||||||
// static
|
// static
|
||||||
void CrashpadClient::DumpAndCrash(EXCEPTION_POINTERS* exception_pointers) {
|
void CrashpadClient::DumpAndCrash(EXCEPTION_POINTERS* exception_pointers) {
|
||||||
if (g_signal_exception == INVALID_HANDLE_VALUE) {
|
if (g_signal_exception == INVALID_HANDLE_VALUE) {
|
||||||
LOG(ERROR) << "haven't called UseHandler(), no dump captured";
|
LOG(ERROR) << "not connected";
|
||||||
TerminateProcess(GetCurrentProcess(), kTerminationCodeUseHandlerNotCalled);
|
TerminateProcess(GetCurrentProcess(),
|
||||||
|
kTerminationCodeNotConnectedToHandler);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We don't need to check for handler startup here, as
|
||||||
|
// UnhandledExceptionHandler() necessarily does that.
|
||||||
|
|
||||||
UnhandledExceptionHandler(exception_pointers);
|
UnhandledExceptionHandler(exception_pointers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,10 +15,12 @@
|
|||||||
#include "client/crashpad_client.h"
|
#include "client/crashpad_client.h"
|
||||||
|
|
||||||
#include "base/files/file_path.h"
|
#include "base/files/file_path.h"
|
||||||
|
#include "base/macros.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "test/paths.h"
|
#include "test/paths.h"
|
||||||
#include "test/scoped_temp_dir.h"
|
#include "test/scoped_temp_dir.h"
|
||||||
#include "test/win/win_multiprocess.h"
|
#include "test/win/win_multiprocess.h"
|
||||||
|
#include "util/win/termination_codes.h"
|
||||||
|
|
||||||
namespace crashpad {
|
namespace crashpad {
|
||||||
namespace test {
|
namespace test {
|
||||||
@ -88,6 +90,92 @@ TEST(CrashpadClient, StartWithSameStdoutStderr) {
|
|||||||
WinMultiprocess::Run<StartWithSameStdoutStderr>();
|
WinMultiprocess::Run<StartWithSameStdoutStderr>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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::string, std::string>(),
|
||||||
|
std::vector<std::string>(),
|
||||||
|
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<HandlerLaunchFailureCrash>();
|
||||||
|
}
|
||||||
|
|
||||||
|
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<HandlerLaunchFailureDumpAndCrash>();
|
||||||
|
}
|
||||||
|
|
||||||
|
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<HandlerLaunchFailureDumpWithoutCrash>();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace test
|
} // namespace test
|
||||||
} // namespace crashpad
|
} // namespace crashpad
|
||||||
|
@ -59,33 +59,47 @@ union Compile_Assert {
|
|||||||
// This may result in a static module initializer in debug-mode builds, but
|
// 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
|
// because it’s POD, no code should need to run to initialize this under
|
||||||
// release-mode optimization.
|
// 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)
|
#if __has_feature(address_sanitizer)
|
||||||
// AddressSanitizer would add a trailing red zone of at least 32 bytes, which
|
// AddressSanitizer would add a trailing red zone of at least 32 bytes,
|
||||||
// would be reflected in the size of the custom section. This confuses
|
// which would be reflected in the size of the custom section. This confuses
|
||||||
// MachOImageReader::GetCrashpadInfo(), which finds that the section’s size
|
// MachOImageReader::GetCrashpadInfo(), which finds that the section’s size
|
||||||
// disagrees with the structure’s size_ field. By specifying an alignment
|
// disagrees with the structure’s size_ field. By specifying an alignment
|
||||||
// greater than the red zone size, the red zone will be suppressed.
|
// greater than the red zone size, the red zone will be suppressed.
|
||||||
,
|
aligned(64),
|
||||||
aligned(64)
|
#endif // __has_feature(address_sanitizer)
|
||||||
#endif
|
|
||||||
)) CrashpadInfo g_crashpad_info;
|
// 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)
|
#elif defined(OS_WIN)
|
||||||
|
|
||||||
// Put the struct in a section name CPADinfo where it can be found without the
|
// Put the struct in a section name CPADinfo where it can be found without the
|
||||||
// symbol table.
|
// symbol table.
|
||||||
#pragma section("CPADinfo", read, write)
|
#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
|
// static
|
||||||
CrashpadInfo* CrashpadInfo::GetCrashpadInfo() {
|
CrashpadInfo* CrashpadInfo::GetCrashpadInfo() {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
This is the App Engine app that serves https://crashpad.chromium.org/.
|
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
|
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,
|
go_appengine directory. This may be added to your $PATH for convenience,
|
||||||
although it is not necessary.
|
although it is not necessary.
|
||||||
|
|
||||||
@ -19,7 +19,7 @@ $ GOROOT=…/go_appengine/goroot GOPATH=…/go_appengine/gopath go get -d
|
|||||||
|
|
||||||
To test locally:
|
To test locally:
|
||||||
|
|
||||||
$ goapp serve
|
$ …/go_appengine/goapp serve
|
||||||
|
|
||||||
Look for the “Starting module "default" running at: http://localhost:8080” line,
|
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.
|
which tells you the URL of the local running instance of the app.
|
||||||
|
@ -37,31 +37,49 @@ func init() {
|
|||||||
|
|
||||||
func handler(w http.ResponseWriter, r *http.Request) {
|
func handler(w http.ResponseWriter, r *http.Request) {
|
||||||
const (
|
const (
|
||||||
baseURL = "https://chromium.googlesource.com/crashpad/crashpad/+/doc/doc/generated/?format=TEXT"
|
baseURL = "https://chromium.googlesource.com/crashpad/crashpad/+/"
|
||||||
bugBaseURL = "https://bugs.chromium.org/p/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)
|
ctx := appengine.NewContext(r)
|
||||||
client := urlfetch.Client(ctx)
|
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.
|
// Don’t show dotfiles.
|
||||||
if strings.HasPrefix(path.Base(r.URL.Path), ".") {
|
if strings.HasPrefix(path.Base(r.URL.Path), ".") {
|
||||||
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
|
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.URL.Path == "/bug" || r.URL.Path == "/bug/" {
|
u, err := url.Parse(generatedDocBaseURL)
|
||||||
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)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
|
@ -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.”
|
|
310
doc/developing.md
Normal file
310
doc/developing.md
Normal file
@ -0,0 +1,310 @@
|
|||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
# 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.md)
|
||||||
|
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.”
|
42
doc/index.ad
42
doc/index.ad
@ -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.
|
|
@ -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.
|
|
41
doc/status.md
Normal file
41
doc/status.md
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
# 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.
|
@ -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?<br />}{basebackend-xhtml11=<br>}
|
|
||||||
endif::doctype-manpage[]
|
|
||||||
ifndef::doctype-manpage[]
|
|
||||||
Version {revnumber}{basebackend-xhtml11?<br />}{basebackend-xhtml11=<br>}
|
|
||||||
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)[\\]?(?P<name>man_link):(?P<target>\S*?)\[(?P<attrlist>.*?)\]=
|
|
||||||
|
|
||||||
ifdef::backend-docbook[]
|
|
||||||
[man_link-inlinemacro]
|
|
||||||
{0%{target}}
|
|
||||||
{0#<citerefentry>}
|
|
||||||
{0#<refentrytitle>{target}</refentrytitle><manvolnum>{0}</manvolnum>}
|
|
||||||
{0#</citerefentry>}
|
|
||||||
endif::backend-docbook[]
|
|
||||||
|
|
||||||
ifdef::basebackend-html[]
|
|
||||||
[man_link-inlinemacro]
|
|
||||||
<a href="{target}.html">{target}{0?({0})}</a>
|
|
||||||
endif::basebackend-html[]
|
|
||||||
|
|
||||||
endif::doctype-manpage[]
|
|
@ -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;
|
|
||||||
}
|
|
@ -29,31 +29,44 @@ cd "$(dirname "${0}")/../.."
|
|||||||
source doc/support/compat.sh
|
source doc/support/compat.sh
|
||||||
|
|
||||||
doc/support/generate_doxygen.sh
|
doc/support/generate_doxygen.sh
|
||||||
doc/support/generate_asciidoc.sh
|
|
||||||
|
|
||||||
output_dir=doc/generated
|
output_dir=doc/generated
|
||||||
maybe_mkdir "${output_dir}"
|
maybe_mkdir "${output_dir}"
|
||||||
|
|
||||||
for subdir in doc doxygen man ; do
|
maybe_mkdir "${output_dir}/doxygen"
|
||||||
output_subdir="${output_dir}/${subdir}"
|
rsync -Ilr --delete --exclude .git "out/doc/doxygen/html/" \
|
||||||
maybe_mkdir "${output_subdir}"
|
"${output_dir}/doxygen"
|
||||||
rsync -Ilr --delete --exclude .git "out/doc/${subdir}/html/" \
|
|
||||||
"${output_subdir}/"
|
|
||||||
done
|
|
||||||
|
|
||||||
# Move doc/index.html to index.html, adjusting relative paths to other files in
|
# Remove old things that used to be present
|
||||||
# doc.
|
rm -rf "${output_dir}/doc"
|
||||||
base_url=https://crashpad.chromium.org/
|
rm -rf "${output_dir}/man"
|
||||||
${sed_ext} -e 's%<a href="([^/]+)\.html">%<a href="doc/\1.html">%g' \
|
rm -f "${output_dir}/index.html"
|
||||||
-e 's%<a href="'"${base_url}"'">%<a href="index.html">%g' \
|
|
||||||
-e 's%<a href="'"${base_url}"'%<a href="%g' \
|
|
||||||
< "${output_dir}/doc/index.html" > "${output_dir}/index.html"
|
|
||||||
rm "${output_dir}/doc/index.html"
|
|
||||||
|
|
||||||
# Ensure a favicon exists at the root since the browser will always request it.
|
# Ensure a favicon exists at the root since the browser will always request it.
|
||||||
cp doc/favicon.ico "${output_dir}/"
|
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} --><a href="https://chromium.googlesource.com/crashpad/crashpad/+/master/${man_path}">${man_basename}</a>
|
||||||
|
__EOF__
|
||||||
|
done
|
||||||
|
|
||||||
|
maybe_mkdir "${output_dir}/man"
|
||||||
|
|
||||||
cd "${output_dir}/man"
|
cd "${output_dir}/man"
|
||||||
cat > index.html << __EOF__
|
cat > index.html << __EOF__
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
@ -62,18 +75,17 @@ cat > index.html << __EOF__
|
|||||||
<ul>
|
<ul>
|
||||||
__EOF__
|
__EOF__
|
||||||
|
|
||||||
for html_file in *.html; do
|
sort "${list_file}" | while read line; do
|
||||||
if [[ "${html_file}" = "index.html" ]]; then
|
line=$(${sed_ext} -e 's/^<!-- .* -->//' <<< "${line}")
|
||||||
continue
|
|
||||||
fi
|
|
||||||
basename=$(${sed_ext} -e 's/\.html$//' <<< "${html_file}")
|
|
||||||
cat >> index.html << __EOF__
|
cat >> index.html << __EOF__
|
||||||
<li>
|
<li>
|
||||||
<a href="${html_file}">${basename}</a>
|
${line}
|
||||||
</li>
|
</li>
|
||||||
__EOF__
|
__EOF__
|
||||||
done
|
done
|
||||||
|
|
||||||
|
rm -f "${list_file}"
|
||||||
|
|
||||||
cat >> index.html << __EOF__
|
cat >> index.html << __EOF__
|
||||||
</ul>
|
</ul>
|
||||||
__EOF__
|
__EOF__
|
||||||
|
@ -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
|
|
@ -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.
|
|
@ -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\<somename>+. 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[]
|
|
223
handler/crashpad_handler.md
Normal file
223
handler/crashpad_handler.md
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
# 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\<somename>`. 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.
|
@ -160,6 +160,13 @@
|
|||||||
'win/crash_other_program.cc',
|
'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',
|
'target_name': 'hanging_program',
|
||||||
'type': 'executable',
|
'type': 'executable',
|
||||||
|
@ -267,6 +267,7 @@ int HandlerMain(int argc, char* argv[]) {
|
|||||||
me, "failed to parse --initial-client-data");
|
me, "failed to parse --initial-client-data");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
#endif // OS_MACOSX
|
#endif // OS_MACOSX
|
||||||
case kOptionMetrics: {
|
case kOptionMetrics: {
|
||||||
|
@ -46,13 +46,13 @@ bool CrashAndDumpTarget(const CrashpadClient& client, HANDLE process) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int thread_count = 0;
|
|
||||||
do {
|
do {
|
||||||
if (te32.th32OwnerProcessID == target_pid) {
|
if (te32.th32OwnerProcessID == target_pid) {
|
||||||
thread_count++;
|
// We set the thread priority of "Thread1" to a non-default value before
|
||||||
if (thread_count == 2) {
|
// going to sleep. Dump and blame this thread. For an explanation of
|
||||||
// Nominate this lucky thread as our blamee, and dump it. This will be
|
// "9", see
|
||||||
// "Thread1" in the child.
|
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms685100.aspx.
|
||||||
|
if (te32.tpBasePri == 9) {
|
||||||
ScopedKernelHANDLE thread(
|
ScopedKernelHANDLE thread(
|
||||||
OpenThread(kXPThreadAllAccess, false, te32.th32ThreadID));
|
OpenThread(kXPThreadAllAccess, false, te32.th32ThreadID));
|
||||||
if (!client.DumpAndCrashTargetProcess(
|
if (!client.DumpAndCrashTargetProcess(
|
||||||
|
20
handler/win/fake_handler_that_crashes_at_startup.cc
Normal file
20
handler/win/fake_handler_that_crashes_at_startup.cc
Normal file
@ -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;
|
||||||
|
}
|
@ -22,6 +22,9 @@
|
|||||||
#include "client/crashpad_info.h"
|
#include "client/crashpad_info.h"
|
||||||
|
|
||||||
DWORD WINAPI Thread1(LPVOID dummy) {
|
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);
|
Sleep(INFINITE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
21
navbar.md
Normal file
21
navbar.md
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
* [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/)
|
@ -117,7 +117,18 @@ class TestMachOImageAnnotationsReader final
|
|||||||
bool* destroy_complex_request) override {
|
bool* destroy_complex_request) override {
|
||||||
*destroy_complex_request = true;
|
*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;
|
ProcessReader process_reader;
|
||||||
bool rv = process_reader.Initialize(task);
|
bool rv = process_reader.Initialize(task);
|
||||||
|
@ -477,7 +477,7 @@ bool MachOImageReader::GetCrashpadInfo(
|
|||||||
|
|
||||||
mach_vm_address_t crashpad_info_address;
|
mach_vm_address_t crashpad_info_address;
|
||||||
const process_types::section* crashpad_info_section =
|
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) {
|
if (!crashpad_info_section) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -270,8 +270,9 @@ class MachOImageReader {
|
|||||||
//! \brief Obtains the module’s CrashpadInfo structure.
|
//! \brief Obtains the module’s CrashpadInfo structure.
|
||||||
//!
|
//!
|
||||||
//! \return `true` on success, `false` on failure. If the module does not have
|
//! \return `true` on success, `false` on failure. If the module does not have
|
||||||
//! a `__crashpad_info` section, this will return `false` without logging
|
//! a `__DATA,crashpad_info` section, this will return `false` without
|
||||||
//! any messages. Other failures will result in messages being logged.
|
//! logging any messages. Other failures will result in messages being
|
||||||
|
//! logged.
|
||||||
bool GetCrashpadInfo(process_types::CrashpadInfo* crashpad_info) const;
|
bool GetCrashpadInfo(process_types::CrashpadInfo* crashpad_info) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
// snapshot/mac/process_types.cc to produce process type struct definitions and
|
// snapshot/mac/process_types.cc to produce process type struct definitions and
|
||||||
// accessors.
|
// 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.
|
// according to this structure.
|
||||||
PROCESS_TYPE_STRUCT_BEGIN(CrashpadInfo)
|
PROCESS_TYPE_STRUCT_BEGIN(CrashpadInfo)
|
||||||
PROCESS_TYPE_STRUCT_MEMBER(uint32_t, signature)
|
PROCESS_TYPE_STRUCT_MEMBER(uint32_t, signature)
|
||||||
|
@ -165,7 +165,7 @@ class ModuleSnapshot {
|
|||||||
//! contain multiple annotations, so they are returned in a vector.
|
//! contain multiple annotations, so they are returned in a vector.
|
||||||
//!
|
//!
|
||||||
//! For Mac OS X snapshots, these annotations are found by interpreting the
|
//! 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
|
//! System libraries using the crash reporter client interface may reference
|
||||||
//! annotations in this structure. Additional annotations messages may be
|
//! annotations in this structure. Additional annotations messages may be
|
||||||
//! found in other locations, which may be module-specific. The dynamic linker
|
//! found in other locations, which may be module-specific. The dynamic linker
|
||||||
@ -184,7 +184,7 @@ class ModuleSnapshot {
|
|||||||
//! keys.”
|
//! keys.”
|
||||||
//!
|
//!
|
||||||
//! For Mac OS X snapshots, these annotations are found by interpreting the
|
//! 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
|
//! Crashpad client interface to store annotations in this structure. Most
|
||||||
//! annotations under the client’s direct control will be retrievable by this
|
//! annotations under the client’s direct control will be retrievable by this
|
||||||
//! method. For clients such as Chrome, this includes the process type.
|
//! method. For clients such as Chrome, this includes the process type.
|
||||||
|
@ -185,6 +185,14 @@ class CdbRun(object):
|
|||||||
global g_had_failures
|
global g_had_failures
|
||||||
g_had_failures = True
|
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,
|
def RunTests(cdb_path,
|
||||||
dump_path,
|
dump_path,
|
||||||
@ -267,9 +275,15 @@ def RunTests(cdb_path,
|
|||||||
r'FreeOwnStackAndBreak.*\nquit:',
|
r'FreeOwnStackAndBreak.*\nquit:',
|
||||||
'at correct location, no additional stack entries')
|
'at correct location, no additional stack entries')
|
||||||
|
|
||||||
# Switch to the other thread after jumping to the exception, and examine
|
# Dump memory pointed to be EDI on the background suspended thread. We don't
|
||||||
# memory.
|
# know the index of the thread because the system may have started other
|
||||||
out = CdbRun(cdb_path, dump_path, '.ecxr; ~1s; db /c14 edi')
|
# 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',
|
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')
|
'data pointed to by registers captured')
|
||||||
|
|
||||||
@ -330,10 +344,17 @@ def RunTests(cdb_path,
|
|||||||
'other program dump exception code')
|
'other program dump exception code')
|
||||||
out.Check('!Sleep', 'other program reasonable location')
|
out.Check('!Sleep', 'other program reasonable location')
|
||||||
out.Check('hanging_program!Thread1', 'other program dump right thread')
|
out.Check('hanging_program!Thread1', 'other program dump right thread')
|
||||||
out.Check('\. 1 Id.*Suspend: 0 ',
|
count = 0
|
||||||
'other program exception on correct thread and correct suspend')
|
while True:
|
||||||
out.Check(' 4 Id.*Suspend: 0 ',
|
match_obj = out.Find(r'Id.*Suspend: (\d+) ')
|
||||||
'other program injection thread correct suspend')
|
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 = CdbRun(cdb_path, other_program_no_exception_path, '.ecxr;k')
|
||||||
out.Check('Unknown exception - code 0cca11ed',
|
out.Check('Unknown exception - code 0cca11ed',
|
||||||
|
@ -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[]
|
|
207
tools/crashpad_database_util.md
Normal file
207
tools/crashpad_database_util.md
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
# 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.
|
@ -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[]
|
|
127
tools/generate_dump.md
Normal file
127
tools/generate_dump.md
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
# 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.
|
@ -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[]
|
|
140
tools/mac/catch_exception_tool.md
Normal file
140
tools/mac/catch_exception_tool.md
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
# 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),
|
||||||
|
[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.
|
@ -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
|
|
||||||
+<mach/exception_types.h>+. 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[]
|
|
234
tools/mac/exception_port_tool.md
Normal file
234
tools/mac/exception_port_tool.md
Normal file
@ -0,0 +1,234 @@
|
|||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
# 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
|
||||||
|
`<mach/exception_types.h>`. 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.
|
@ -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[]
|
|
133
tools/mac/on_demand_service_tool.md
Normal file
133
tools/mac/on_demand_service_tool.md
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
# 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…_]<br/>
|
||||||
|
**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.
|
@ -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[]
|
|
147
tools/mac/run_with_crashpad.md
Normal file
147
tools/mac/run_with_crashpad.md
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
# 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.
|
@ -271,8 +271,10 @@ void ExceptionHandlerServer::InitializeWithInheritedDataForInitialClient(
|
|||||||
// TODO(scottmg): Vista+. Might need to pass through or possibly find an Nt*.
|
// 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);
|
size_t bytes = sizeof(wchar_t) * _MAX_PATH + sizeof(FILE_NAME_INFO);
|
||||||
std::unique_ptr<uint8_t[]> data(new uint8_t[bytes]);
|
std::unique_ptr<uint8_t[]> data(new uint8_t[bytes]);
|
||||||
if (!GetFileInformationByHandleEx(
|
if (!GetFileInformationByHandleEx(first_pipe_instance_.get(),
|
||||||
first_pipe_instance_.get(), FileNameInfo, data.get(), bytes)) {
|
FileNameInfo,
|
||||||
|
data.get(),
|
||||||
|
static_cast<DWORD>(bytes))) {
|
||||||
PLOG(FATAL) << "GetFileInformationByHandleEx";
|
PLOG(FATAL) << "GetFileInformationByHandleEx";
|
||||||
}
|
}
|
||||||
FILE_NAME_INFO* file_name_info =
|
FILE_NAME_INFO* file_name_info =
|
||||||
@ -411,6 +413,16 @@ bool ExceptionHandlerServer::ServiceClientConnection(
|
|||||||
return true;
|
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:
|
case ClientToServerMessage::kRegister:
|
||||||
// Handled below.
|
// Handled below.
|
||||||
break;
|
break;
|
||||||
|
@ -25,8 +25,8 @@
|
|||||||
namespace crashpad {
|
namespace crashpad {
|
||||||
|
|
||||||
bool SendToCrashHandlerServer(const base::string16& pipe_name,
|
bool SendToCrashHandlerServer(const base::string16& pipe_name,
|
||||||
const crashpad::ClientToServerMessage& message,
|
const ClientToServerMessage& message,
|
||||||
crashpad::ServerToClientMessage* response) {
|
ServerToClientMessage* response) {
|
||||||
// Retry CreateFile() in a loop. If the handler isn’t actively waiting in
|
// Retry CreateFile() in a loop. If the handler isn’t actively waiting in
|
||||||
// ConnectNamedPipe() on a pipe instance because it’s busy doing something
|
// ConnectNamedPipe() on a pipe instance because it’s busy doing something
|
||||||
// else, CreateFile() will fail with ERROR_PIPE_BUSY. WaitNamedPipe() waits
|
// 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
|
// 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
|
// done to guarantee correct ordering. When the client starts the handler
|
||||||
// itself, CrashpadClient::StartHandler() provides this synchronization.
|
// itself, CrashpadClient::StartHandler() provides this synchronization.
|
||||||
for (int tries = 0;;) {
|
for (;;) {
|
||||||
ScopedFileHANDLE pipe(
|
ScopedFileHANDLE pipe(
|
||||||
CreateFile(pipe_name.c_str(),
|
CreateFile(pipe_name.c_str(),
|
||||||
GENERIC_READ | GENERIC_WRITE,
|
GENERIC_READ | GENERIC_WRITE,
|
||||||
@ -52,13 +52,12 @@ bool SendToCrashHandlerServer(const base::string16& pipe_name,
|
|||||||
SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION,
|
SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION,
|
||||||
nullptr));
|
nullptr));
|
||||||
if (!pipe.is_valid()) {
|
if (!pipe.is_valid()) {
|
||||||
if (++tries == 5 || GetLastError() != ERROR_PIPE_BUSY) {
|
if (GetLastError() != ERROR_PIPE_BUSY) {
|
||||||
PLOG(ERROR) << "CreateFile";
|
PLOG(ERROR) << "CreateFile";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!WaitNamedPipe(pipe_name.c_str(), 1000) &&
|
if (!WaitNamedPipe(pipe_name.c_str(), NMPWAIT_WAIT_FOREVER)) {
|
||||||
GetLastError() != ERROR_SEM_TIMEOUT) {
|
|
||||||
PLOG(ERROR) << "WaitNamedPipe";
|
PLOG(ERROR) << "WaitNamedPipe";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -75,7 +74,7 @@ bool SendToCrashHandlerServer(const base::string16& pipe_name,
|
|||||||
BOOL result = TransactNamedPipe(
|
BOOL result = TransactNamedPipe(
|
||||||
pipe.get(),
|
pipe.get(),
|
||||||
// This is [in], but is incorrectly declared non-const.
|
// This is [in], but is incorrectly declared non-const.
|
||||||
const_cast<crashpad::ClientToServerMessage*>(&message),
|
const_cast<ClientToServerMessage*>(&message),
|
||||||
sizeof(message),
|
sizeof(message),
|
||||||
response,
|
response,
|
||||||
sizeof(*response),
|
sizeof(*response),
|
||||||
|
@ -82,8 +82,14 @@ struct ClientToServerMessage {
|
|||||||
enum Type : uint32_t {
|
enum Type : uint32_t {
|
||||||
//! \brief For RegistrationRequest.
|
//! \brief For RegistrationRequest.
|
||||||
kRegister,
|
kRegister,
|
||||||
|
|
||||||
//! \brief For ShutdownRequest.
|
//! \brief For ShutdownRequest.
|
||||||
kShutdown,
|
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;
|
} type;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
|
@ -29,7 +29,7 @@ enum TerminationCodes : unsigned int {
|
|||||||
|
|
||||||
//! \brief A dump was requested for a client that was never registered with
|
//! \brief A dump was requested for a client that was never registered with
|
||||||
//! the crash handler.
|
//! the crash handler.
|
||||||
kTerminationCodeUseHandlerNotCalled = 0xffff7003,
|
kTerminationCodeNotConnectedToHandler = 0xffff7003,
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace crashpad
|
} // namespace crashpad
|
||||||
|
Loading…
x
Reference in New Issue
Block a user