[Lldb-commits] [lldb] r204251 - Change the backtrace view into a process tree view where you can expand the process, its threads and see all frames under each thread.

Greg Clayton gclayton at apple.com
Wed Mar 19 09:22:49 PDT 2014


Author: gclayton
Date: Wed Mar 19 11:22:48 2014
New Revision: 204251

URL: http://llvm.org/viewvc/llvm-project?rev=204251&view=rev
Log:
Change the backtrace view into a process tree view where you can expand the process, its threads and see all frames under each thread. 


Modified:
    lldb/trunk/source/Core/IOHandler.cpp

Modified: lldb/trunk/source/Core/IOHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/IOHandler.cpp?rev=204251&r1=204250&r2=204251&view=diff
==============================================================================
--- lldb/trunk/source/Core/IOHandler.cpp (original)
+++ lldb/trunk/source/Core/IOHandler.cpp Wed Mar 19 11:22:48 2014
@@ -15,6 +15,7 @@
 #include "lldb/Breakpoint/BreakpointLocation.h"
 #include "lldb/Core/IOHandler.h"
 #include "lldb/Core/Debugger.h"
+#include "lldb/Core/Module.h"
 #include "lldb/Core/State.h"
 #include "lldb/Core/StreamFile.h"
 #include "lldb/Core/ValueObjectRegister.h"
@@ -2309,6 +2310,7 @@ type summary add -s "${var.origin%S} ${v
                                     ConstString broadcaster_class (broadcaster->GetBroadcasterClass());
                                     if (broadcaster_class == broadcaster_class_process)
                                     {
+                                        debugger.GetCommandInterpreter().UpdateExecutionContext(NULL);
                                         update = true;
                                         continue; // Don't get any key, just update our view
                                     }
