aprantl created this revision.
aprantl added reviewers: jingham, clayborg.
aprantl added a subscriber: lldb-commits.
aprantl set the repository for this revision to rL LLVM.

Here's a fun little idea plus a preliminary patch implementing it.

When I'm debugging programs I often wonder what exactly will happen when I 
step-in. This is particularly a problem with code that has lots of control flow 
happening on a single line, such as a C++ for loop with iterators, a function 
call with a lambda or block definition, or plain old nested function calls.

For example, let's say I'm stopped inside lldb in SourceManager.cpp:93 — I 
would really like to know which function I'll be stepping into next. Will the 
next "step" take me into get(), new, File(), or reset()?

```
   90       // If file_sp is no good or it points to a non-existent file, reset 
it.
   91       if (!file_sp || !file_sp->GetFileSpec().Exists())
   92       {
-> 93           file_sp.reset (new File (file_spec, target_sp.get()));
   94   
   95           if (debugger_sp)
   96               debugger_sp->GetSourceFileCache().AddSourceFile(file_sp);
(lldb) step
```
Of course a debugger cannot predict the future, but what it can do is tell me 
exactly where I am stopped now!
Compilers like clang already include column information in the debug info by 
default. The attached patch makes use of this by adding an underline attribute 
to the character on the current column to indicate the exact breakpoint on the 
current line (here simulated with a caret):

```
   90      // If file_sp is no good or it points to a non-existent file, reset 
it.
   91      if (!file_sp || !file_sp->GetFileSpec().Exists())
   92      {
-> 93          file_sp.reset (new File (file_spec, target_sp.get()));
                                  ^
   94  
   95          if (debugger_sp)
   96              debugger_sp->GetSourceFileCache().AddSourceFile(file_sp);
(lldb) step
```

With this markup I may now assume that "step" will take me into the File() 
constructor. Just what I wanted to know.

This is of course just scratching the surface of what we could do with column 
information, but probably a good starting point. Having a more fine-grained 
visualization, for example, it might be interesting to have "next" take me to 
the next "is_stmt" in the line table instead of always to the next line, and so 
on.

Let me know what you think!

Repository:
  rL LLVM

http://reviews.llvm.org/D20835

Files:
  include/lldb/API/SBSourceManager.h
  include/lldb/Core/SourceManager.h
  scripts/interface/SBSourceManager.i
  scripts/interface/SBStream.i
  source/API/SBSourceManager.cpp
  source/Commands/CommandObjectSource.cpp
  source/Core/Disassembler.cpp
  source/Core/SourceManager.cpp
  source/Target/StackFrame.cpp

Index: source/Target/StackFrame.cpp
===================================================================
--- source/Target/StackFrame.cpp
+++ source/Target/StackFrame.cpp
@@ -1579,6 +1579,7 @@
                 {
                     size_t num_lines = target->GetSourceManager().DisplaySourceLinesWithLineNumbers (m_sc.line_entry.file,
                                                                                       m_sc.line_entry.line,
+                                                                                      m_sc.line_entry.column,
                                                                                       source_lines_before,
                                                                                       source_lines_after,
                                                                                       "->",
Index: source/Core/SourceManager.cpp
===================================================================
--- source/Core/SourceManager.cpp
+++ source/Core/SourceManager.cpp
@@ -22,6 +22,7 @@
 #include "lldb/Symbol/Function.h"
 #include "lldb/Symbol/SymbolContext.h"
 #include "lldb/Target/Target.h"
+#include "lldb/Utility/AnsiTerminal.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -101,6 +102,7 @@
 SourceManager::DisplaySourceLinesWithLineNumbersUsingLastFile (uint32_t start_line,
                                                                uint32_t count,
                                                                uint32_t curr_line,
+                                                               uint32_t curr_column,
                                                                const char* current_line_cstr,
                                                                Stream *s,
                                                                const SymbolContextList *bp_locs)
@@ -152,7 +154,8 @@
                                       prefix,
                                       line == curr_line ? current_line_cstr : "",
                                       line);
-            size_t this_line_size = m_last_file_sp->DisplaySourceLines (line, 0, 0, s);
+            size_t this_line_size =
+                m_last_file_sp->DisplaySourceLines(line, line == curr_line ? curr_column : 0, s);
             if (this_line_size == 0)
             {
                 m_last_line = UINT32_MAX;
@@ -170,6 +173,7 @@
 (
     const FileSpec &file_spec,
     uint32_t line,
+    uint32_t column,
     uint32_t context_before,
     uint32_t context_after,
     const char* current_line_cstr,
@@ -192,7 +196,7 @@
             m_last_line = 0;
         m_last_file_sp = file_sp;
     }
-    return DisplaySourceLinesWithLineNumbersUsingLastFile (start_line, count, line, current_line_cstr, s, bp_locs);
+    return DisplaySourceLinesWithLineNumbersUsingLastFile (start_line, count, line, column, current_line_cstr, s, bp_locs);
 }
 
 size_t
@@ -240,7 +244,7 @@
         else
             m_last_line = 1;
         
-        return DisplaySourceLinesWithLineNumbersUsingLastFile (m_last_line, m_last_count, UINT32_MAX, "", s, bp_locs);
+        return DisplaySourceLinesWithLineNumbersUsingLastFile (m_last_line, m_last_count, UINT32_MAX, UINT32_MAX, "", s, bp_locs);
     }
     return 0;
 }
