Revert "Revert "[LLDB][GUI] Expand selected thread tree item by default""

This reverts commit fd18f0e84c.

I reverted this change to see its effect on failing GUI tests on LLDB
Arm/AArch64 Linux buildbots. I could not find any evidence against this
particular change so reverting it back.

Differential Revision: https://reviews.llvm.org/D100243
This commit is contained in:
Muhammad Omair Javaid
2021-08-02 05:15:59 +05:00
parent 8f30db8794
commit a94fbb25de
4 changed files with 117 additions and 3 deletions

View File

@@ -3768,8 +3768,13 @@ public:
virtual void TreeDelegateDrawTreeItem(TreeItem &item, Window &window) = 0;
virtual void TreeDelegateGenerateChildren(TreeItem &item) = 0;
virtual void TreeDelegateUpdateSelection(TreeItem &root, int &selection_index,
TreeItem *&selected_item) {
return;
}
virtual bool TreeDelegateItemSelected(
TreeItem &item) = 0; // Return true if we need to update views
virtual bool TreeDelegateExpandRootByDefault() { return false; }
};
typedef std::shared_ptr<TreeDelegate> TreeDelegateSP;
@@ -3779,7 +3784,10 @@ public:
TreeItem(TreeItem *parent, TreeDelegate &delegate, bool might_have_children)
: m_parent(parent), m_delegate(delegate), m_user_data(nullptr),
m_identifier(0), m_row_idx(-1), m_children(),
m_might_have_children(might_have_children), m_is_expanded(false) {}
m_might_have_children(might_have_children), m_is_expanded(false) {
if (m_parent == nullptr)
m_is_expanded = m_delegate.TreeDelegateExpandRootByDefault();
}
TreeItem &operator=(const TreeItem &rhs) {
if (this != &rhs) {
@@ -4008,6 +4016,8 @@ public:
const int num_visible_rows = NumVisibleRows();
m_num_rows = 0;
m_root.CalculateRowIndexes(m_num_rows);
m_delegate_sp->TreeDelegateUpdateSelection(m_root, m_selected_row_idx,
m_selected_item);
// If we unexpanded while having something selected our total number of
// rows is less than the num visible rows, then make sure we show all the
@@ -4309,7 +4319,7 @@ class ThreadsTreeDelegate : public TreeDelegate {
public:
ThreadsTreeDelegate(Debugger &debugger)
: TreeDelegate(), m_thread_delegate_sp(), m_debugger(debugger),
m_stop_id(UINT32_MAX) {
m_stop_id(UINT32_MAX), m_update_selection(false) {
FormatEntity::Parse("process ${process.id}{, name = ${process.name}}",
m_format);
}
@@ -4337,6 +4347,7 @@ public:
void TreeDelegateGenerateChildren(TreeItem &item) override {
ProcessSP process_sp = GetProcess();
m_update_selection = false;
if (process_sp && process_sp->IsAlive()) {
StateType state = process_sp->GetState();
if (StateIsStoppedState(state, true)) {
@@ -4345,6 +4356,7 @@ public:
return; // Children are already up to date
m_stop_id = stop_id;
m_update_selection = true;
if (!m_thread_delegate_sp) {
// Always expand the thread item the first time we show it
@@ -4356,11 +4368,15 @@ public:
TreeItem t(&item, *m_thread_delegate_sp, false);
ThreadList &threads = process_sp->GetThreadList();
std::lock_guard<std::recursive_mutex> guard(threads.GetMutex());
ThreadSP selected_thread = threads.GetSelectedThread();
size_t num_threads = threads.GetSize();
item.Resize(num_threads, t);
for (size_t i = 0; i < num_threads; ++i) {
item[i].SetIdentifier(threads.GetThreadAtIndex(i)->GetID());
ThreadSP thread = threads.GetThreadAtIndex(i);
item[i].SetIdentifier(thread->GetID());
item[i].SetMightHaveChildren(true);
if (selected_thread->GetID() == thread->GetID())
item[i].Expand();
}
return;
}
@@ -4368,12 +4384,42 @@ public:
item.ClearChildren();
}
void TreeDelegateUpdateSelection(TreeItem &root, int &selection_index,
TreeItem *&selected_item) override {
if (!m_update_selection)
return;
ProcessSP process_sp = GetProcess();
if (!(process_sp && process_sp->IsAlive()))
return;
StateType state = process_sp->GetState();
if (!StateIsStoppedState(state, true))
return;
ThreadList &threads = process_sp->GetThreadList();
std::lock_guard<std::recursive_mutex> guard(threads.GetMutex());
ThreadSP selected_thread = threads.GetSelectedThread();
size_t num_threads = threads.GetSize();
for (size_t i = 0; i < num_threads; ++i) {
ThreadSP thread = threads.GetThreadAtIndex(i);
if (selected_thread->GetID() == thread->GetID()) {
selected_item = &root[i][thread->GetSelectedFrameIndex()];
selection_index = selected_item->GetRowIndex();
return;
}
}
}
bool TreeDelegateItemSelected(TreeItem &item) override { return false; }
bool TreeDelegateExpandRootByDefault() override { return true; }
protected:
std::shared_ptr<ThreadTreeDelegate> m_thread_delegate_sp;
Debugger &m_debugger;
uint32_t m_stop_id;
bool m_update_selection;
FormatEntity::Entry m_format;
};

View File

@@ -0,0 +1,3 @@
C_SOURCES := main.c
ENABLE_THREADS := YES
include Makefile.rules

View File

@@ -0,0 +1,55 @@
"""
Test the 'gui' default thread tree expansion.
The root process tree item and the tree item corresponding to the selected
thread should be expanded by default.
"""
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test.lldbpexpect import PExpectTest
class TestGuiExpandThreadsTree(PExpectTest):
mydir = TestBase.compute_mydir(__file__)
# PExpect uses many timeouts internally and doesn't play well
# under ASAN on a loaded machine..
@skipIfAsan
@skipIfCursesSupportMissing
def test_gui(self):
self.build()
self.launch(executable=self.getBuildArtifact("a.out"), dimensions=(100,500))
self.expect("breakpoint set -r thread_start_routine", substrs=["Breakpoint 1", "address ="])
self.expect("run", substrs=["stop reason ="])
escape_key = chr(27).encode()
# Start the GUI and close the welcome window.
self.child.sendline("gui")
self.child.send(escape_key)
self.child.expect_exact("Threads")
# The thread running thread_start_routine should be expanded.
self.child.expect_exact("frame #0: thread_start_routine")
# Exit GUI.
self.child.send(escape_key)
self.expect_prompt()
# Select the main thread.
self.child.sendline("thread select 1")
# Start the GUI.
self.child.sendline("gui")
self.child.expect_exact("Threads")
# The main thread should be expanded.
self.child.expect("frame #\d+: main")
# Quit the GUI
self.child.send(escape_key)
self.expect_prompt()
self.quit()

View File

@@ -0,0 +1,10 @@
#include <pthread.h>
void *thread_start_routine(void *arg) { return NULL; }
int main() {
pthread_t thread;
pthread_create(&thread, NULL, thread_start_routine, NULL);
pthread_join(thread, NULL);
return 0;
}