hrev51439 adds 2 changesets to branch 'master'
old head: e7b58949815d687cf47e53a50bd5c9451a7e6a41
new head: 456342ca99e43ef8faf5db853d13d6cc258d3ca8
overview:
http://cgit.haiku-os.org/haiku/log/?qt=range&q=456342ca99e4+%5Ee7b58949815d
----------------------------------------------------------------------------
93f521060e78: Revert "Debugger: Implement #10671."
This reverts commit 02c7127cb914cfe9c0ffcf44efba0ea019573731.
456342ca99e4: Debugger: Reimplement #10671.
- Rather than the previous (reverted) approach of tracking the last selected
stack frame from within the StackTraceView, we now do so from the
TeamWindow,
where the selection can be mapped by thread. This fixes a subtle issue
where,
due to a lack of contextual information, the stack trace view would restore
the remembered last selected frame rather than an explicitly chosen one.
This
was most noticeable upon selecting a function that had a corresponding stack
frame in the current stack trace, where, instead of selecting that frame,
the existing one would remain highlighted, even though the state of all
other
views had updated. Found while investigating the cause of #13710.
[ Rene Gollent <rene@xxxxxxxxxxx> ]
----------------------------------------------------------------------------
4 files changed, 166 insertions(+), 165 deletions(-)
.../gui/team_window/StackTraceView.cpp | 138 +--------------
.../gui/team_window/StackTraceView.h | 10 --
.../gui/team_window/TeamWindow.cpp | 166 ++++++++++++++++---
.../user_interface/gui/team_window/TeamWindow.h | 17 +-
############################################################################
Commit: 93f521060e787cee01f28504dde672951e2c7f5e
URL: http://cgit.haiku-os.org/haiku/commit/?id=93f521060e78
Author: Rene Gollent <rene@xxxxxxxxxxx>
Date: Sun Sep 24 19:51:41 2017 UTC
Ticket: https://dev.haiku-os.org/ticket/10671
Revert "Debugger: Implement #10671."
This reverts commit 02c7127cb914cfe9c0ffcf44efba0ea019573731.
----------------------------------------------------------------------------
diff --git
a/src/apps/debugger/user_interface/gui/team_window/StackTraceView.cpp
b/src/apps/debugger/user_interface/gui/team_window/StackTraceView.cpp
index 977c8a6..bbce26e 100644
--- a/src/apps/debugger/user_interface/gui/team_window/StackTraceView.cpp
+++ b/src/apps/debugger/user_interface/gui/team_window/StackTraceView.cpp
@@ -1,6 +1,6 @@
/*
* Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@xxxxxx.
- * Copyright 2011-2014, Rene Gollent, rene@xxxxxxxxxxx.
+ * Copyright 2011-2013, Rene Gollent, rene@xxxxxxxxxxx.
* Distributed under the terms of the MIT License.
*/
@@ -14,8 +14,6 @@
#include <ControlLook.h>
#include <Window.h>
-#include <AutoDeleter.h>
-
#include "table/TableColumns.h"
#include "FunctionInstance.h"
@@ -101,86 +99,6 @@ private:
};
-// #pragma mark - StackTraceKey
-
-
-struct StackTraceView::StackTraceKey {
- StackTrace* stackTrace;
-
- StackTraceKey(StackTrace* stackTrace)
- :
- stackTrace(stackTrace)
- {
- }
-
- uint32 HashValue() const
- {
- return *(uint32*)stackTrace;
- }
-
- bool operator==(const StackTraceKey& other) const
- {
- return stackTrace == other.stackTrace;
- }
-};
-
-
-// #pragma mark - StackTraceSelectionEntry
-
-
-struct StackTraceView::StackTraceSelectionEntry : StackTraceKey {
- StackTraceSelectionEntry* next;
- int32 selectedFrameIndex;
-
- StackTraceSelectionEntry(StackTrace* stackTrace)
- :
- StackTraceKey(stackTrace),
- selectedFrameIndex(0)
- {
- }
-
- inline int32 SelectedFrameIndex() const
- {
- return selectedFrameIndex;
- }
-
- void SetSelectedFrameIndex(int32 index)
- {
- selectedFrameIndex = index;
- }
-};
-
-
-// #pragma mark - StackTraceSelectionEntryHashDefinition
-
-
-struct StackTraceView::StackTraceSelectionEntryHashDefinition {
- typedef StackTraceKey KeyType;
- typedef StackTraceSelectionEntry ValueType;
-
- size_t HashKey(const StackTraceKey& key) const
- {
- return key.HashValue();
- }
-
- size_t Hash(const StackTraceSelectionEntry* value) const
- {
- return value->HashValue();
- }
-
- bool Compare(const StackTraceKey& key,
- const StackTraceSelectionEntry* value) const
- {
- return key == *value;
- }
-
- StackTraceSelectionEntry*& GetLink(StackTraceSelectionEntry* value)
const
- {
- return value->next;
- }
-};
-
-
// #pragma mark - StackTraceView
@@ -191,7 +109,6 @@ StackTraceView::StackTraceView(Listener* listener)
fFramesTable(NULL),
fFramesTableModel(NULL),
fTraceClearPending(false),
- fSelectionInfoTable(NULL),
fListener(listener)
{
SetName("Stack Trace");
@@ -203,7 +120,6 @@ StackTraceView::~StackTraceView()
SetStackTrace(NULL);
fFramesTable->SetTableModel(NULL);
delete fFramesTableModel;
- delete fSelectionInfoTable;
}
@@ -253,25 +169,12 @@ void
StackTraceView::SetStackFrame(StackFrame* stackFrame)
{
if (fStackTrace != NULL && stackFrame != NULL) {
- int32 selectedIndex = -1;
- StackTraceSelectionEntry* entry = fSelectionInfoTable->Lookup(
- fStackTrace);
- if (entry != NULL)
- selectedIndex = entry->SelectedFrameIndex();
- else {
- for (int32 i = 0; StackFrame* other =
fStackTrace->FrameAt(i);
- i++) {
- if (stackFrame == other) {
- selectedIndex = i;
- break;
- }
+ for (int32 i = 0; StackFrame* other = fStackTrace->FrameAt(i);
i++) {
+ if (stackFrame == other) {
+ fFramesTable->SelectRow(i, false);
+ return;
}
}
-
- if (selectedIndex >= 0) {
- fFramesTable->SelectRow(selectedIndex, false);
- return;
- }
}
fFramesTable->DeselectAllRows();
@@ -308,11 +211,6 @@ void
StackTraceView::SetStackTraceClearPending()
{
fTraceClearPending = true;
- StackTraceSelectionEntry* entry =
fSelectionInfoTable->Lookup(fStackTrace);
- if (entry != NULL) {
- fSelectionInfoTable->Remove(entry);
- delete entry;
- }
}
@@ -322,23 +220,8 @@ StackTraceView::TableSelectionChanged(Table* table)
if (fListener == NULL || fTraceClearPending)
return;
- int32 selectedIndex = table->SelectionModel()->RowAt(0);
- StackFrame* frame = fFramesTableModel->FrameAt(selectedIndex);
-
- StackTraceSelectionEntry* entry =
fSelectionInfoTable->Lookup(fStackTrace);
- if (entry == NULL) {
- entry = new(std::nothrow) StackTraceSelectionEntry(fStackTrace);
- if (entry == NULL)
- return;
-
- ObjectDeleter<StackTraceSelectionEntry> entryDeleter(entry);
- if (fSelectionInfoTable->Insert(entry) != B_OK)
- return;
-
- entryDeleter.Detach();
- }
-
- entry->SetSelectedFrameIndex(selectedIndex);
+ StackFrame* frame
+ = fFramesTableModel->FrameAt(table->SelectionModel()->RowAt(0));
fListener->StackFrameSelectionChanged(frame);
}
@@ -347,13 +230,6 @@ StackTraceView::TableSelectionChanged(Table* table)
void
StackTraceView::_Init()
{
- fSelectionInfoTable = new StackTraceSelectionInfoTable;
- if (fSelectionInfoTable->Init() != B_OK) {
- delete fSelectionInfoTable;
- fSelectionInfoTable = NULL;
- throw std::bad_alloc();
- }
-
fFramesTable = new Table("stack trace", 0, B_FANCY_BORDER);
AddChild(fFramesTable->ToView());
fFramesTable->SetSortingEnabled(false);
diff --git a/src/apps/debugger/user_interface/gui/team_window/StackTraceView.h
b/src/apps/debugger/user_interface/gui/team_window/StackTraceView.h
index e0199f7..01cbdde 100644
--- a/src/apps/debugger/user_interface/gui/team_window/StackTraceView.h
+++ b/src/apps/debugger/user_interface/gui/team_window/StackTraceView.h
@@ -1,5 +1,4 @@
/*
- * Copyright 2014, Rene Gollent, rene@xxxxxxxxxxx.
* Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxx.
* Distributed under the terms of the MIT License.
*/
@@ -8,8 +7,6 @@
#include <GroupView.h>
-#include <util/OpenHashTable.h>
-
#include "table/Table.h"
#include "Team.h"
@@ -40,12 +37,6 @@ public:
private:
class FramesTableModel;
- struct StackTraceKey;
- struct StackTraceSelectionEntry;
- struct StackTraceSelectionEntryHashDefinition;
-
- typedef
BOpenHashTable<StackTraceSelectionEntryHashDefinition>
- StackTraceSelectionInfoTable;
private:
// TableListener
@@ -58,7 +49,6 @@ private:
Table* fFramesTable;
FramesTableModel* fFramesTableModel;
bool fTraceClearPending;
- StackTraceSelectionInfoTable* fSelectionInfoTable;
Listener* fListener;
};
############################################################################
Revision: hrev51439
Commit: 456342ca99e43ef8faf5db853d13d6cc258d3ca8
URL: http://cgit.haiku-os.org/haiku/commit/?id=456342ca99e4
Author: Rene Gollent <rene@xxxxxxxxxxx>
Date: Mon Sep 25 00:23:34 2017 UTC
Ticket: https://dev.haiku-os.org/ticket/10671
Ticket: https://dev.haiku-os.org/ticket/13710
Debugger: Reimplement #10671.
- Rather than the previous (reverted) approach of tracking the last selected
stack frame from within the StackTraceView, we now do so from the TeamWindow,
where the selection can be mapped by thread. This fixes a subtle issue where,
due to a lack of contextual information, the stack trace view would restore
the remembered last selected frame rather than an explicitly chosen one. This
was most noticeable upon selecting a function that had a corresponding stack
frame in the current stack trace, where, instead of selecting that frame,
the existing one would remain highlighted, even though the state of all other
views had updated. Found while investigating the cause of #13710.
----------------------------------------------------------------------------
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 94099d1..5a82a3b 100644
--- a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp
+++ b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp
@@ -82,6 +82,97 @@ enum {
};
+// #pragma mark - ThreadStackFrameSelectionKey
+
+
+struct TeamWindow::ThreadStackFrameSelectionKey {
+ ::Thread* thread;
+
+ ThreadStackFrameSelectionKey(::Thread* thread)
+ :
+ thread(thread)
+ {
+ thread->AcquireReference();
+ }
+
+ ~ThreadStackFrameSelectionKey()
+ {
+ thread->ReleaseReference();
+ }
+
+ uint32 HashValue() const
+ {
+ return (uint32)thread->ID();
+ }
+
+ bool operator==(const ThreadStackFrameSelectionKey& other) const
+ {
+ return thread == other.thread;
+ }
+};
+
+
+// #pragma mark - ThreadStackFrameSelectionEntry
+
+
+struct TeamWindow::ThreadStackFrameSelectionEntry
+ : ThreadStackFrameSelectionKey {
+ ThreadStackFrameSelectionEntry* next;
+ StackFrame* selectedFrame;
+
+ ThreadStackFrameSelectionEntry(::Thread* thread, StackFrame* frame)
+ :
+ ThreadStackFrameSelectionKey(thread),
+ selectedFrame(frame)
+ {
+ }
+
+ inline StackFrame* SelectedFrame() const
+ {
+ return selectedFrame;
+ }
+
+ void SetSelectedFrame(StackFrame* frame)
+ {
+ selectedFrame = frame;
+ }
+};
+
+
+// #pragma mark - ThreadStackFrameSelectionEntryHashDefinition
+
+
+struct TeamWindow::ThreadStackFrameSelectionEntryHashDefinition {
+ typedef ThreadStackFrameSelectionKey KeyType;
+ typedef ThreadStackFrameSelectionEntry ValueType;
+
+ size_t HashKey(const ThreadStackFrameSelectionKey& key) const
+ {
+ return key.HashValue();
+ }
+
+ size_t Hash(const ThreadStackFrameSelectionKey* value) const
+ {
+ return value->HashValue();
+ }
+
+ bool Compare(const ThreadStackFrameSelectionKey& key,
+ const ThreadStackFrameSelectionKey* value) const
+ {
+ return key == *value;
+ }
+
+ ThreadStackFrameSelectionEntry*& GetLink(
+ ThreadStackFrameSelectionEntry* value) const
+ {
+ return value->next;
+ }
+};
+
+
+// #pragma mark - PathViewMessageFilter
+
+
class PathViewMessageFilter : public BMessageFilter {
public:
PathViewMessageFilter(BMessenger teamWindow)
@@ -115,6 +206,7 @@ TeamWindow::TeamWindow(::Team* team, UserInterfaceListener*
listener)
fActiveImage(NULL),
fActiveStackTrace(NULL),
fActiveStackFrame(NULL),
+ fThreadSelectionInfoTable(NULL),
fActiveBreakpoint(NULL),
fActiveFunction(NULL),
fActiveSourceCode(NULL),
@@ -190,6 +282,7 @@ TeamWindow::~TeamWindow()
_SetActiveThread(NULL);
delete fFilePanel;
+ delete fThreadSelectionInfoTable;
if (fActiveSourceWorker > 0)
wait_for_thread(fActiveSourceWorker, NULL);
@@ -990,6 +1083,13 @@ TeamWindow::FunctionSourceCodeChanged(Function* function)
void
TeamWindow::_Init()
{
+ fThreadSelectionInfoTable = new ThreadStackFrameSelectionInfoTable;
+ if (fThreadSelectionInfoTable->Init() != B_OK) {
+ delete fThreadSelectionInfoTable;
+ fThreadSelectionInfoTable = NULL;
+ throw std::bad_alloc();
+ }
+
BScrollView* sourceScrollView;
const float splitSpacing = 3.0f;
@@ -1293,10 +1393,17 @@ TeamWindow::_SetActiveStackTrace(StackTrace* stackTrace)
fStackTraceView->SetStackTrace(fActiveStackTrace);
fSourceView->SetStackTrace(fActiveStackTrace, fActiveThread);
- if (fActiveStackTrace != NULL)
- _SetActiveStackFrame(fActiveStackTrace->FrameAt(0));
- else
- _SetActiveStackFrame(NULL);
+ StackFrame* frame = NULL;
+ if (fActiveStackTrace != NULL) {
+ ThreadStackFrameSelectionEntry* entry
+ = fThreadSelectionInfoTable->Lookup(fActiveThread);
+ if (entry != NULL)
+ frame = entry->SelectedFrame();
+ else
+ frame = fActiveStackTrace->FrameAt(0);
+ }
+
+ _SetActiveStackFrame(frame);
}
@@ -1325,7 +1432,21 @@ TeamWindow::_SetActiveStackFrame(StackFrame* frame)
fActiveSourceObject = ACTIVE_SOURCE_STACK_FRAME;
- _SetActiveFunction(fActiveStackFrame->Function());
+ ThreadStackFrameSelectionEntry* entry
+ = fThreadSelectionInfoTable->Lookup(fActiveThread);
+ if (entry == NULL) {
+ entry = new(std::nothrow)
ThreadStackFrameSelectionEntry(
+ fActiveThread, fActiveStackFrame);
+ if (entry == NULL)
+ return;
+
+ ObjectDeleter<ThreadStackFrameSelectionEntry>
entryDeleter(entry);
+ if (fThreadSelectionInfoTable->Insert(entry) == B_OK)
+ entryDeleter.Detach();
+ } else
+ entry->SetSelectedFrame(fActiveStackFrame);
+
+ _SetActiveFunction(fActiveStackFrame->Function(), false);
}
_UpdateCpuState();
@@ -1377,7 +1498,8 @@ TeamWindow::_SetActiveBreakpoint(UserBreakpoint*
breakpoint)
void
-TeamWindow::_SetActiveFunction(FunctionInstance* functionInstance)
+TeamWindow::_SetActiveFunction(FunctionInstance* functionInstance,
+ bool searchForFrame)
{
if (functionInstance == fActiveFunction)
return;
@@ -1428,29 +1550,20 @@ TeamWindow::_SetActiveFunction(FunctionInstance*
functionInstance)
locker.Lock();
- // if we already have an active stack frame at the requested
- // function, we're done. This will be the case if e.g. the function
- // is being set as a result of a call to _SetActiveStackFrame(), and
- // would otherwise lead to issues in recursive cases where the wrong
- // frame might mistakenly be selected.
- if (fActiveStackFrame != NULL
- && fActiveStackFrame->Function() == fActiveFunction) {
+ if (!searchForFrame || fActiveStackTrace == NULL)
return;
- }
// look if our current stack trace has a frame matching the selected
// function. If so, set it to match.
StackFrame* matchingFrame = NULL;
BReference<StackFrame> frameRef;
- if (fActiveStackTrace != NULL) {
- for (int32 i = 0; i < fActiveStackTrace->CountFrames(); i++) {
- StackFrame* frame = fActiveStackTrace->FrameAt(i);
- if (frame->Function() == fActiveFunction) {
- matchingFrame = frame;
- frameRef.SetTo(frame);
- break;
- }
+ for (int32 i = 0; i < fActiveStackTrace->CountFrames(); i++) {
+ StackFrame* frame = fActiveStackTrace->FrameAt(i);
+ if (frame->Function() == fActiveFunction) {
+ matchingFrame = frame;
+ frameRef.SetTo(frame);
+ break;
}
}
@@ -1627,6 +1740,15 @@ TeamWindow::_HandleThreadStateChanged(thread_id threadID)
if (thread == NULL)
return;
+ if (thread->State() != THREAD_STATE_STOPPED) {
+ ThreadStackFrameSelectionEntry* entry
+ = fThreadSelectionInfoTable->Lookup(thread);
+ if (entry != NULL) {
+ fThreadSelectionInfoTable->Remove(entry);
+ delete entry;
+ }
+ }
+
// If the thread has been stopped and we don't have an active thread yet
// (or it isn't stopped), switch to this thread. Otherwise ignore the
event.
if (thread->State() == THREAD_STATE_STOPPED
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 3a16570..c54aee0 100644
--- a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.h
+++ b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.h
@@ -1,6 +1,6 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxx.
- * Copyright 2010-2015, Rene Gollent, rene@xxxxxxxxxxx.
+ * Copyright 2010-2017, Rene Gollent, rene@xxxxxxxxxxx.
* Distributed under the terms of the MIT License.
*/
#ifndef TEAM_WINDOW_H
@@ -10,6 +10,8 @@
#include <String.h>
#include <Window.h>
+#include <util/OpenHashTable.h>
+
#include "BreakpointsView.h"
#include "Function.h"
#include "GuiTeamUiSettings.h"
@@ -83,6 +85,14 @@ private:
ACTIVE_SOURCE_BREAKPOINT
};
+ struct ThreadStackFrameSelectionKey;
+ struct ThreadStackFrameSelectionEntry;
+ struct ThreadStackFrameSelectionEntryHashDefinition;
+
+ typedef BOpenHashTable<ThreadStackFrameSelectionEntryHashDefinition>
+ ThreadStackFrameSelectionInfoTable;
+
+
private:
// ThreadListView::Listener
virtual void
ThreadSelectionChanged(::Thread* thread);
@@ -171,7 +181,8 @@ private:
void
_SetActiveStackFrame(StackFrame* frame);
void _SetActiveBreakpoint(
UserBreakpoint* breakpoint);
- void
_SetActiveFunction(FunctionInstance* function);
+ void
_SetActiveFunction(FunctionInstance* function,
+ bool
searchForFrame = true);
void
_SetActiveSourceCode(SourceCode* sourceCode);
void _UpdateCpuState();
void _UpdateRunButtons();
@@ -209,6 +220,8 @@ private:
Image* fActiveImage;
StackTrace* fActiveStackTrace;
StackFrame* fActiveStackFrame;
+ ThreadStackFrameSelectionInfoTable*
+
fThreadSelectionInfoTable;
UserBreakpoint* fActiveBreakpoint;
FunctionInstance* fActiveFunction;
SourceCode* fActiveSourceCode;