@@ -548,17 +552,17 @@
 }
 
 size_t
-SourceManager::File::DisplaySourceLines (uint32_t line, uint32_t context_before, uint32_t context_after, Stream *s)
+SourceManager::File::DisplaySourceLines (uint32_t line, uint32_t column, Stream *s)
 {
     // Sanity check m_data_sp before proceeding.
     if (!m_data_sp)
         return 0;
 
-    const uint32_t start_line = line <= context_before ? 1 : line - context_before;
+    const uint32_t start_line = line <= 0 ? 1 : line;
     const uint32_t start_line_offset = GetLineOffset (start_line);
     if (start_line_offset != UINT32_MAX)
     {
-        const uint32_t end_line = line + context_after;
+        const uint32_t end_line = line;
         uint32_t end_line_offset = GetLineOffset (end_line + 1);
         if (end_line_offset == UINT32_MAX)
             end_line_offset = m_data_sp->GetByteSize();
@@ -569,7 +573,20 @@
         {
             size_t count = end_line_offset - start_line_offset;
             const uint8_t *cstr = m_data_sp->GetBytes() + start_line_offset;
-            bytes_written = s->Write(cstr, count);
+            if (column && column < count)
+            {
+                // Mark the current column with an underline.
+                std::string ctl;
+                bytes_written = s->Write(cstr, column-1);
+                ctl = lldb_utility::ansi::FormatAnsiTerminalCodes("${ansi.underline}");
+                bytes_written += s->Write(ctl.c_str(), ctl.length());
+                bytes_written += s->Write(cstr+column-1, 1);
+                ctl = lldb_utility::ansi::FormatAnsiTerminalCodes("${ansi.normal}");
+                bytes_written += s->Write(ctl.c_str(), ctl.length());
+                bytes_written += s->Write(cstr+column, count-column);
+            } else
+              bytes_written = s->Write(cstr, count);
+
             if (!is_newline_char(cstr[count-1]))
                 bytes_written += s->EOL();
         }
Index: source/Core/Disassembler.cpp
===================================================================
--- source/Core/Disassembler.cpp
+++ source/Core/Disassembler.cpp
@@ -475,6 +475,7 @@
                                 {
                                     source_manager.DisplaySourceLinesWithLineNumbers (sc.line_entry.file,
                                                                                       sc.line_entry.line,
+                                                                                      sc.line_entry.column,
                                                                                       num_mixed_context_lines,
                                                                                       num_mixed_context_lines,
                                                                                       ((inst_is_at_pc && (options & eOptionMarkPCSourceLine)) ? "->" : ""),
Index: source/Commands/CommandObjectSource.cpp
===================================================================
--- source/Commands/CommandObjectSource.cpp
+++ source/Commands/CommandObjectSource.cpp
@@ -999,6 +999,7 @@
             result.AppendMessageWithFormat("File: %s\n", start_file.GetPath().c_str());
             return target->GetSourceManager().DisplaySourceLinesWithLineNumbers (start_file,
                                                                                  line_no,
+                                                                                 UINT32_MAX,
                                                                                  0,
                                                                                  m_options.num_lines,
                                                                                  "",
@@ -1279,6 +1280,7 @@
 
                     target->GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.comp_unit,
                                                                                   sc.line_entry.line,
+                                                                                  sc.line_entry.column,
                                                                                   lines_to_back_up,
                                                                                   m_options.num_lines - lines_to_back_up,
                                                                                   "->",
@@ -1327,6 +1329,7 @@
                             m_options.start_line,   // Line to display
                             m_options.num_lines,    // Lines after line to
                             UINT32_MAX,             // Don't mark "line"
+                            UINT32_MAX,             // Don't mark "column"
                             "",                     // Don't mark "line"
                             &result.GetOutputStream(),
                             GetBreakpointLocations ()))
@@ -1477,6 +1480,7 @@
                 
                 target->GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.line_entry.file ? sc.line_entry.file : sc.comp_unit,
                                                                               m_options.start_line,
+                                                                              UINT32_MAX,
                                                                               0,
                                                                               m_options.num_lines,
                                                                               "",
Index: source/API/SBSourceManager.cpp
===================================================================
--- source/API/SBSourceManager.cpp
+++ source/API/SBSourceManager.cpp
@@ -48,6 +48,7 @@
         size_t
         DisplaySourceLinesWithLineNumbers (const lldb_private::FileSpec &file,
                                            uint32_t line,
+                                           uint32_t column,
                                            uint32_t context_before,
                                            uint32_t context_after,
                                            const char *current_line_cstr,
@@ -61,6 +62,7 @@
             {
                 return target_sp->GetSourceManager().DisplaySourceLinesWithLineNumbers (file,
                                                                                         line,
+                                                                                        column,
                                                                                         context_before,
                                                                                         context_after,
                                                                                         current_line_cstr,
@@ -73,6 +75,7 @@
                 {
                     return debugger_sp->GetSourceManager().DisplaySourceLinesWithLineNumbers (file,
                                                                                               line,
+                                                                                              column,
                                                                                               context_before,
                                                                                               context_after,
                                                                                               current_line_cstr,
@@ -126,6 +129,7 @@
 (
     const SBFileSpec &file,
     uint32_t line,
+    uint32_t column,
     uint32_t context_before,
     uint32_t context_after,
     const char *current_line_cstr,
@@ -137,6 +141,7 @@
 
     return m_opaque_ap->DisplaySourceLinesWithLineNumbers (file.ref(),
                                                            line,
+                                                           column,
                                                            context_before,
                                                            context_after,
                                                            current_line_cstr,
Index: scripts/interface/SBStream.i
===================================================================
--- scripts/interface/SBStream.i
+++ scripts/interface/SBStream.i
@@ -24,6 +24,7 @@
         stream = lldb.SBStream()
         source_mgr.DisplaySourceLinesWithLineNumbers(filespec,
                                                      self.line,
+                                                     self.column,
                                                      2, # context before
                                                      2, # context after
                                                      '=>', # prefix for current line
Index: scripts/interface/SBSourceManager.i
===================================================================
--- scripts/interface/SBSourceManager.i
+++ scripts/interface/SBSourceManager.i
@@ -21,6 +21,7 @@
         stream = lldb.SBStream()
         source_mgr.DisplaySourceLinesWithLineNumbers(filespec,
                                                      self.line,
+                                                     self.column,
                                                      2, # context before
                                                      2, # context after
                                                      '=>', # prefix for current line
@@ -45,6 +46,7 @@
     size_t
     DisplaySourceLinesWithLineNumbers (const lldb::SBFileSpec &file,
                                        uint32_t line,
+                                       uint32_t column,
                                        uint32_t context_before,
                                        uint32_t context_after,
                                        const char* current_line_cstr,
Index: include/lldb/Core/SourceManager.h
===================================================================
--- include/lldb/Core/SourceManager.h
+++ include/lldb/Core/SourceManager.h
@@ -40,8 +40,7 @@
 
         size_t
         DisplaySourceLines (uint32_t line,
-                            uint32_t context_before,
-                            uint32_t context_after,
+                            uint32_t column,
                             Stream *s);
         void
         FindLinesMatchingRegex (RegularExpression& regex, 
@@ -135,6 +134,7 @@
     size_t
     DisplaySourceLinesWithLineNumbers(const FileSpec &file,
                                       uint32_t line,
+                                      uint32_t column,
                                       uint32_t context_before,
                                       uint32_t context_after,
                                       const char* current_line_cstr,
@@ -146,6 +146,7 @@
     DisplaySourceLinesWithLineNumbersUsingLastFile(uint32_t start_line,
                                                    uint32_t count,
                                                    uint32_t curr_line,
+                                                   uint32_t curr_column,
                                                    const char* current_line_cstr,
                                                    Stream *s,
                                                    const SymbolContextList *bp_locs = nullptr);
Index: include/lldb/API/SBSourceManager.h
===================================================================
--- include/lldb/API/SBSourceManager.h
+++ include/lldb/API/SBSourceManager.h
@@ -31,6 +31,7 @@
     size_t
     DisplaySourceLinesWithLineNumbers (const lldb::SBFileSpec &file,
                                        uint32_t line,
+                                       uint32_t column,
                                        uint32_t context_before,
                                        uint32_t context_after,
                                        const char* current_line_cstr,
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to