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:
parent
1436fe7448
commit
3ea675fc93
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user