@@ -2323,6 +2325,7 @@ type summary add -s "${var.origin%S} ${v
                     switch (key_result)
                     {
                         case eKeyHandled:
+                            debugger.GetCommandInterpreter().UpdateExecutionContext(NULL);
                             update = true;
                             break;
                         case eKeyNotHandled:
@@ -2514,6 +2517,7 @@ public:
     TreeItem (TreeItem *parent, TreeDelegate &delegate, bool might_have_children) :
         m_parent (parent),
         m_delegate (delegate),
+        m_user_data (NULL),
         m_identifier (0),
         m_row_idx (-1),
         m_children (),
@@ -2529,6 +2533,7 @@ public:
         {
             m_parent = rhs.m_parent;
             m_delegate = rhs.m_delegate;
+            m_user_data = rhs.m_user_data;
             m_identifier = rhs.m_identifier;
             m_row_idx = rhs.m_row_idx;
             m_children = rhs.m_children;
@@ -2594,11 +2599,14 @@ public:
         SetRowIndex(row_idx);
         ++row_idx;
 
-        // The root item must calculate its children
-        if (m_parent == NULL)
+        const bool expanded = IsExpanded();
+
+        // The root item must calculate its children,
+        // or we must calculate the number of children
+        // if the item is expanded
+        if (m_parent == NULL || expanded)
             GetNumChildren();
         
-        const bool expanded = IsExpanded();
         for (auto &item : m_children)
         {
             if (expanded)
@@ -2756,17 +2764,18 @@ public:
         return NULL;
     }
     
-//    void *
-//    GetUserData() const
-//    {
-//        return m_user_data;
-//    }
-//    
-//    void
-//    SetUserData (void *user_data)
-//    {
-//        m_user_data = user_data;
-//    }
+    void *
+    GetUserData() const
+    {
+        return m_user_data;
+    }
+    
+    void
+    SetUserData (void *user_data)
+    {
+        m_user_data = user_data;
+    }
+
     uint64_t
     GetIdentifier() const
     {
@@ -2780,10 +2789,16 @@ public:
     }
     
 
+    void
+    SetMightHaveChildren (bool b)
+    {
+        m_might_have_children = b;
+    }
+
 protected:
     TreeItem *m_parent;
     TreeDelegate &m_delegate;
-    //void *m_user_data;
+    void *m_user_data;
     uint64_t m_identifier;
     int m_row_idx; // Zero based visible row index, -1 if not visible or for the root item
     std::vector<TreeItem> m_children;
@@ -3025,12 +3040,9 @@ protected:
 class FrameTreeDelegate : public TreeDelegate
 {
 public:
-    FrameTreeDelegate (const ThreadSP &thread_sp) :
-        TreeDelegate(),
-        m_thread_wp()
+    FrameTreeDelegate () :
+        TreeDelegate()
     {
-        if (thread_sp)
-            m_thread_wp = thread_sp;
     }
     
     virtual ~FrameTreeDelegate()
@@ -3040,11 +3052,11 @@ public:
     virtual void
     TreeDelegateDrawTreeItem (TreeItem &item, Window &window)
     {
-        ThreadSP thread_sp = m_thread_wp.lock();
-        if (thread_sp)
+        Thread* thread = (Thread*)item.GetUserData();
+        if (thread)
         {
             const uint64_t frame_idx = item.GetIdentifier();
-            StackFrameSP frame_sp = thread_sp->GetStackFrameAtIndex(frame_idx);
+            StackFrameSP frame_sp = thread->GetStackFrameAtIndex(frame_idx);
             if (frame_sp)
             {
                 StreamString strm;
@@ -3069,23 +3081,16 @@ public:
     virtual bool
     TreeDelegateItemSelected (TreeItem &item)
     {
-        ThreadSP thread_sp = m_thread_wp.lock();
-        if (thread_sp)
+        Thread* thread = (Thread*)item.GetUserData();
+        if (thread)
         {
+            thread->GetProcess()->GetThreadList().SetSelectedThreadByID(thread->GetID());
             const uint64_t frame_idx = item.GetIdentifier();
-            thread_sp->SetSelectedFrameByIndex(frame_idx);
+            thread->SetSelectedFrameByIndex(frame_idx);
             return true;
         }
         return false;
     }
-    void
-    SetThread (ThreadSP thread_sp)
-    {
-        m_thread_wp = thread_sp;
-    }
-    
-protected:
-    ThreadWP m_thread_wp;
 };
 
 class ThreadTreeDelegate : public TreeDelegate
@@ -3094,7 +3099,6 @@ public:
     ThreadTreeDelegate (Debugger &debugger) :
         TreeDelegate(),
         m_debugger (debugger),
-        m_thread_wp (),
         m_tid (LLDB_INVALID_THREAD_ID),
         m_stop_id (UINT32_MAX)
     {
@@ -3105,10 +3109,25 @@ public:
     {
     }
     
+    ProcessSP
+    GetProcess ()
+    {
+        return m_debugger.GetCommandInterpreter().GetExecutionContext().GetProcessSP();
+    }
+
+    ThreadSP
+    GetThread (const TreeItem &item)
+    {
+        ProcessSP process_sp = GetProcess ();
+        if (process_sp)
+            return process_sp->GetThreadList().FindThreadByID(item.GetIdentifier());
+        return ThreadSP();
+    }
+    
     virtual void
     TreeDelegateDrawTreeItem (TreeItem &item, Window &window)
     {
-        ThreadSP thread_sp = m_thread_wp.lock();
+        ThreadSP thread_sp = GetThread (item);
         if (thread_sp)
         {
             StreamString strm;
@@ -3124,43 +3143,36 @@ public:
     virtual void
     TreeDelegateGenerateChildren (TreeItem &item)
     {
-        TargetSP target_sp (m_debugger.GetSelectedTarget());
-        if (target_sp)
+        ProcessSP process_sp = GetProcess ();
+        if (process_sp && process_sp->IsAlive())
         {
-            ProcessSP process_sp = target_sp->GetProcessSP();
-            if (process_sp && process_sp->IsAlive())
+            StateType state = process_sp->GetState();
+            if (StateIsStoppedState(state, true))
             {
-                StateType state = process_sp->GetState();
-                if (StateIsStoppedState(state, true))
+                ThreadSP thread_sp = GetThread (item);
+                if (thread_sp)
                 {
-                    ThreadSP thread_sp = process_sp->GetThreadList().GetSelectedThread();
-                    if (thread_sp)
-                    {
-                        if (m_stop_id == process_sp->GetStopID() && thread_sp->GetID() == m_tid)
-                            return; // Children are already up to date
-                        if (m_frame_delegate_sp)
-                            m_frame_delegate_sp->SetThread(thread_sp);
-                        else
-                        {
-                            // Always expand the thread item the first time we show it
-                            item.Expand();
-                            m_frame_delegate_sp.reset (new FrameTreeDelegate(thread_sp));
-                        }
+                    if (m_stop_id == process_sp->GetStopID() && thread_sp->GetID() == m_tid)
+                        return; // Children are already up to date
+                    if (!m_frame_delegate_sp)
+                    {
+                        // Always expand the thread item the first time we show it
+                        m_frame_delegate_sp.reset (new FrameTreeDelegate());
+                    }
 
-                        m_stop_id = process_sp->GetStopID();
-                        m_thread_wp = thread_sp;
-                        m_tid = thread_sp->GetID();
-                        
-                        TreeItem t (&item, *m_frame_delegate_sp, false);
-                        size_t num_frames = thread_sp->GetStackFrameCount();
-                        item.Resize (num_frames, t);
-                        for (size_t i=0; i<num_frames; ++i)
-                        {
-                            item[i].SetIdentifier(i);
-                        }
+                    m_stop_id = process_sp->GetStopID();
+                    m_tid = thread_sp->GetID();
+                    
+                    TreeItem t (&item, *m_frame_delegate_sp, false);
+                    size_t num_frames = thread_sp->GetStackFrameCount();
+                    item.Resize (num_frames, t);
+                    for (size_t i=0; i<num_frames; ++i)
+                    {
+                        item[i].SetUserData(thread_sp.get());
+                        item[i].SetIdentifier(i);
                     }
-                    return;
                 }
+                return;
             }
         }
         item.ClearChildren();
@@ -3169,16 +3181,24 @@ public:
     virtual bool
     TreeDelegateItemSelected (TreeItem &item)
     {
-        ThreadSP thread_sp = m_thread_wp.lock();
-        if (thread_sp)
+        ProcessSP process_sp = GetProcess ();
+        if (process_sp && process_sp->IsAlive())
         {
-            ThreadList &thread_list = thread_sp->GetProcess()->GetThreadList();
-            Mutex::Locker locker (thread_list.GetMutex());
-            ThreadSP selected_thread_sp = thread_list.GetSelectedThread();
-            if (selected_thread_sp->GetID() != thread_sp->GetID())
+            StateType state = process_sp->GetState();
+            if (StateIsStoppedState(state, true))
             {
-                thread_list.SetSelectedThreadByID(thread_sp->GetID());
-                return true;
+                ThreadSP thread_sp = GetThread (item);
+                if (thread_sp)
+                {
+                    ThreadList &thread_list = thread_sp->GetProcess()->GetThreadList();
+                    Mutex::Locker locker (thread_list.GetMutex());
+                    ThreadSP selected_thread_sp = thread_list.GetSelectedThread();
+                    if (selected_thread_sp->GetID() != thread_sp->GetID())
+                    {
+                        thread_list.SetSelectedThreadByID(thread_sp->GetID());
+                        return true;
+                    }
+                }
             }
         }
         return false;
@@ -3186,12 +3206,100 @@ public:
 
 protected:
     Debugger &m_debugger;
-    ThreadWP m_thread_wp;
     std::shared_ptr<FrameTreeDelegate> m_frame_delegate_sp;
     lldb::user_id_t m_tid;
     uint32_t m_stop_id;
 };
 
+class ThreadsTreeDelegate : public TreeDelegate
+{
+public:
+    ThreadsTreeDelegate (Debugger &debugger) :
+        TreeDelegate(),
+        m_thread_delegate_sp (),
+        m_debugger (debugger),
+        m_stop_id (UINT32_MAX)
+    {
+    }
+    
+    virtual
+    ~ThreadsTreeDelegate()
+    {
+    }
+    
+    ProcessSP
+    GetProcess ()
+    {
+        return m_debugger.GetCommandInterpreter().GetExecutionContext().GetProcessSP();
+    }
+
+    virtual void
+    TreeDelegateDrawTreeItem (TreeItem &item, Window &window)
+    {
+        ProcessSP process_sp = GetProcess ();
+        if (process_sp && process_sp->IsAlive())
+        {
+            StreamString strm;
+            ExecutionContext exe_ctx (process_sp);
+            const char *format = "process ${process.id}{, name = ${process.name}}";
+            if (Debugger::FormatPrompt (format, NULL, &exe_ctx, NULL, strm))
+            {
+                int right_pad = 1;
+                window.PutCStringTruncated(strm.GetString().c_str(), right_pad);
+            }
+        }
+    }
+
+    virtual void
+    TreeDelegateGenerateChildren (TreeItem &item)
+    {
+        ProcessSP process_sp = GetProcess ();
+        if (process_sp && process_sp->IsAlive())
+        {
+            StateType state = process_sp->GetState();
+            if (StateIsStoppedState(state, true))
+            {
+                const uint32_t stop_id = process_sp->GetStopID();
+                if (m_stop_id == stop_id)
+                    return; // Children are already up to date
+                
+                m_stop_id = stop_id;
+
+                if (!m_thread_delegate_sp)
+                {
+                    // Always expand the thread item the first time we show it
+                    //item.Expand();
+                    m_thread_delegate_sp.reset (new ThreadTreeDelegate(m_debugger));
+                }
+                
+                TreeItem t (&item, *m_thread_delegate_sp, false);
+                ThreadList &threads = process_sp->GetThreadList();
+                Mutex::Locker locker (threads.GetMutex());
+                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());
+                    item[i].SetMightHaveChildren(true);
+                }
+                return;
+            }
+        }
+        item.ClearChildren();
+    }
+    
+    virtual bool
+    TreeDelegateItemSelected (TreeItem &item)
+    {
+        return false;
+    }
+    
+protected:
+    std::shared_ptr<ThreadTreeDelegate> m_thread_delegate_sp;
+    Debugger &m_debugger;
+    uint32_t m_stop_id;
+};
+
 class ValueObjectListDelegate : public WindowDelegate
 {
 public:
@@ -4413,6 +4521,7 @@ public:
         m_disassembly_scope (NULL),
         m_disassembly_sp (),
         m_disassembly_range (),
+        m_title (),
         m_line_width (4),
         m_selected_line (0),
         m_pc_line (0),
@@ -4496,7 +4605,7 @@ public:
         }
         
         m_min_x = 1;
-        m_min_y = 1;
+        m_min_y = 2;
         m_max_x = window.GetMaxX()-1;
         m_max_y = window.GetMaxY()-1;
         
@@ -4533,9 +4642,17 @@ public:
             const bool stop_id_changed = stop_id != m_stop_id;
             bool frame_changed = false;
             m_stop_id = stop_id;
+            m_title.Clear();
             if (frame_sp)
             {
                 m_sc = frame_sp->GetSymbolContext(eSymbolContextEverything);
+                if (m_sc.module_sp)
+                {
+                    m_title.Printf("%s", m_sc.module_sp->GetFileSpec().GetFilename().GetCString());
+                    ConstString func_name = m_sc.GetFunctionName();
+                    if (func_name)
+                        m_title.Printf("`%s", func_name.GetCString());
+                }
                 const uint32_t frame_idx = frame_sp->GetFrameIndex();
                 frame_changed = frame_idx != m_frame_idx;
                 m_frame_idx = frame_idx;
@@ -4657,10 +4774,23 @@ public:
             }
         }
         
-            
+        
+        const int window_width = window.GetWidth();
         window.Erase();
         window.DrawTitleBox ("Sources");
-        
+        if (!m_title.GetString().empty())
+        {
+            window.AttributeOn(A_REVERSE);
+            window.MoveCursor(1, 1);
+            window.PutChar(' ');
+            window.PutCStringTruncated(m_title.GetString().c_str(), 1);
+            int x = window.GetCursorX();
+            if (x < window_width - 1)
+            {
+                window.Printf ("%*s", window_width - x - 1, "");
+            }
+            window.AttributeOff(A_REVERSE);
+        }
 
         Target *target = exe_ctx.GetTargetPtr();
         const size_t num_source_lines = GetNumSourceLines();
@@ -4700,7 +4830,7 @@ public:
                 const uint32_t curr_line = m_first_visible_line + i;
                 if (curr_line < num_source_lines)
                 {
-                    const int line_y = 1+i;
+                    const int line_y = m_min_y+i;
                     window.MoveCursor(1, line_y);
                     const bool is_pc_line = curr_line == m_pc_line;
                     const bool line_is_selected = m_selected_line == curr_line;
@@ -4748,15 +4878,15 @@ public:
                             if (stop_description && stop_description[0])
                             {
                                 size_t stop_description_len = strlen(stop_description);
-                                int desc_x = window.GetWidth() - stop_description_len - 16;
+                                int desc_x = window_width - stop_description_len - 16;
                                 window.Printf ("%*s", desc_x - window.GetCursorX(), "");
-                                //window.MoveCursor(window.GetWidth() - stop_description_len - 15, line_y);
+                                //window.MoveCursor(window_width - stop_description_len - 15, line_y);
                                 window.Printf ("<<< Thread %u: %s ", thread->GetIndexID(), stop_description);
                             }
                         }
                         else
                         {
-                            window.Printf ("%*s", window.GetWidth() - window.GetCursorX() - 1, "");
+                            window.Printf ("%*s", window_width - window.GetCursorX() - 1, "");
                         }
                     }
                     if (highlight_attr)
@@ -4834,7 +4964,8 @@ public:
                     if (!inst)
                         break;
                     
-                    window.MoveCursor(1, i+1);
+                    const int line_y = m_min_y+i;
+                    window.MoveCursor(1, line_y);
                     const bool is_pc_line = frame_sp && inst_idx == pc_idx;
                     const bool line_is_selected = m_selected_line == inst_idx;
                     // Highlight the line as the PC line first, then if the selected line
@@ -4901,15 +5032,15 @@ public:
                             if (stop_description && stop_description[0])
                             {
                                 size_t stop_description_len = strlen(stop_description);
-                                int desc_x = window.GetWidth() - stop_description_len - 16;
+                                int desc_x = window_width - stop_description_len - 16;
                                 window.Printf ("%*s", desc_x - window.GetCursorX(), "");
-                                //window.MoveCursor(window.GetWidth() - stop_description_len - 15, line_y);
+                                //window.MoveCursor(window_width - stop_description_len - 15, line_y);
                                 window.Printf ("<<< Thread %u: %s ", thread->GetIndexID(), stop_description);
                             }
                         }
                         else
                         {
-                            window.Printf ("%*s", window.GetWidth() - window.GetCursorX() - 1, "");
+                            window.Printf ("%*s", window_width - window.GetCursorX() - 1, "");
                         }
                     }
                     if (highlight_attr)
@@ -5142,6 +5273,7 @@ protected:
     SymbolContextScope *m_disassembly_scope;
     lldb::DisassemblerSP m_disassembly_sp;
     AddressRange m_disassembly_range;
+    StreamString m_title;
     lldb::user_id_t m_tid;
     char m_line_format[8];
     int m_line_width;
@@ -5255,7 +5387,7 @@ IOHandlerCursesGUI::Activate ()
         main_window_sp->SetDelegate (std::static_pointer_cast<WindowDelegate>(app_delegate_sp));
         source_window_sp->SetDelegate (WindowDelegateSP(new SourceFileWindowDelegate(m_debugger)));
         variables_window_sp->SetDelegate (WindowDelegateSP(new FrameVariablesWindowDelegate(m_debugger)));
-        TreeDelegateSP thread_delegate_sp (new ThreadTreeDelegate(m_debugger));
+        TreeDelegateSP thread_delegate_sp (new ThreadsTreeDelegate(m_debugger));
         threads_window_sp->SetDelegate (WindowDelegateSP(new TreeWindowDelegate(m_debugger, thread_delegate_sp)));
         status_window_sp->SetDelegate (WindowDelegateSP(new StatusBarWindowDelegate(m_debugger)));
 





More information about the lldb-commits mailing list