[haiku-commits] haiku: hrev49464 - in src/apps/debugger: controllers user_interface/gui/team_window model

  • From: anevilyak@xxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sun, 26 Jul 2015 20:38:29 +0200 (CEST)

hrev49464 adds 5 changesets to branch 'master'
old head: 209cd3dd4fa80d0096cc77f8effa2116eb1e38f8
new head: 9123fde7b9ce627fb4ea6a824fd3151d02b51298
overview:
http://cgit.haiku-os.org/haiku/log/?qt=range&q=9123fde7b9ce+%5E209cd3dd4fa8

----------------------------------------------------------------------------

8f21b175209c: Debugger: Add more helpers to Team.

ClearImages():
- Removes all existing images from the team's image list and notifies callers.
To be used in case of an exec().

ClearSignalDispositionMappings():
- Remove any existing custom signal disposition mappings. This is intended to
be used in preparation for loading new ones from a team after exec() is
called.

25c638c20b7a: Debugger: Adjust ThreadHandler.

- SetBreakpointAndRun() now takes an additional argument indicating if this
invocation is for a fresh run of a team or not, as continuing the thread's
execution needs to be done differently in the two cases.

754b42a5a19e: Debugger: Add rename event for Team.

Team:
- Add listener hook and event type for rename events. These occur on exec()
since at this point we're running a different executable.

TeamWindow:
- Factor out code for generating window title into a helper, and use from both
window initialization and newly implemented rename listener hook.

10bbf8cb8d8b: Debugger: TeamWindow refactor.

- When asked to load settings, post a message and do so in the window's
message loop. This avoids a lock order reversal when asked to do so
later as a result of exec() changing the target image out.

9123fde7b9ce: Debugger: Implement #9783.

TeamDebugger:
- When we're notified that the target team has called exec(), take all
necessary steps to prepare. These include saving settings for the old
team, clearing out breakpoints, resetting signal dispositions, and
removing the old team's image list. Also set a flag indicating an exec
is pending for later processing.
- On image load notification, if the pending flag is set, check if the
new image is the app image, and if so update the team's name to
the new image, load that respective team's settings, and set a
temporary breakpoint in its main() so the user has a chance to
perform any additional desired actions before starting execution
in the new executable.

[ Rene Gollent <rene@xxxxxxxxxxx> ]

----------------------------------------------------------------------------

9 files changed, 232 insertions(+), 77 deletions(-)
src/apps/debugger/MessageCodes.h | 1 +
src/apps/debugger/controllers/TeamDebugger.cpp | 83 +++++++++-
src/apps/debugger/controllers/TeamDebugger.h | 3 +
src/apps/debugger/controllers/ThreadHandler.cpp | 10 +-
src/apps/debugger/controllers/ThreadHandler.h | 3 +-
src/apps/debugger/model/Team.cpp | 32 ++++
src/apps/debugger/model/Team.h | 9 +
.../gui/team_window/TeamWindow.cpp | 163 +++++++++++--------
.../user_interface/gui/team_window/TeamWindow.h | 5 +

############################################################################

Commit: 8f21b175209ccd6c576e7d379e35ecb2debed123
URL: http://cgit.haiku-os.org/haiku/commit/?id=8f21b175209c
Author: Rene Gollent <rene@xxxxxxxxxxx>
Date: Sat Jul 25 21:16:27 2015 UTC

Debugger: Add more helpers to Team.

ClearImages():
- Removes all existing images from the team's image list and notifies callers.
To be used in case of an exec().

ClearSignalDispositionMappings():
- Remove any existing custom signal disposition mappings. This is intended to
be used in preparation for loading new ones from a team after exec() is
called.

----------------------------------------------------------------------------

diff --git a/src/apps/debugger/model/Team.cpp b/src/apps/debugger/model/Team.cpp
index b224778..58c60a7 100644
--- a/src/apps/debugger/model/Team.cpp
+++ b/src/apps/debugger/model/Team.cpp
@@ -277,6 +277,14 @@ Team::Images() const
}


+void
+Team::ClearImages()
+{
+ while (!fImages.IsEmpty())
+ RemoveImage(fImages.First());
+}
+
+
bool
Team::AddStopImageName(const BString& name)
{
@@ -377,6 +385,13 @@ Team::GetSignalDispositionMappings() const
}


