Debugger: Refactor non-interactive report handling.
- Add dedicated ReportDebugger application class for the case where we're asked to do nothing more than save a report. Also add a corresponding UserInterface subclass whose sole purpose is to take those necessary actions and then exit. - When the debugger is invoked via the --save-report option, we now start via the aforementioned report/interface rather than piggybacking on the CLI. - Clean up CommandLineUserInterface/CliContext to remove handling for the report saving option. Should hopefully resolve #12155.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2014, Rene Gollent, [email protected].
|
||||
* Copyright 2011-2015, Rene Gollent, [email protected].
|
||||
* Copyright 2012, Ingo Weinhold, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
@@ -93,13 +93,9 @@ private:
|
||||
// #pragma mark - CommandLineUserInterface
|
||||
|
||||
|
||||
CommandLineUserInterface::CommandLineUserInterface(bool saveReport,
|
||||
const char* reportPath, thread_id reportTargetThread)
|
||||
CommandLineUserInterface::CommandLineUserInterface()
|
||||
:
|
||||
fCommands(20, true),
|
||||
fReportPath(reportPath),
|
||||
fSaveReport(saveReport),
|
||||
fReportTargetThread(reportTargetThread),
|
||||
fShowSemaphore(-1),
|
||||
fShown(false),
|
||||
fTerminating(false)
|
||||
@@ -128,8 +124,6 @@ CommandLineUserInterface::Init(Team* team, UserInterfaceListener* listener)
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
fContext.SetInteractive(!fSaveReport);
|
||||
|
||||
error = _RegisterCommands();
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
@@ -138,8 +132,6 @@ CommandLineUserInterface::Init(Team* team, UserInterfaceListener* listener)
|
||||
if (fShowSemaphore < 0)
|
||||
return fShowSemaphore;
|
||||
|
||||
team->AddListener(this);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -176,9 +168,7 @@ CommandLineUserInterface::Terminate()
|
||||
bool
|
||||
CommandLineUserInterface::IsInteractive() const
|
||||
{
|
||||
// if we were invoked solely for the purpose of saving a crash report,
|
||||
// then we're not taking user input into account.
|
||||
return !fSaveReport;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -237,43 +227,12 @@ CommandLineUserInterface::Run()
|
||||
if (error != B_OK)
|
||||
return;
|
||||
|
||||
if (fSaveReport) {
|
||||
ArgumentVector args;
|
||||
char buffer[256];
|
||||
const char* parseErrorLocation;
|
||||
if (_ReportTargetThreadStopNeeded()) {
|
||||
snprintf(buffer, sizeof(buffer), "stop %" B_PRId32,
|
||||
fReportTargetThread);
|
||||
args.Parse(buffer, &parseErrorLocation);
|
||||
_ExecuteCommand(args.ArgumentCount(), args.Arguments());
|
||||
} else
|
||||
_SubmitSaveReport();
|
||||
}
|
||||
|
||||
_InputLoop();
|
||||
// Release the Show() semaphore to signal Terminate().
|
||||
release_sem(fShowSemaphore);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CommandLineUserInterface::ThreadStateChanged(const Team::ThreadEvent& event)
|
||||
{
|
||||
if (fSaveReport) {
|
||||
Thread* thread = event.GetThread();
|
||||
// If we were asked to attach/report on a specific thread
|
||||
// rather than a team, and said thread was still
|
||||
// running, when we attached, we need to wait for its corresponding
|
||||
// stop state before generating a report, else we might not get its
|
||||
// stack trace.
|
||||
if (thread->ID() == fReportTargetThread
|
||||
&& thread->State() == THREAD_STATE_STOPPED) {
|
||||
_SubmitSaveReport();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*static*/ status_t
|
||||
CommandLineUserInterface::_InputLoopEntry(void* data)
|
||||
{
|
||||
@@ -473,32 +432,3 @@ CommandLineUserInterface::_CompareCommandEntries(const CommandEntry* command1,
|
||||
{
|
||||
return ::Compare(command1->Name(), command2->Name());
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CommandLineUserInterface::_ReportTargetThreadStopNeeded() const
|
||||
{
|
||||
if (fReportTargetThread < 0)
|
||||
return false;
|
||||
|
||||
Team* team = fContext.GetTeam();
|
||||
AutoLocker<Team> teamLocker(team);
|
||||
Thread* thread = team->ThreadByID(fReportTargetThread);
|
||||
if (thread == NULL)
|
||||
return false;
|
||||
|
||||
return thread->State() != THREAD_STATE_STOPPED;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CommandLineUserInterface::_SubmitSaveReport()
|
||||
{
|
||||
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());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user