From 2c4195e84019d5e1e40a116b0113f4186c0b1687 Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Sun, 24 Apr 2016 20:26:36 -0400 Subject: [PATCH] Debugger: Integrate core handling into TargetHostInterface. {Local}TargetHostInterface: - Add virtual method for requesting a debugger interface for a core file. Implement accordingly in LocalTargetHostInterface based on Ingo's previous implementation in the Debugger app. TeamDebuggerOptions: - Add an enum to define the type of team debugger request being made to explicitly make this clear rather than guessing based on the provided arguments. Set accordingly in the various cases. - Add a parameter for the core file path. Debugger: - Refactor to fill in TeamDebuggerOptions appropriately for core file requests, and consequently simplify code. This doesn't yet deal with the fact that a post-mortem team's ID can clash with that of a live team, which may lead to issues when attempting to attach to a live team in such a case. --- src/apps/debugger/Debugger.cpp | 110 +++--------------- .../TargetHostInterface.cpp | 54 ++++++--- .../TargetHostInterface.h | 15 ++- .../local/LocalTargetHostInterface.cpp | 39 +++++++ .../local/LocalTargetHostInterface.h | 5 +- 5 files changed, 106 insertions(+), 117 deletions(-) diff --git a/src/apps/debugger/Debugger.cpp b/src/apps/debugger/Debugger.cpp index 88a6ccd288..a88e6b9b35 100644 --- a/src/apps/debugger/Debugger.cpp +++ b/src/apps/debugger/Debugger.cpp @@ -116,6 +116,14 @@ set_debugger_options_from_options(TeamDebuggerOptions& _debuggerOptions, _debuggerOptions.commandLineArgv = options.commandLineArgv; _debuggerOptions.team = options.team; _debuggerOptions.thread = options.thread; + _debuggerOptions.coreFilePath = options.coreFilePath; + + if (options.coreFilePath != NULL) + _debuggerOptions.requestType = TEAM_DEBUGGER_REQUEST_LOAD_CORE; + else if (options.commandLineArgc != 0) + _debuggerOptions.requestType = TEAM_DEBUGGER_REQUEST_CREATE; + else + _debuggerOptions.requestType = TEAM_DEBUGGER_REQUEST_ATTACH; } @@ -256,8 +264,7 @@ global_init(TargetHostInterfaceRoster::Listener* listener) class Debugger : public BApplication, - private TargetHostInterfaceRoster::Listener, - private TeamDebugger::Listener { + private TargetHostInterfaceRoster::Listener { public: Debugger(); ~Debugger(); @@ -274,17 +281,9 @@ private: // TargetHostInterfaceRoster::Listener virtual void TeamDebuggerCountChanged(int32 count); - // TeamDebugger::Listener - virtual void TeamDebuggerStarted(TeamDebugger* debugger); - virtual void TeamDebuggerRestartRequested( - TeamDebugger* debugger); - virtual void TeamDebuggerQuit(TeamDebugger* debugger); - private: status_t _StartNewTeam(TargetHostInterface* interface, const char* teamPath, const char* args); - status_t _LoadCoreFile(const char* coreFilePath, - TeamDebuggerOptions debuggerOptions); private: SettingsManager fSettingsManager; @@ -412,6 +411,7 @@ Debugger::MessageReceived(BMessage* message) } TeamDebuggerOptions options; + options.requestType = TEAM_DEBUGGER_REQUEST_ATTACH; options.settingsManager = &fSettingsManager; options.team = teamID; status_t error = interface->StartTeamDebugger(options); @@ -470,13 +470,9 @@ Debugger::ArgvReceived(int32 argc, char** argv) set_debugger_options_from_options(debuggerOptions, options); debuggerOptions.settingsManager = &fSettingsManager; - if (options.coreFilePath != NULL) { - _LoadCoreFile(options.coreFilePath, debuggerOptions); - } else { - TargetHostInterface* hostInterface - = TargetHostInterfaceRoster::Default()->ActiveInterfaceAt(0); - hostInterface->StartTeamDebugger(debuggerOptions); - } + TargetHostInterface* hostInterface + = TargetHostInterfaceRoster::Default()->ActiveInterfaceAt(0); + hostInterface->StartTeamDebugger(debuggerOptions); } @@ -518,30 +514,6 @@ Debugger::TeamDebuggerCountChanged(int32 count) } -void -Debugger::TeamDebuggerStarted(TeamDebugger* debugger) -{ - // TODO: Dummy for core file support. Managing team debuggers needs to work - // differently. -} - - -void -Debugger::TeamDebuggerRestartRequested(TeamDebugger* debugger) -{ - // TODO: Dummy for core file support. Managing team debuggers needs to work - // differently. -} - - -void -Debugger::TeamDebuggerQuit(TeamDebugger* debugger) -{ - // TODO: Dummy for core file support. Managing team debuggers needs to work - // differently. -} - - status_t Debugger::_StartNewTeam(TargetHostInterface* interface, const char* path, const char* args) @@ -558,6 +530,7 @@ Debugger::_StartNewTeam(TargetHostInterface* interface, const char* path, argVector.Parse(data.String()); TeamDebuggerOptions options; + options.requestType = TEAM_DEBUGGER_REQUEST_CREATE; options.settingsManager = &fSettingsManager; options.commandLineArgc = argVector.ArgumentCount(); if (options.commandLineArgc <= 0) @@ -576,61 +549,6 @@ Debugger::_StartNewTeam(TargetHostInterface* interface, const char* path, } -status_t -Debugger::_LoadCoreFile(const char* coreFilePath, - TeamDebuggerOptions debuggerOptions) -{ - // load the core file - CoreFile* coreFile = new(std::nothrow) CoreFile; - if (coreFile == NULL) - return B_NO_MEMORY; - ObjectDeleter coreFileDeleter(coreFile); - - status_t error = coreFile->Init(coreFilePath); - if (error != B_OK) - return error; - - // create the user interface - UserInterface* userInterface = new(std::nothrow) GraphicalUserInterface; - if (userInterface == NULL) { - fprintf(stderr, "Error: Out of memory!\n"); - return B_NO_MEMORY; - } - BReference userInterfaceReference(userInterface, true); - - // create the debugger interface - CoreFileDebuggerInterface* interface - = new(std::nothrow) CoreFileDebuggerInterface(coreFile); - if (interface == NULL) - return B_NO_MEMORY; - coreFileDeleter.Detach(); - - BReference interfaceReference(interface, true); - error = interface->Init(); - if (error != B_OK) - return error; - - // create the team debugger - TeamDebugger* debugger = new(std::nothrow) TeamDebugger(this, userInterface, - &fSettingsManager); - if (debugger == NULL) - return B_NO_MEMORY; - - const CoreFileTeamInfo& teamInfo = coreFile->GetTeamInfo(); - error = debugger->Init(interface, teamInfo.Id(), 0, NULL, false); - if (error != B_OK) { - fprintf(stderr, "Error: failed to init team debugger for core file " - "\"%s\": %s", coreFilePath, strerror(error)); - delete debugger; - return error; - } - - printf("team debugger for core file \"%s\" created and" - " initialized successfully!\n", coreFilePath); - return B_OK; -} - - // #pragma mark - CliDebugger diff --git a/src/apps/debugger/target_host_interface/TargetHostInterface.cpp b/src/apps/debugger/target_host_interface/TargetHostInterface.cpp index 890bb1ea86..bb933b38fc 100644 --- a/src/apps/debugger/target_host_interface/TargetHostInterface.cpp +++ b/src/apps/debugger/target_host_interface/TargetHostInterface.cpp @@ -20,12 +20,14 @@ TeamDebuggerOptions::TeamDebuggerOptions() : + requestType(TEAM_DEBUGGER_REQUEST_UNKNOWN), commandLineArgc(0), commandLineArgv(NULL), team(-1), thread(-1), settingsManager(NULL), - userInterface(NULL) + userInterface(NULL), + coreFilePath(NULL) { } @@ -56,12 +58,12 @@ TargetHostInterface::StartTeamDebugger(const TeamDebuggerOptions& options) { // we only want to stop in main for teams we're responsible for // creating ourselves. - bool stopInMain = options.commandLineArgv != NULL; + bool stopInMain = options.requestType == TEAM_DEBUGGER_REQUEST_CREATE; team_id team = options.team; thread_id thread = options.thread; AutoLocker interfaceLocker(this); - if (options.commandLineArgc > 0) { + if (options.requestType == TEAM_DEBUGGER_REQUEST_CREATE) { status_t error = CreateTeam(options.commandLineArgc, options.commandLineArgv, team); if (error != B_OK) @@ -69,19 +71,22 @@ TargetHostInterface::StartTeamDebugger(const TeamDebuggerOptions& options) thread = team; } - if (team < 0 && thread < 0) - return B_BAD_VALUE; + if (options.requestType != TEAM_DEBUGGER_REQUEST_LOAD_CORE) { - if (team < 0) { - status_t error = FindTeamByThread(thread, team); - if (error != B_OK) - return error; - } + if (team < 0 && thread < 0) + return B_BAD_VALUE; - TeamDebugger* debugger = FindTeamDebugger(team); - if (debugger != NULL) { - debugger->Activate(); - return B_OK; + if (team < 0) { + status_t error = FindTeamByThread(thread, team); + if (error != B_OK) + return error; + } + + TeamDebugger* debugger = FindTeamDebugger(team); + if (debugger != NULL) { + debugger->Activate(); + return B_OK; + } } return _StartTeamDebugger(team, options, stopInMain); @@ -243,13 +248,24 @@ TargetHostInterface::_StartTeamDebugger(team_id teamID, DebuggerInterface* interface = NULL; TeamDebugger* debugger = NULL; - status_t error = Attach(teamID, options.thread, interface); - if (error != B_OK) { - fprintf(stderr, "Error: Failed to attach to team %" B_PRId32 ": %s!\n", - teamID, strerror(error)); - return error; + status_t error = B_OK; + if (options.requestType != TEAM_DEBUGGER_REQUEST_LOAD_CORE) { + error = Attach(teamID, options.thread, interface); + if (error != B_OK) { + fprintf(stderr, "Error: Failed to attach to team %" B_PRId32 + ": %s!\n", teamID, strerror(error)); + return error; + } + } else { + error = LoadCore(options.coreFilePath, interface, threadID); + if (error != B_OK) { + fprintf(stderr, "Error: Failed to load core file '%s': %s!\n", + options.coreFilePath, strerror(error)); + return error; + } } + BReference debuggerInterfaceReference(interface, true); debugger = new(std::nothrow) TeamDebugger(this, userInterface, diff --git a/src/apps/debugger/target_host_interface/TargetHostInterface.h b/src/apps/debugger/target_host_interface/TargetHostInterface.h index dcac3eafb5..88923aa648 100644 --- a/src/apps/debugger/target_host_interface/TargetHostInterface.h +++ b/src/apps/debugger/target_host_interface/TargetHostInterface.h @@ -47,10 +47,13 @@ public: virtual status_t Attach(team_id id, thread_id threadID, DebuggerInterface*& _interface) const = 0; - virtual status_t CreateTeam(int commandLineArgc, const char* const* arguments, team_id& _teamID) const = 0; + virtual status_t LoadCore(const char* coreFilePath, + DebuggerInterface*& _interface, + thread_id& _thread) const = 0; + virtual status_t FindTeamByThread(thread_id thread, team_id& _teamID) const = 0; @@ -104,14 +107,24 @@ public: }; +enum { + TEAM_DEBUGGER_REQUEST_UNKNOWN = 0, + TEAM_DEBUGGER_REQUEST_CREATE, + TEAM_DEBUGGER_REQUEST_ATTACH, + TEAM_DEBUGGER_REQUEST_LOAD_CORE +}; + + struct TeamDebuggerOptions { TeamDebuggerOptions(); + int requestType; int commandLineArgc; const char* const* commandLineArgv; team_id team; thread_id thread; SettingsManager* settingsManager; UserInterface* userInterface; + const char* coreFilePath; }; diff --git a/src/apps/debugger/target_host_interface/local/LocalTargetHostInterface.cpp b/src/apps/debugger/target_host_interface/local/LocalTargetHostInterface.cpp index f55c3f96d2..cc6006f35c 100644 --- a/src/apps/debugger/target_host_interface/local/LocalTargetHostInterface.cpp +++ b/src/apps/debugger/target_host_interface/local/LocalTargetHostInterface.cpp @@ -1,5 +1,6 @@ /* * Copyright 2016, Rene Gollent, rene@gollent.com. + * Copyright 2016, Ingo Weinhold, ingo_weinhold@gmx.de. * Distributed under the terms of the MIT License. */ @@ -12,12 +13,15 @@ #include +#include #include #include #include #include "debug_utils.h" +#include "CoreFile.h" +#include "CoreFileDebuggerInterface.h" #include "LocalDebuggerInterface.h" #include "TargetHost.h" @@ -183,6 +187,41 @@ LocalTargetHostInterface::CreateTeam(int commandLineArgc, } +status_t +LocalTargetHostInterface::LoadCore(const char* coreFilePath, + DebuggerInterface*& _interface, thread_id& _thread) const +{ + // load the core file + CoreFile* coreFile = new(std::nothrow) CoreFile; + if (coreFile == NULL) + return B_NO_MEMORY; + ObjectDeleter coreFileDeleter(coreFile); + + status_t error = coreFile->Init(coreFilePath); + if (error != B_OK) + return error; + + // create the debugger interface + CoreFileDebuggerInterface* interface + = new(std::nothrow) CoreFileDebuggerInterface(coreFile); + if (interface == NULL) + return B_NO_MEMORY; + coreFileDeleter.Detach(); + + BReference interfaceReference(interface, true); + error = interface->Init(); + if (error != B_OK) + return error; + + const CoreFileTeamInfo& teamInfo = coreFile->GetTeamInfo(); + _thread = teamInfo.Id(); + _interface = interface; + interfaceReference.Detach(); + + return B_OK; +} + + status_t LocalTargetHostInterface::FindTeamByThread(thread_id thread, team_id& _teamID) const diff --git a/src/apps/debugger/target_host_interface/local/LocalTargetHostInterface.h b/src/apps/debugger/target_host_interface/local/LocalTargetHostInterface.h index c9f6e7021d..6b8d3c74d6 100644 --- a/src/apps/debugger/target_host_interface/local/LocalTargetHostInterface.h +++ b/src/apps/debugger/target_host_interface/local/LocalTargetHostInterface.h @@ -23,10 +23,13 @@ public: virtual status_t Attach(team_id id, thread_id threadID, DebuggerInterface*& _interface) const; - virtual status_t CreateTeam(int commandLineArgc, const char* const* arguments, team_id& _teamID) const; + virtual status_t LoadCore(const char* coreFilePath, + DebuggerInterface*& _interface, + thread_id& _thread) const; + virtual status_t FindTeamByThread(thread_id thread, team_id& _teamID) const;