+void
+Team::ClearSignalDispositionMappings()
+{
+ fCustomSignalDispositions.clear();
+}
+
+
bool
Team::AddBreakpoint(Breakpoint* breakpoint)
{
diff --git a/src/apps/debugger/model/Team.h b/src/apps/debugger/model/Team.h
index 9891172..d2620e9 100644
--- a/src/apps/debugger/model/Team.h
+++ b/src/apps/debugger/model/Team.h
@@ -137,6 +137,7 @@ public:
Image* ImageByID(image_id
imageID) const;
Image*
ImageByAddress(target_addr_t address) const;
const ImageList& Images() const;
+ void ClearImages();

bool AddStopImageName(const
BString& name);
void
RemoveStopImageName(const BString& name);
@@ -161,6 +162,8 @@ public:
const SignalDispositionMappings&

GetSignalDispositionMappings() const;

+ void
ClearSignalDispositionMappings();
+
bool
AddBreakpoint(Breakpoint* breakpoint);
//
takes over reference (also on error)
void
RemoveBreakpoint(Breakpoint* breakpoint);

############################################################################

Commit: 25c638c20b7a6479c5630b99b55937e4a0aee680
URL: http://cgit.haiku-os.org/haiku/commit/?id=25c638c20b7a
Author: Rene Gollent <rene@xxxxxxxxxxx>
Date: Sat Jul 25 21:17:18 2015 UTC

Debugger: Adjust ThreadHandler.

- SetBreakpointAndRun() now takes an additional argument indicating if this
invocation is for a fresh run of a team or not, as continuing the thread's
execution needs to be done differently in the two cases.

----------------------------------------------------------------------------

diff --git a/src/apps/debugger/controllers/ThreadHandler.cpp
b/src/apps/debugger/controllers/ThreadHandler.cpp
index 838b8ff..361f657 100644
--- a/src/apps/debugger/controllers/ThreadHandler.cpp
+++ b/src/apps/debugger/controllers/ThreadHandler.cpp
@@ -119,16 +119,22 @@ ThreadHandler::Init()


status_t
-ThreadHandler::SetBreakpointAndRun(target_addr_t address)
+ThreadHandler::SetBreakpointAndRun(target_addr_t address, bool initialStart)
{
status_t error = _InstallTemporaryBreakpoint(address);
if (error != B_OK)
return error;

fPreviousInstructionPointer = 0;
- resume_thread(ThreadID());
+ // when the program is first run, the initial thread is not yet under
+ // the control of the debug nub, so it needs to be resumed rather than
+ // continued.
+ if (initialStart) {
+ resume_thread(ThreadID());
// TODO: This should probably better be a DebuggerInterface
method,
// but this method is used only when debugging a local team
anyway.
+ } else
+ fDebuggerInterface->ContinueThread(ThreadID());
// Pretend "step out" mode, so that the temporary breakpoint hit will
not
// be ignored.
fStepMode = STEP_OUT;
diff --git a/src/apps/debugger/controllers/ThreadHandler.h
b/src/apps/debugger/controllers/ThreadHandler.h
index 432eac1..b0b4cdd 100644
--- a/src/apps/debugger/controllers/ThreadHandler.h
+++ b/src/apps/debugger/controllers/ThreadHandler.h
@@ -39,7 +39,8 @@ public:
thread_id ThreadID() const
{ return fThread->ID(); }
Thread* GetThread() const
{ return fThread; }

- status_t
SetBreakpointAndRun(target_addr_t address);
+ status_t
SetBreakpointAndRun(target_addr_t address,
+ bool
initialStart = true);
// team
lock held

// All Handle*() methods are invoked in team debugger
thread,

############################################################################

Commit: 754b42a5a19e0f183356ebf5efab39529f7fcbb0
URL: http://cgit.haiku-os.org/haiku/commit/?id=754b42a5a19e
Author: Rene Gollent <rene@xxxxxxxxxxx>
Date: Sun Jul 26 16:57:15 2015 UTC

Debugger: Add rename event for Team.

Team:
- Add listener hook and event type for rename events. These occur on exec()
since at this point we're running a different executable.

TeamWindow:
- Factor out code for generating window title into a helper, and use from both
window initialization and newly implemented rename listener hook.

----------------------------------------------------------------------------

diff --git a/src/apps/debugger/MessageCodes.h b/src/apps/debugger/MessageCodes.h
index 89604a8..6d08b84 100644
--- a/src/apps/debugger/MessageCodes.h
+++ b/src/apps/debugger/MessageCodes.h
@@ -31,6 +31,7 @@ enum {
MSG_SET_CUSTOM_SIGNAL_DISPOSITION = 'scsd',
MSG_REMOVE_CUSTOM_SIGNAL_DISPOSITION = 'rcsd',

+ MSG_TEAM_RENAMED
= 'tera',
MSG_THREAD_STATE_CHANGED =
'tsch',
MSG_THREAD_CPU_STATE_CHANGED = 'tcsc',
MSG_THREAD_STACK_TRACE_CHANGED = 'tstc',
diff --git a/src/apps/debugger/model/Team.cpp b/src/apps/debugger/model/Team.cpp
index 58c60a7..73ad3bc 100644
--- a/src/apps/debugger/model/Team.cpp
+++ b/src/apps/debugger/model/Team.cpp
@@ -120,6 +120,7 @@ void
Team::SetName(const BString& name)
{
fName = name;
+ _NotifyTeamRenamed();
}


@@ -863,6 +864,16 @@ Team::NotifyMemoryChanged(target_addr_t address,
target_size_t size)


void
+Team::_NotifyTeamRenamed()
+{
+ for (ListenerList::Iterator it = fListeners.GetIterator();
+ Listener* listener = it.Next();) {
+ listener->TeamRenamed(Event(TEAM_EVENT_TEAM_RENAMED, this));
+ }
+}
+
+
+void
Team::_NotifyThreadAdded(Thread* thread)
{
for (ListenerList::Iterator it = fListeners.GetIterator();
@@ -1068,6 +1079,12 @@ Team::Listener::~Listener()


void
+Team::Listener::TeamRenamed(const Team::Event& event)
+{
+}
+
+
+void
Team::Listener::ThreadAdded(const Team::ThreadEvent& event)
{
}
diff --git a/src/apps/debugger/model/Team.h b/src/apps/debugger/model/Team.h
index d2620e9..a5ea092 100644
--- a/src/apps/debugger/model/Team.h
+++ b/src/apps/debugger/model/Team.h
@@ -24,6 +24,8 @@

// team event types
enum {
+ TEAM_EVENT_TEAM_RENAMED,
+
TEAM_EVENT_THREAD_ADDED,
TEAM_EVENT_THREAD_REMOVED,
TEAM_EVENT_IMAGE_ADDED,
@@ -273,6 +275,7 @@ private:
typedef DoublyLinkedList<Listener> ListenerList;

private:
+ void _NotifyTeamRenamed();
void
_NotifyThreadAdded(Thread* thread);
void
_NotifyThreadRemoved(Thread* thread);
void
_NotifyImageAdded(Image* image);
@@ -474,6 +477,9 @@ class Team::Listener : public
DoublyLinkedListLinkImpl<Team::Listener> {
public:
virtual ~Listener();

+ virtual void TeamRenamed(
+ const
Team::Event& event);
+
virtual void ThreadAdded(const
Team::ThreadEvent& event);
virtual void ThreadRemoved(const
Team::ThreadEvent& event);

diff --git a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp
b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp
index ae63b94..ced4988 100644
--- a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp
+++ b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp
@@ -145,12 +145,7 @@ TeamWindow::TeamWindow(::Team* team,
UserInterfaceListener* listener)
fFilePanel(NULL),
fActiveSourceWorker(-1)
{
- fTeam->Lock();
- BString name = fTeam->Name();
- fTeam->Unlock();
- if (fTeam->ID() >= 0)
- name << " (" << fTeam->ID() << ")";
- SetTitle(name.String());
+ _UpdateTitle();

fTeam->AddListener(this);
}
@@ -518,6 +513,11 @@ TeamWindow::MessageReceived(BMessage* message)
}
break;
}
+ case MSG_TEAM_RENAMED:
+ {
+ _UpdateTitle();
+ break;
+ }
case MSG_THREAD_STATE_CHANGED:
{
int32 threadID;
@@ -906,6 +906,13 @@ TeamWindow::ValueNodeWriteRequested(ValueNode* node,
CpuState* state,


void
+TeamWindow::TeamRenamed(const Team::Event& event)
+{
+ PostMessage(MSG_TEAM_RENAMED);
+}
+
+
+void
TeamWindow::ThreadStateChanged(const Team::ThreadEvent& event)
{
BMessage message(MSG_THREAD_STATE_CHANGED);
@@ -1142,6 +1149,18 @@ TeamWindow::_Init()


void
+TeamWindow::_UpdateTitle()
+{
+ AutoLocker< ::Team> lock(fTeam);
+
+ BString name = fTeam->Name();
+ if (fTeam->ID() >= 0)
+ name << " (" << fTeam->ID() << ")";
+ SetTitle(name.String());
+}
+
+
+void
TeamWindow::_SetActiveThread(::Thread* thread)
{
if (thread == fActiveThread)
diff --git a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.h
b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.h
index f8d6018..627f429 100644
--- a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.h
+++ b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.h
@@ -134,6 +134,7 @@ private:

CpuState* state, Value* value);

// Team::Listener
+ virtual void TeamRenamed(const Team::Event&
event);
virtual void ThreadStateChanged(
const
Team::ThreadEvent& event);
virtual void ThreadCpuStateChanged(
@@ -157,6 +158,7 @@ private:

void _Init();

+ void _UpdateTitle();
void
_SetActiveThread(::Thread* thread);
void _SetActiveImage(Image*
image);
void
_SetActiveStackTrace(StackTrace* stackTrace);

############################################################################

Commit: 10bbf8cb8d8bc8eb9e63e87be8dd21f9b73c7937
URL: http://cgit.haiku-os.org/haiku/commit/?id=10bbf8cb8d8b
Author: Rene Gollent <rene@xxxxxxxxxxx>
Date: Sun Jul 26 18:20:04 2015 UTC

Debugger: TeamWindow refactor.

- When asked to load settings, post a message and do so in the window's
message loop. This avoids a lock order reversal when asked to do so
later as a result of exec() changing the target image out.

----------------------------------------------------------------------------

diff --git a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp
b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp
index ced4988..4b7f15e 100644
--- a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp
+++ b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp
@@ -73,7 +73,8 @@ enum {
MSG_DEBUG_REPORT_SAVED = 'drsa',
MSG_LOCATE_SOURCE_IF_NEEDED = 'lsin',
MSG_SOURCE_ENTRY_QUERY_COMPLETE = 'seqc',
- MSG_CLEAR_STACK_TRACE = 'clst'
+ MSG_CLEAR_STACK_TRACE = 'clst',
+ MSG_HANDLE_LOAD_SETTINGS = 'hlst'
};


@@ -513,6 +514,17 @@ TeamWindow::MessageReceived(BMessage* message)
}
break;
}
+ case MSG_HANDLE_LOAD_SETTINGS:
+ {
+ GuiTeamUiSettings* settings;
+ if (message->FindPointer("settings",
+ reinterpret_cast<void**>(&settings)) != B_OK) {
+ break;
+ }
+
+ _LoadSettings(settings);
+ break;
+ }
case MSG_TEAM_RENAMED:
{
_UpdateTitle();
@@ -617,64 +629,9 @@ TeamWindow::QuitRequested()
status_t
TeamWindow::LoadSettings(const GuiTeamUiSettings* settings)
{
- AutoLocker<BWindow> lock(this);
- if (!lock.IsLocked())
- return B_ERROR;
-
- BMessage teamWindowSettings;
- // no settings stored yet
- if (settings->Settings("teamWindow", teamWindowSettings) != B_OK)
- return B_OK;
-
- BRect frame;
- if (teamWindowSettings.FindRect("frame", &frame) == B_OK) {
- ResizeTo(frame.Width(), frame.Height());
- MoveTo(frame.left, frame.top);
- }
-
- BMessage archive;
- if (teamWindowSettings.FindMessage("sourceSplit", &archive) == B_OK)
- GuiSettingsUtils::UnarchiveSplitView(archive, fSourceSplitView);
-
- if (teamWindowSettings.FindMessage("functionSplit", &archive) == B_OK)
- GuiSettingsUtils::UnarchiveSplitView(archive,
fFunctionSplitView);
-
- if (teamWindowSettings.FindMessage("imageSplit", &archive) == B_OK)
- GuiSettingsUtils::UnarchiveSplitView(archive, fImageSplitView);
-
- if (teamWindowSettings.FindMessage("threadSplit", &archive) == B_OK)
- GuiSettingsUtils::UnarchiveSplitView(archive, fThreadSplitView);
-
- if (teamWindowSettings.FindMessage("consoleSplit", &archive) == B_OK)
- GuiSettingsUtils::UnarchiveSplitView(archive,
fConsoleSplitView);
-
- if (teamWindowSettings.FindMessage("imageListView", &archive) == B_OK)
- fImageListView->LoadSettings(archive);
-
- if (teamWindowSettings.FindMessage("imageFunctionsView", &archive) ==
B_OK)
- fImageFunctionsView->LoadSettings(archive);
-
- if (teamWindowSettings.FindMessage("threadListView", &archive) == B_OK)
- fThreadListView->LoadSettings(archive);
-
- if (teamWindowSettings.FindMessage("variablesView", &archive) == B_OK)
- fVariablesView->LoadSettings(archive);
-
- if (teamWindowSettings.FindMessage("registersView", &archive) == B_OK)
- fRegistersView->LoadSettings(archive);
-
- if (teamWindowSettings.FindMessage("stackTraceView", &archive) == B_OK)
- fStackTraceView->LoadSettings(archive);
-
- if (teamWindowSettings.FindMessage("breakpointsView", &archive) == B_OK)
- fBreakpointsView->LoadSettings(archive);
-
- if (teamWindowSettings.FindMessage("consoleOutputView", &archive) ==
B_OK)
- fConsoleOutputView->LoadSettings(archive);
-
- fUiSettings = *settings;
-
- return B_OK;
+ BMessage message(MSG_HANDLE_LOAD_SETTINGS);
+ message.AddPointer("settings", settings);
+ return PostMessage(&message);
}


@@ -1149,10 +1106,67 @@ TeamWindow::_Init()


void
+TeamWindow::_LoadSettings(const GuiTeamUiSettings* settings)
+{
+ BMessage teamWindowSettings;
+ // no settings stored yet
+ if (settings->Settings("teamWindow", teamWindowSettings) != B_OK)
+ return;
+
+ BRect frame;
+ if (teamWindowSettings.FindRect("frame", &frame) == B_OK) {
+ ResizeTo(frame.Width(), frame.Height());
+ MoveTo(frame.left, frame.top);
+ }
+
+ BMessage archive;
+ if (teamWindowSettings.FindMessage("sourceSplit", &archive) == B_OK)
+ GuiSettingsUtils::UnarchiveSplitView(archive, fSourceSplitView);
+
+ if (teamWindowSettings.FindMessage("functionSplit", &archive) == B_OK)
+ GuiSettingsUtils::UnarchiveSplitView(archive,
fFunctionSplitView);
+
+ if (teamWindowSettings.FindMessage("imageSplit", &archive) == B_OK)
+ GuiSettingsUtils::UnarchiveSplitView(archive, fImageSplitView);
+
+ if (teamWindowSettings.FindMessage("threadSplit", &archive) == B_OK)
+ GuiSettingsUtils::UnarchiveSplitView(archive, fThreadSplitView);
+
+ if (teamWindowSettings.FindMessage("consoleSplit", &archive) == B_OK)
+ GuiSettingsUtils::UnarchiveSplitView(archive,
fConsoleSplitView);
+
+ if (teamWindowSettings.FindMessage("imageListView", &archive) == B_OK)
+ fImageListView->LoadSettings(archive);
+
+ if (teamWindowSettings.FindMessage("imageFunctionsView", &archive) ==
B_OK)
+ fImageFunctionsView->LoadSettings(archive);
+
+ if (teamWindowSettings.FindMessage("threadListView", &archive) == B_OK)
+ fThreadListView->LoadSettings(archive);
+
+ if (teamWindowSettings.FindMessage("variablesView", &archive) == B_OK)
+ fVariablesView->LoadSettings(archive);
+
+ if (teamWindowSettings.FindMessage("registersView", &archive) == B_OK)
+ fRegistersView->LoadSettings(archive);
+
+ if (teamWindowSettings.FindMessage("stackTraceView", &archive) == B_OK)
+ fStackTraceView->LoadSettings(archive);
+
+ if (teamWindowSettings.FindMessage("breakpointsView", &archive) == B_OK)
+ fBreakpointsView->LoadSettings(archive);
+
+ if (teamWindowSettings.FindMessage("consoleOutputView", &archive) ==
B_OK)
+ fConsoleOutputView->LoadSettings(archive);
+
+ fUiSettings = *settings;
+}
+
+
+void
TeamWindow::_UpdateTitle()
{
AutoLocker< ::Team> lock(fTeam);
-
BString name = fTeam->Name();
if (fTeam->ID() >= 0)
name << " (" << fTeam->ID() << ")";
diff --git a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.h
b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.h
index 627f429..f9be946 100644
--- a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.h
+++ b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.h
@@ -158,6 +158,9 @@ private:

void _Init();

+ void _LoadSettings(
+ const
GuiTeamUiSettings* settings);
+
void _UpdateTitle();
void
_SetActiveThread(::Thread* thread);
void _SetActiveImage(Image*
image);

############################################################################

Revision: hrev49464
Commit: 9123fde7b9ce627fb4ea6a824fd3151d02b51298
URL: http://cgit.haiku-os.org/haiku/commit/?id=9123fde7b9ce
Author: Rene Gollent <rene@xxxxxxxxxxx>
Date: Sat Jul 25 21:18:21 2015 UTC

Ticket: https://dev.haiku-os.org/ticket/9783

Debugger: Implement #9783.

TeamDebugger:
- When we're notified that the target team has called exec(), take all
necessary steps to prepare. These include saving settings for the old
team, clearing out breakpoints, resetting signal dispositions, and
removing the old team's image list. Also set a flag indicating an exec
is pending for later processing.
- On image load notification, if the pending flag is set, check if the
new image is the app image, and if so update the team's name to
the new image, load that respective team's settings, and set a
temporary breakpoint in its main() so the user has a chance to
perform any additional desired actions before starting execution
in the new executable.

----------------------------------------------------------------------------

diff --git a/src/apps/debugger/controllers/TeamDebugger.cpp
b/src/apps/debugger/controllers/TeamDebugger.cpp
index e9d92bb..5bea9ee 100644
--- a/src/apps/debugger/controllers/TeamDebugger.cpp
+++ b/src/apps/debugger/controllers/TeamDebugger.cpp
@@ -231,7 +231,8 @@ TeamDebugger::TeamDebugger(Listener* listener,
UserInterface* userInterface,
fTerminating(false),
fKillTeamOnQuit(false),
fCommandLineArgc(0),
- fCommandLineArgv(NULL)
+ fCommandLineArgv(NULL),
+ fExecPending(false)
{
fUserInterface->AcquireReference();
}
@@ -454,7 +455,8 @@ TeamDebugger::Init(team_id teamID, thread_id threadID, int
argc,
// set team debugging flags
fDebuggerInterface->SetTeamDebuggingFlags(
B_TEAM_DEBUG_THREADS | B_TEAM_DEBUG_IMAGES
- | B_TEAM_DEBUG_POST_SYSCALL | B_TEAM_DEBUG_SIGNALS);
+ | B_TEAM_DEBUG_POST_SYSCALL | B_TEAM_DEBUG_SIGNALS
+ | B_TEAM_DEBUG_TEAM_CREATION);

// get the initial state of the team
AutoLocker< ::Team> teamLocker(fTeam);
@@ -1556,10 +1558,15 @@ TeamDebugger::_HandleDebuggerMessage(DebugEvent* event)
break;
}
case B_DEBUGGER_MESSAGE_TEAM_EXEC:
+ {
TRACE_EVENTS("B_DEBUGGER_MESSAGE_TEAM_EXEC: team: %"
B_PRId32 "\n",
event->Team());
- // TODO: Handle!
+
+ TeamExecEvent* teamEvent
+ = dynamic_cast<TeamExecEvent*>(event);
+ _PrepareForTeamExec(teamEvent);
break;
+ }
case B_DEBUGGER_MESSAGE_THREAD_CREATED:
{
ThreadCreatedEvent* threadEvent
@@ -1850,6 +1857,43 @@ TeamDebugger::_HandlePostSyscall(PostSyscallEvent* event)


void
+TeamDebugger::_PrepareForTeamExec(TeamExecEvent* event)
+{
+ // NB: must be called with team lock held.
+
+ _SaveSettings();
+
+ // when notified of exec, we need to clear out data related
+ // to the old team.
+ const ImageList& images = fTeam->Images();
+
+ for (ImageList::ConstIterator it = images.GetIterator();
+ Image* image = it.Next();) {
+ fBreakpointManager->RemoveImageBreakpoints(image);
+ }
+
+ BObjectList<UserBreakpoint> breakpointsToRemove(20, false);
+ const UserBreakpointList& breakpoints = fTeam->UserBreakpoints();
+ for (UserBreakpointList::ConstIterator it = breakpoints.GetIterator();
+ UserBreakpoint* breakpoint = it.Next();) {
+ breakpointsToRemove.AddItem(breakpoint);
+ breakpoint->AcquireReference();
+ }
+
+ for (int32 i = 0; i < breakpointsToRemove.CountItems(); i++) {
+ UserBreakpoint* breakpoint = breakpointsToRemove.ItemAt(i);
+ fTeam->RemoveUserBreakpoint(breakpoint);
+ fTeam->NotifyUserBreakpointChanged(breakpoint);
+ breakpoint->ReleaseReference();
+ }
+
+ fTeam->ClearImages();
+ fTeam->ClearSignalDispositionMappings();
+ fExecPending = true;
+}
+
+
+void
TeamDebugger::_HandleImageDebugInfoChanged(image_id imageID)
{
// get the image (via the image handler)
@@ -1860,10 +1904,22 @@ TeamDebugger::_HandleImageDebugInfoChanged(image_id
imageID)

Image* image = imageHandler->GetImage();
BReference<Image> imageReference(image);
+ image_debug_info_state state = image->ImageDebugInfoState();
+
+ bool handlePostExecSetup = fExecPending && image->Type() == B_APP_IMAGE
+ && state != IMAGE_DEBUG_INFO_LOADING;
+
+ // this needs to be done first so that breakpoints are loaded.
+ // otherwise, UpdateImageBreakpoints() won't find the appropriate
+ // UserBreakpoints to create/install instances for.
+ if (handlePostExecSetup) {
+ fTeam->SetName(image->Name());
+ _LoadSettings();
+ fExecPending = false;
+ }

locker.Unlock();

- image_debug_info_state state = image->ImageDebugInfoState();
if (state == IMAGE_DEBUG_INFO_LOADED
|| state == IMAGE_DEBUG_INFO_UNAVAILABLE) {
// update breakpoints in the image
@@ -1875,9 +1931,9 @@ TeamDebugger::_HandleImageDebugInfoChanged(image_id
imageID)
fImageInfoPendingThreads->Remove(thread);
ObjectDeleter<ImageInfoPendingThread>
threadDeleter(thread);
locker.Lock();
+ ThreadHandler* handler =
_GetThreadHandler(thread->ThreadID());
+ BReference<ThreadHandler> handlerReference(handler);
if (fTeam->StopOnImageLoad()) {
- ThreadHandler* handler =
_GetThreadHandler(thread->ThreadID());
- BReference<ThreadHandler>
handlerReference(handler);

bool stop = true;
const BString& imageName = image->Name();
@@ -1899,10 +1955,19 @@ TeamDebugger::_HandleImageDebugInfoChanged(image_id
imageID)
return;
} else
locker.Unlock();
- } else
+ } else if (handlePostExecSetup) {
+ // in the case of an exec(), we can't stop in
main() until
+ // the new app image has been loaded, so we
know where to
+ // set the main breakpoint at.
+ SymbolInfo symbolInfo;
+ if
(fDebuggerInterface->GetSymbolInfo(fTeam->ID(), image->ID(),
+ "main", B_SYMBOL_TYPE_TEXT,
symbolInfo) == B_OK) {
+
handler->SetBreakpointAndRun(symbolInfo.Address(), false);
+ }
+ } else {
locker.Unlock();
-
- fDebuggerInterface->ContinueThread(thread->ThreadID());
+
fDebuggerInterface->ContinueThread(thread->ThreadID());
+ }
}
}
}
diff --git a/src/apps/debugger/controllers/TeamDebugger.h
b/src/apps/debugger/controllers/TeamDebugger.h
index 371a0ed..d69e0f5 100644
--- a/src/apps/debugger/controllers/TeamDebugger.h
+++ b/src/apps/debugger/controllers/TeamDebugger.h
@@ -184,6 +184,8 @@ private:
bool _HandlePostSyscall(

PostSyscallEvent* event);

+ void
_PrepareForTeamExec(TeamExecEvent* event);
+
void
_HandleImageDebugInfoChanged(image_id imageID);
void
_HandleImageFileChanged(image_id imageID);

@@ -259,6 +261,7 @@ private:
TeamSettings fTeamSettings;
int
fCommandLineArgc;
const char** fCommandLineArgv;
+ bool fExecPending;
};




Other related posts:

  • » [haiku-commits] haiku: hrev49464 - in src/apps/debugger: controllers user_interface/gui/team_window model - anevilyak