diff --git a/src/apps/debugger/Debugger.cpp b/src/apps/debugger/Debugger.cpp index 9a25be1108..295b0542c8 100644 --- a/src/apps/debugger/Debugger.cpp +++ b/src/apps/debugger/Debugger.cpp @@ -56,8 +56,10 @@ static const char* kUsage = "fourth form additionally stops the specified thread.\n" "\n" "Options:\n" - " -h, --help - Print this usage info and exit.\n" - " -c, --cli - Use command line user interface\n" + " -h, --help - Print this usage info and exit.\n" + " -c, --cli - Use command line user interface\n" + " -s, --save-report - Save crash report for the targetted team and exit.\n" + " Implies --cli.\n" ; @@ -76,6 +78,8 @@ struct Options { team_id team; thread_id thread; bool useCLI; + bool saveReport; + const char* reportPath; Options() : @@ -83,7 +87,9 @@ struct Options { commandLineArgv(NULL), team(-1), thread(-1), - useCLI(false) + useCLI(false), + saveReport(false), + reportPath(NULL) { } }; @@ -105,15 +111,16 @@ parse_arguments(int argc, const char* const* argv, bool noOutput, while (true) { static struct option sLongOptions[] = { { "help", no_argument, 0, 'h' }, + { "cli", no_argument, 0, 'c' }, + { "save-report", optional_argument, 0, 's' }, { "team", required_argument, 0, 't' }, { "thread", required_argument, 0, 'T' }, - { "cli", no_argument, 0, 'c' }, { 0, 0, 0, 0 } }; opterr = 0; // don't print errors - int c = getopt_long(argc, (char**)argv, "+ch", sLongOptions, NULL); + int c = getopt_long(argc, (char**)argv, "+chs", sLongOptions, NULL); if (c == -1) break; @@ -128,6 +135,14 @@ parse_arguments(int argc, const char* const* argv, bool noOutput, print_usage_and_exit(false); break; + case 's': + { + options.useCLI = true; + options.saveReport = true; + options.reportPath = optarg; + break; + } + case 't': { options.team = strtol(optarg, NULL, 0); @@ -581,7 +596,8 @@ CliDebugger::Run(const Options& options) // create the command line UI CommandLineUserInterface* userInterface - = new(std::nothrow) CommandLineUserInterface; + = new(std::nothrow) CommandLineUserInterface(options.saveReport, + options.reportPath); if (userInterface == NULL) { fprintf(stderr, "Error: Out of memory!\n"); return false; diff --git a/src/apps/debugger/user_interface/cli/CommandLineUserInterface.cpp b/src/apps/debugger/user_interface/cli/CommandLineUserInterface.cpp index e6d2bb097a..a909727aeb 100644 --- a/src/apps/debugger/user_interface/cli/CommandLineUserInterface.cpp +++ b/src/apps/debugger/user_interface/cli/CommandLineUserInterface.cpp @@ -88,9 +88,12 @@ private: // #pragma mark - CommandLineUserInterface -CommandLineUserInterface::CommandLineUserInterface() +CommandLineUserInterface::CommandLineUserInterface(bool saveReport, + const char* reportPath) : fCommands(20, true), + fReportPath(reportPath), + fSaveReport(saveReport), fShowSemaphore(-1), fShown(false), fTerminating(false) @@ -202,7 +205,18 @@ CommandLineUserInterface::Run() if (error != B_OK) return; - _InputLoop(); + if (!fSaveReport) + _InputLoop(); + else { + ArgumentVector args; + char buffer[256]; + const char* parseErrorLocation; + snprintf(buffer, sizeof(buffer), "save-report %s", + fReportPath != NULL ? fReportPath : ""); + args.Parse(buffer, &parseErrorLocation); + _ExecuteCommand(args.ArgumentCount(), args.Arguments()); + fContext.QuitSession(true); + } // Release the Show() semaphore to signal Terminate(). release_sem(fShowSemaphore); diff --git a/src/apps/debugger/user_interface/cli/CommandLineUserInterface.h b/src/apps/debugger/user_interface/cli/CommandLineUserInterface.h index 6bede606c3..fc01510256 100644 --- a/src/apps/debugger/user_interface/cli/CommandLineUserInterface.h +++ b/src/apps/debugger/user_interface/cli/CommandLineUserInterface.h @@ -19,7 +19,8 @@ class CliCommand; class CommandLineUserInterface : public UserInterface { public: - CommandLineUserInterface(); + CommandLineUserInterface(bool saveReport, + const char* reportPath); virtual ~CommandLineUserInterface(); virtual const char* ID() const; @@ -70,6 +71,8 @@ private: private: CliContext fContext; CommandList fCommands; + const char* fReportPath; + bool fSaveReport; sem_id fShowSemaphore; bool fShown; volatile bool fTerminating;