From 623c4a0f42522beef36793c74914c8618d2f6ec9 Mon Sep 17 00:00:00 2001 From: Tobias Sargeant Date: Fri, 13 Oct 2017 17:55:46 +0100 Subject: Convert {mini|micro}dump_stackwalk argument parsing to getopt. Bug: google-breakpad:748 Change-Id: I70b16ba6456df0be038d6c7170eb22b093fdc65d Reviewed-on: https://chromium-review.googlesource.com/718756 Reviewed-by: Mike Frysinger --- src/processor/microdump_stackwalk.cc | 106 ++++++++++++++++++++--------------- 1 file changed, 61 insertions(+), 45 deletions(-) (limited to 'src/processor/microdump_stackwalk.cc') diff --git a/src/processor/microdump_stackwalk.cc b/src/processor/microdump_stackwalk.cc index 7ea80495..4200636c 100644 --- a/src/processor/microdump_stackwalk.cc +++ b/src/processor/microdump_stackwalk.cc @@ -32,6 +32,7 @@ #include #include +#include #include #include @@ -50,6 +51,13 @@ namespace { +struct Options { + bool machine_readable; + + string microdump_file; + std::vector symbol_paths; +}; + using google_breakpad::BasicSourceLineResolver; using google_breakpad::MicrodumpProcessor; using google_breakpad::ProcessResult; @@ -58,19 +66,18 @@ using google_breakpad::scoped_ptr; using google_breakpad::SimpleSymbolSupplier; using google_breakpad::StackFrameSymbolizer; -// Processes |microdump_file| using MicrodumpProcessor. |symbol_path|, if -// non-empty, is the base directory of a symbol storage area, laid out in -// the format required by SimpleSymbolSupplier. If such a storage area -// is specified, it is made available for use by the MicrodumpProcessor. +// Processes |options.microdump_file| using +// MicrodumpProcessor. |options.symbol_path|, if non-empty, is the +// base directory of a symbol storage area, laid out in the format +// required by SimpleSymbolSupplier. If such a storage area is +// specified, it is made available for use by the MicrodumpProcessor. // // Returns the value of MicrodumpProcessor::Process. If processing succeeds, // prints identifying OS and CPU information from the microdump, crash // information and call stacks for the crashing thread. // All information is printed to stdout. -int PrintMicrodumpProcess(const char* microdump_file, - const std::vector& symbol_paths, - bool machine_readable) { - std::ifstream file_stream(microdump_file); +int PrintMicrodumpProcess(const Options& options) { + std::ifstream file_stream(options.microdump_file); std::vector bytes; file_stream.seekg(0, std::ios_base::end); bytes.resize(file_stream.tellg()); @@ -79,8 +86,8 @@ int PrintMicrodumpProcess(const char* microdump_file, string microdump_content(&bytes[0], bytes.size()); scoped_ptr symbol_supplier; - if (!symbol_paths.empty()) { - symbol_supplier.reset(new SimpleSymbolSupplier(symbol_paths)); + if (!options.symbol_paths.empty()) { + symbol_supplier.reset(new SimpleSymbolSupplier(options.symbol_paths)); } BasicSourceLineResolver resolver; @@ -91,7 +98,7 @@ int PrintMicrodumpProcess(const char* microdump_file, &process_state); if (res == google_breakpad::PROCESS_OK) { - if (machine_readable) { + if (options.machine_readable) { PrintProcessStateMachineReadable(process_state); } else { PrintProcessState(process_state, false, &resolver); @@ -103,49 +110,58 @@ int PrintMicrodumpProcess(const char* microdump_file, return 1; } -void usage(const char *program_name) { - fprintf(stderr, "usage: %s [-m] [symbol-path ...]\n" - " -m : Output in machine-readable format\n", - program_name); +} // namespace + +static void Usage(int argc, const char *argv[], bool error) { + fprintf(error ? stderr : stdout, + "Usage: %s [options] [symbol-path ...]\n" + "\n" + "Output a stack trace for the provided microdump\n" + "\n" + "Options:\n" + "\n" + " -m Output in machine-readable format\n", + basename(argv[0])); } -} // namespace +static void SetupOptions(int argc, const char *argv[], Options* options) { + int ch; -int main(int argc, char** argv) { - BPLOG_INIT(&argc, &argv); + options->machine_readable = false; - if (argc < 2) { - usage(argv[0]); - return 1; - } + while ((ch = getopt(argc, (char * const *)argv, "hm")) != -1) { + switch (ch) { + case 'h': + Usage(argc, argv, false); + exit(0); + break; - const char* microdump_file; - bool machine_readable; - int symbol_path_arg; + case 'm': + options->machine_readable = true; + break; - if (strcmp(argv[1], "-m") == 0) { - if (argc < 3) { - usage(argv[0]); - return 1; + case '?': + Usage(argc, argv, true); + exit(1); + break; } - - machine_readable = true; - microdump_file = argv[2]; - symbol_path_arg = 3; - } else { - machine_readable = false; - microdump_file = argv[1]; - symbol_path_arg = 2; } - // extra arguments are symbol paths - std::vector symbol_paths; - if (argc > symbol_path_arg) { - for (int argi = symbol_path_arg; argi < argc; ++argi) - symbol_paths.push_back(argv[argi]); + if ((argc - optind) == 0) { + fprintf(stderr, "%s: Missing microdump file\n", argv[0]); + Usage(argc, argv, true); + exit(1); } - return PrintMicrodumpProcess(microdump_file, - symbol_paths, - machine_readable); + options->microdump_file = argv[optind]; + + for (int argi = optind + 1; argi < argc; ++argi) + options->symbol_paths.push_back(argv[argi]); +} + +int main(int argc, const char* argv[]) { + Options options; + SetupOptions(argc, argv, &options); + + return PrintMicrodumpProcess(options); } -- cgit v1.2.1