mirror of
https://github.com/chromium/crashpad.git
synced 2024-12-27 15:32:10 +08:00
Add the run_with_crashpad tool.
run_with_crashpad runs a program with a Crashpad exception handler. It allows a Crashpad exception-handling server to be started and to direct crashes to it from programs that are not themselves clients of the Crashpad client library. R=rsesek@chromium.org Review URL: https://codereview.chromium.org/810423004
This commit is contained in:
parent
2602e9d5d0
commit
f4ec7ba590
99
tools/mac/run_with_crashpad.ad
Normal file
99
tools/mac/run_with_crashpad.ad
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
// 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*.
|
||||||
|
|
||||||
|
*-a*, *--handler-argument*='ARGUMENT'::
|
||||||
|
Invokes the Crashpad handler program with 'ARGUMENT' as one of its arguments.
|
||||||
|
This option may appear zero, one, or more times. 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 crash*
|
||||||
|
Illegal instruction: 4
|
||||||
|
----
|
||||||
|
|
||||||
|
Starts a Crashpad exception handler server at a nonstandard path, and runs
|
||||||
|
exception_port_tool(1) to show the task-level exception ports.
|
||||||
|
[subs="quotes"]
|
||||||
|
----
|
||||||
|
$ *run_with_crashpad --handler=/tmp/crashpad_handler exception_port_tool*
|
||||||
|
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),
|
||||||
|
exception_port_tool(1)
|
||||||
|
|
||||||
|
include::../man_footer.ad[]
|
144
tools/mac/run_with_crashpad.cc
Normal file
144
tools/mac/run_with_crashpad.cc
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <libgen.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "base/files/file_path.h"
|
||||||
|
#include "base/logging.h"
|
||||||
|
#include "client/crashpad_client.h"
|
||||||
|
#include "tools/tool_support.h"
|
||||||
|
|
||||||
|
namespace crashpad {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
void Usage(const std::string& me) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Usage: %s [OPTION]... COMMAND [ARG]...\n"
|
||||||
|
"Start a Crashpad handler and have it handle crashes from COMMAND.\n"
|
||||||
|
"\n"
|
||||||
|
" -h, --handler=HANDLER invoke HANDLER instead of crashpad_handler\n"
|
||||||
|
" -a, --handler-argument=ARGUMENT invoke the handler with ARGUMENT\n"
|
||||||
|
" --help display this help and exit\n"
|
||||||
|
" --version output version information and exit\n",
|
||||||
|
me.c_str());
|
||||||
|
ToolSupport::UsageTail(me);
|
||||||
|
}
|
||||||
|
|
||||||
|
int RunWithCrashpadMain(int argc, char* argv[]) {
|
||||||
|
const std::string me(basename(argv[0]));
|
||||||
|
|
||||||
|
enum ExitCode {
|
||||||
|
kExitSuccess = EXIT_SUCCESS,
|
||||||
|
|
||||||
|
// To differentiate this tool’s errors from errors in the programs it execs,
|
||||||
|
// use a high exit code for ordinary failures instead of EXIT_FAILURE. This
|
||||||
|
// is the same rationale for using the distinct exit codes for exec
|
||||||
|
// failures.
|
||||||
|
kExitFailure = 125,
|
||||||
|
|
||||||
|
// Like env, use exit code 126 if the program was found but could not be
|
||||||
|
// invoked, and 127 if it could not be found.
|
||||||
|
// http://pubs.opengroup.org/onlinepubs/9699919799/utilities/env.html
|
||||||
|
kExitExecFailure = 126,
|
||||||
|
kExitExecENOENT = 127,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum OptionFlags {
|
||||||
|
// “Short” (single-character) options.
|
||||||
|
kOptionHandler = 'h',
|
||||||
|
kOptionHandlerArgument = 'a',
|
||||||
|
|
||||||
|
// Long options without short equivalents.
|
||||||
|
kOptionLastChar = 255,
|
||||||
|
|
||||||
|
// Standard options.
|
||||||
|
kOptionHelp = -2,
|
||||||
|
kOptionVersion = -3,
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct option long_options[] = {
|
||||||
|
{"handler", required_argument, nullptr, kOptionHandler},
|
||||||
|
{"handler-argument", required_argument, nullptr, kOptionHandlerArgument},
|
||||||
|
{"help", no_argument, nullptr, kOptionHelp},
|
||||||
|
{"version", no_argument, nullptr, kOptionVersion},
|
||||||
|
{nullptr, 0, nullptr, 0},
|
||||||
|
};
|
||||||
|
|
||||||
|
struct {
|
||||||
|
std::string handler;
|
||||||
|
std::vector<std::string> handler_arguments;
|
||||||
|
} options = {};
|
||||||
|
options.handler = "crashpad_handler";
|
||||||
|
|
||||||
|
int opt;
|
||||||
|
while ((opt = getopt_long(argc, argv, "+a:h:", long_options, nullptr)) !=
|
||||||
|
-1) {
|
||||||
|
switch (opt) {
|
||||||
|
case kOptionHandler:
|
||||||
|
options.handler = optarg;
|
||||||
|
break;
|
||||||
|
case kOptionHandlerArgument:
|
||||||
|
options.handler_arguments.push_back(optarg);
|
||||||
|
break;
|
||||||
|
case kOptionHelp:
|
||||||
|
Usage(me);
|
||||||
|
return kExitSuccess;
|
||||||
|
case kOptionVersion:
|
||||||
|
ToolSupport::Version(me);
|
||||||
|
return kExitSuccess;
|
||||||
|
default:
|
||||||
|
ToolSupport::UsageHint(me, nullptr);
|
||||||
|
return kExitFailure;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
argc -= optind;
|
||||||
|
argv += optind;
|
||||||
|
|
||||||
|
if (!argc) {
|
||||||
|
ToolSupport::UsageHint(me, "COMMAND is required");
|
||||||
|
return kExitFailure;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start the handler process and direct exceptions to it.
|
||||||
|
CrashpadClient crashpad_client;
|
||||||
|
if (!crashpad_client.StartHandler(base::FilePath(options.handler),
|
||||||
|
options.handler_arguments)) {
|
||||||
|
return kExitFailure;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!crashpad_client.UseHandler()) {
|
||||||
|
return kExitFailure;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Using the remaining arguments, start a new program with the new exception
|
||||||
|
// port in effect.
|
||||||
|
execvp(argv[0], argv);
|
||||||
|
PLOG(ERROR) << "execvp " << argv[0];
|
||||||
|
return errno == ENOENT ? kExitExecENOENT : kExitExecFailure;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
} // namespace crashpad
|
||||||
|
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
return crashpad::RunWithCrashpadMain(argc, argv);
|
||||||
|
}
|
@ -102,6 +102,22 @@
|
|||||||
'mac/on_demand_service_tool.mm',
|
'mac/on_demand_service_tool.mm',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
'target_name': 'run_with_crashpad',
|
||||||
|
'type': 'executable',
|
||||||
|
'dependencies': [
|
||||||
|
'tool_support',
|
||||||
|
'../client/client.gyp:client',
|
||||||
|
'../compat/compat.gyp:compat',
|
||||||
|
'../third_party/mini_chromium/mini_chromium/base/base.gyp:base',
|
||||||
|
],
|
||||||
|
'include_dirs': [
|
||||||
|
'..',
|
||||||
|
],
|
||||||
|
'sources': [
|
||||||
|
'mac/run_with_crashpad.cc',
|
||||||
|
],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
}, {
|
}, {
|
||||||
'targets': [],
|
'targets': [],
|
||||||
|
Loading…
x
Reference in New Issue
Block a user