diff --git a/src/apps/debugger/Debugger.cpp b/src/apps/debugger/Debugger.cpp index 9b2db4333a..62e9650b3b 100644 --- a/src/apps/debugger/Debugger.cpp +++ b/src/apps/debugger/Debugger.cpp @@ -100,6 +100,8 @@ struct Options { struct DebuggedProgramInfo { team_id team; thread_id thread; + int commandLineArgc; + const char* const* commandLineArgv; bool stopInMain; }; @@ -266,6 +268,8 @@ get_debugged_program(const Options& options, DebuggedProgramInfo& _info) } printf("team: %" B_PRId32 ", thread: %" B_PRId32 "\n", team, thread); + _info.commandLineArgc = options.commandLineArgc; + _info.commandLineArgv = options.commandLineArgv; _info.team = team; _info.thread = thread; _info.stopInMain = stopInMain; @@ -281,6 +285,7 @@ get_debugged_program(const Options& options, DebuggedProgramInfo& _info) static TeamDebugger* start_team_debugger(team_id teamID, SettingsManager* settingsManager, TeamDebugger::Listener* listener, thread_id threadID = -1, + int commandLineArgc = 0, const char* const* commandLineArgv = NULL, bool stopInMain = false, UserInterface* userInterface = NULL, status_t* _result = NULL) { @@ -303,8 +308,10 @@ start_team_debugger(team_id teamID, SettingsManager* settingsManager, TeamDebugger* debugger = new(std::nothrow) TeamDebugger(listener, userInterface, settingsManager); - if (debugger) - error = debugger->Init(teamID, threadID, stopInMain); + if (debugger) { + error = debugger->Init(teamID, threadID, commandLineArgc, + commandLineArgv, stopInMain); + } if (error != B_OK) { printf("Error: debugger for team %" B_PRId32 " failed to init: %s!\n", @@ -340,6 +347,8 @@ private: private: // TeamDebugger::Listener virtual void TeamDebuggerStarted(TeamDebugger* debugger); + virtual void TeamDebuggerRestartRequested( + TeamDebugger* debugger); virtual void TeamDebuggerQuit(TeamDebugger* debugger); virtual bool QuitRequested(); @@ -371,6 +380,8 @@ public: private: // TeamDebugger::Listener virtual void TeamDebuggerStarted(TeamDebugger* debugger); + virtual void TeamDebuggerRestartRequested( + TeamDebugger* debugger); virtual void TeamDebuggerQuit(TeamDebugger* debugger); }; @@ -455,6 +466,25 @@ Debugger::MessageReceived(BMessage* message) message->SendReply(&reply); break; } + case MSG_TEAM_RESTART_REQUESTED: + { + int32 teamID; + if (message->FindInt32("team", &teamID) != B_OK) + break; + TeamDebugger* debugger = _FindTeamDebugger(teamID); + if (debugger == NULL) + break; + + Options options; + options.commandLineArgc = debugger->ArgumentCount(); + options.commandLineArgv = debugger->Arguments(); + + status_t result = _StartOrFindTeam(options); + if (result == B_OK) + debugger->PostMessage(B_QUIT_REQUESTED); + + break; + } case MSG_TEAM_DEBUGGER_QUIT: { int32 threadID; @@ -528,6 +558,15 @@ Debugger::TeamDebuggerQuit(TeamDebugger* debugger) } +void +Debugger::TeamDebuggerRestartRequested(TeamDebugger* debugger) +{ + BMessage message(MSG_TEAM_RESTART_REQUESTED); + message.AddInt32("team", debugger->TeamID()); + PostMessage(&message); +} + + bool Debugger::QuitRequested() { @@ -612,7 +651,8 @@ Debugger::_StartOrFindTeam(Options& options) status_t result; start_team_debugger(programInfo.team, &fSettingsManager, this, - programInfo.thread, programInfo.stopInMain, NULL, &result); + programInfo.thread, programInfo.commandLineArgc, + programInfo.commandLineArgv, programInfo.stopInMain, NULL, &result); return result; } @@ -671,8 +711,9 @@ CliDebugger::Run(const Options& options) return false; TeamDebugger* teamDebugger = start_team_debugger(programInfo.team, - &settingsManager, this, programInfo.thread, programInfo.stopInMain, - userInterface); + &settingsManager, this, programInfo.thread, + programInfo.commandLineArgc, programInfo.commandLineArgv, + programInfo.stopInMain, userInterface); if (teamDebugger == NULL) return false; @@ -694,6 +735,13 @@ CliDebugger::TeamDebuggerStarted(TeamDebugger* debugger) } +void +CliDebugger::TeamDebuggerRestartRequested(TeamDebugger* debugger) +{ + // TODO: implement +} + + void CliDebugger::TeamDebuggerQuit(TeamDebugger* debugger) { diff --git a/src/apps/debugger/MessageCodes.h b/src/apps/debugger/MessageCodes.h index ae81129ab3..ccf5e65d34 100644 --- a/src/apps/debugger/MessageCodes.h +++ b/src/apps/debugger/MessageCodes.h @@ -1,5 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef MESSAGE_CODES_H @@ -48,6 +49,7 @@ enum { MSG_VALUE_NODE_VALUE_CHANGED = 'vnvc', MSG_TEAM_DEBUGGER_QUIT = 'dbqt', + MSG_TEAM_RESTART_REQUESTED = 'trrq', MSG_SHOW_TEAMS_WINDOW = 'stsw', MSG_TEAMS_WINDOW_CLOSED = 'tswc', MSG_START_NEW_TEAM = 'sttt', diff --git a/src/apps/debugger/controllers/TeamDebugger.cpp b/src/apps/debugger/controllers/TeamDebugger.cpp index 63d7ba5ee3..3f369afd15 100644 --- a/src/apps/debugger/controllers/TeamDebugger.cpp +++ b/src/apps/debugger/controllers/TeamDebugger.cpp @@ -218,7 +218,9 @@ TeamDebugger::TeamDebugger(Listener* listener, UserInterface* userInterface, fDebugEventListener(-1), fUserInterface(userInterface), fTerminating(false), - fKillTeamOnQuit(false) + fKillTeamOnQuit(false), + fCommandLineArgc(0), + fCommandLineArgv(NULL) { fUserInterface->AcquireReference(); } @@ -293,12 +295,20 @@ TeamDebugger::~TeamDebugger() delete fTeam; delete fFileManager; + for (int i = 0; i < fCommandLineArgc; i++) { + if (fCommandLineArgv[i] != NULL) + free(const_cast(fCommandLineArgv[i])); + } + + delete [] fCommandLineArgv; + fListener->TeamDebuggerQuit(this); } status_t -TeamDebugger::Init(team_id teamID, thread_id threadID, bool stopInMain) +TeamDebugger::Init(team_id teamID, thread_id threadID, int argc, + const char* const* argv, bool stopInMain) { bool targetIsLocal = true; // TODO: Support non-local targets! @@ -308,12 +318,16 @@ TeamDebugger::Init(team_id teamID, thread_id threadID, bool stopInMain) fTeamID = teamID; + status_t error = _HandleSetArguments(argc, argv); + if (error != B_OK) + return error; + // create debugger interface fDebuggerInterface = new(std::nothrow) DebuggerInterface(fTeamID); if (fDebuggerInterface == NULL) return B_NO_MEMORY; - status_t error = fDebuggerInterface->Init(); + error = fDebuggerInterface->Init(); if (error != B_OK) return error; @@ -717,6 +731,25 @@ TeamDebugger::MessageReceived(BMessage* message) Activate(); break; + case MSG_TEAM_RESTART_REQUESTED: + { + if (fCommandLineArgc == 0) + break; + + BString argumentString; + for (int i = 0; i < fCommandLineArgc; i++) { + if (i > 0) + argumentString.Append(" "); + argumentString.Append(fCommandLineArgv[i]); + } + + BMessage startMessage(MSG_START_NEW_TEAM); + startMessage.AddString("path", fCommandLineArgv[0]); + startMessage.AddString("arguments", argumentString); + + break; + } + default: BLooper::MessageReceived(message); break; @@ -1240,11 +1273,19 @@ bool TeamDebugger::_HandleTeamDeleted(TeamDeletedEvent* event) { char message[64]; - snprintf(message, sizeof(message), "Team %" B_PRId32 " has terminated.", + snprintf(message, sizeof(message), "Team %" B_PRId32 " has terminated. ", event->Team()); - fUserInterface->SynchronouslyAskUser("Quit Debugger", message, "Quit", - NULL, NULL); - PostMessage(B_QUIT_REQUESTED); + + int32 result = fUserInterface->SynchronouslyAskUser("Team terminated", + message, "Do nothing", "Quit", fCommandLineArgc != 0 + ? "Restart team" : NULL); + + if (result == 1) + PostMessage(B_QUIT_REQUESTED); + else if (result == 2) { + _SaveSettings(); + fListener->TeamDebuggerRestartRequested(this); + } return true; } @@ -1658,6 +1699,26 @@ TeamDebugger::_HandleInspectAddress(target_addr_t address, } +status_t +TeamDebugger::_HandleSetArguments(int argc, const char* const* argv) +{ + fCommandLineArgc = argc; + fCommandLineArgv = new(std::nothrow) const char*[argc]; + if (fCommandLineArgv == NULL) + return B_NO_MEMORY; + + memset(const_cast(fCommandLineArgv), 0, sizeof(char*) * argc); + + for (int i = 0; i < argc; i++) { + fCommandLineArgv[i] = strdup(argv[i]); + if (fCommandLineArgv[i] == NULL) + return B_NO_MEMORY; + } + + return B_OK; +} + + ThreadHandler* TeamDebugger::_GetThreadHandler(thread_id threadID) { diff --git a/src/apps/debugger/controllers/TeamDebugger.h b/src/apps/debugger/controllers/TeamDebugger.h index 6b5e33b010..57ec4b497c 100644 --- a/src/apps/debugger/controllers/TeamDebugger.h +++ b/src/apps/debugger/controllers/TeamDebugger.h @@ -1,5 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef TEAM_DEBUGGER_H @@ -40,12 +41,19 @@ public: ~TeamDebugger(); status_t Init(team_id teamID, thread_id threadID, + int argc, + const char* const* argv, bool stopInMain); void Activate(); team_id TeamID() const { return fTeamID; } + int ArgumentCount() const + { return fCommandLineArgc; } + const char** Arguments() const + { return fCommandLineArgv; } + virtual void MessageReceived(BMessage* message); private: @@ -153,6 +161,8 @@ private: void _HandleInspectAddress( target_addr_t address, TeamMemoryBlock::Listener* listener); + status_t _HandleSetArguments(int argc, + const char* const* argv); ThreadHandler* _GetThreadHandler(thread_id threadID); @@ -189,6 +199,8 @@ private: volatile bool fTerminating; bool fKillTeamOnQuit; TeamSettings fTeamSettings; + int fCommandLineArgc; + const char** fCommandLineArgv; }; @@ -197,6 +209,8 @@ public: virtual ~Listener(); virtual void TeamDebuggerStarted(TeamDebugger* debugger) = 0; + virtual void TeamDebuggerRestartRequested( + TeamDebugger* debugger) = 0; virtual void TeamDebuggerQuit(TeamDebugger* debugger) = 0; };