Debugger: Fix #11430.

InspectorWindow:
- Inherit from Team::Listener and implement hook for thread state
  change events.
- On thread state change, if the new state is stopped, and we have
  an active block, release it, and ask to re-inspect.
- Factor out helper function for updating the active block.
- Always ensure the MemoryView is updated when we change blocks.

MemoryView:
- Clean up acquisition of target memory block.

This ensures that the block data is kept up to date when stepping
through code with an inspector window open.
This commit is contained in:
Rene Gollent 2014-11-08 23:28:53 -05:00
parent 1436fe7448
commit 3ea675fc93
3 changed files with 62 additions and 23 deletions

View File

@ -51,15 +51,14 @@ InspectorWindow::InspectorWindow(::Team* team, UserInterfaceListener* listener,
fExpressionInfo(NULL),
fTarget(target)
{
AutoLocker< ::Team> teamLocker(fTeam);
fTeam->AddListener(this);
}
InspectorWindow::~InspectorWindow()
{
if (fCurrentBlock != NULL) {
fCurrentBlock->RemoveListener(this);
fCurrentBlock->ReleaseReference();
}
_SetCurrentBlock(NULL);
if (fLanguage != NULL)
fLanguage->ReleaseReference();
@ -68,6 +67,9 @@ InspectorWindow::~InspectorWindow()
fExpressionInfo->RemoveListener(this);
fExpressionInfo->ReleaseReference();
}
AutoLocker< ::Team> teamLocker(fTeam);
fTeam->RemoveListener(this);
}
@ -206,11 +208,27 @@ InspectorWindow::_Init()
}
void
InspectorWindow::MessageReceived(BMessage* message)
{
switch (message->what) {
case MSG_THREAD_STATE_CHANGED:
{
::Thread* thread;
if (message->FindPointer("thread",
reinterpret_cast<void**>(&thread)) != B_OK) {
break;
}
BReference< ::Thread> threadReference(thread, true);
if (thread->State() == THREAD_STATE_STOPPED) {
if (fCurrentBlock != NULL) {
_SetCurrentBlock(NULL);
_SetToAddress(fCurrentAddress);
}
}
break;
}
case MSG_INSPECT_ADDRESS:
{
target_addr_t address = 0;
@ -226,7 +244,6 @@ InspectorWindow::MessageReceived(BMessage* message)
_SetToAddress(address);
break;
}
case MSG_EXPRESSION_EVALUATED:
{
BString errorMessage;
@ -281,17 +298,8 @@ InspectorWindow::MessageReceived(BMessage* message)
break;
}
{
AutoLocker< ::Team> teamLocker(fTeam);
block->RemoveListener(this);
}
if (result == B_OK) {
if (fCurrentBlock != NULL)
fCurrentBlock->ReleaseReference();
fCurrentBlock = block;
fMemoryView->SetTargetAddress(block, fCurrentAddress);
_SetCurrentBlock(block);
fPreviousBlockButton->SetEnabled(true);
fNextBlockButton->SetEnabled(true);
} else {
@ -329,6 +337,18 @@ InspectorWindow::QuitRequested()
}
void
InspectorWindow::ThreadStateChanged(const Team::ThreadEvent& event)
{
BMessage message(MSG_THREAD_STATE_CHANGED);
BReference< ::Thread> threadReference(event.GetThread());
message.AddPointer("thread", threadReference.Get());
if (PostMessage(&message) == B_OK)
threadReference.Detach();
}
void
InspectorWindow::MemoryBlockRetrieved(TeamMemoryBlock* block)
{
@ -480,3 +500,17 @@ InspectorWindow::_SetToAddress(target_addr_t address)
} else
fMemoryView->SetTargetAddress(fCurrentBlock, address);
}
void
InspectorWindow::_SetCurrentBlock(TeamMemoryBlock* block)
{
AutoLocker< ::Team> teamLocker(fTeam);
if (fCurrentBlock != NULL) {
fCurrentBlock->RemoveListener(this);
fCurrentBlock->ReleaseReference();
}
fCurrentBlock = block;
fMemoryView->SetTargetAddress(fCurrentBlock, fCurrentAddress);
}

View File

@ -24,9 +24,8 @@ class SourceLanguage;
class UserInterfaceListener;
class InspectorWindow : public BWindow,
public TeamMemoryBlock::Listener,
public MemoryView::Listener,
class InspectorWindow : public BWindow, private Team::Listener,
private TeamMemoryBlock::Listener, private MemoryView::Listener,
private ExpressionInfo::Listener {
public:
InspectorWindow(::Team* team,
@ -42,6 +41,10 @@ public:
virtual void MessageReceived(BMessage* message);
virtual bool QuitRequested();
// Team::Listener
virtual void ThreadStateChanged(
const Team::ThreadEvent& event);
// TeamMemoryBlock::Listener
virtual void MemoryBlockRetrieved(TeamMemoryBlock* block);
virtual void MemoryBlockRetrievalFailed(
@ -70,6 +73,7 @@ private:
BMessage& settings);
void _SetToAddress(target_addr_t address);
void _SetCurrentBlock(TeamMemoryBlock* block);
private:
UserInterfaceListener* fListener;

View File

@ -90,12 +90,13 @@ void
MemoryView::SetTargetAddress(TeamMemoryBlock* block, target_addr_t address)
{
fTargetAddress = address;
if (block != fTargetBlock && fTargetBlock != NULL)
fTargetBlock->ReleaseReference();
if (block != fTargetBlock) {
if (fTargetBlock != NULL)
fTargetBlock->ReleaseReference();
fTargetBlock = block;
fTargetBlock->AcquireReference();
if (block != NULL)
fTargetBlock->AcquireReference();
}
MakeFocus(true);