persona0220 created this revision.
persona0220 added reviewers: jj10306, wallace.
Herald added a project: All.
persona0220 requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

This diff is created on top of D137614 <https://reviews.llvm.org/D137614>


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D139969

Files:
  lldb/include/lldb/Target/TraceDumper.h
  lldb/source/Commands/CommandObjectThread.cpp
  lldb/source/Target/TraceDumper.cpp

Index: lldb/source/Target/TraceDumper.cpp
===================================================================
--- lldb/source/Target/TraceDumper.cpp
+++ lldb/source/Target/TraceDumper.cpp
@@ -340,7 +340,7 @@
   }
 }
 
-TraceDumper::TraceItem TraceDumper::CreatRawTraceItem() {
+TraceDumper::TraceItem TraceDumper::CreateRawTraceItem() {
   TraceItem item = {};
   item.id = m_cursor_sp->GetId();
 
@@ -428,7 +428,7 @@
        m_cursor_sp->Next()) {
 
     last_id = m_cursor_sp->GetId();
-    TraceItem item = CreatRawTraceItem();
+    TraceItem item = CreateRawTraceItem();
 
     if (m_cursor_sp->IsEvent() && m_options.show_events) {
       item.event = m_cursor_sp->GetEventType();
@@ -469,246 +469,390 @@
   return last_id;
 }
 
-TraceCallGraphDumper::TraceCallGraphDumper(
-    const TraceCursorSP &cursor_sp, const TraceCallGraphSP &call_graph_sp,
-    Stream &s)
-    : m_cursor_sp(cursor_sp), m_graph_sp(call_graph_sp), m_s(s),
-      m_exe_ctx(cursor_sp->GetExecutionContextRef()) {}
-
 // Overload pattern-based syntax sugar for easier variant matching.
 template <typename... Ts> struct match : Ts... { using Ts::operator()...; };
 template <class... Ts> match(Ts...) -> match<Ts...>;
 
-/// Utility for indenting and writing to a stream in one line.
-static Stream &WithIndent(Stream &s) {
-  s.Indent();
-  return s;
-}
+class GraphOutputWriterCLI : public TraceCallGraphDumper::OutputWriter {
+public:
+  GraphOutputWriterCLI(const TraceCursorSP &cursor_sp,
+      const TraceCallGraphSP &call_graph_sp, Stream &s)
+      : m_cursor_sp(cursor_sp), m_graph_sp(call_graph_sp),
+        m_exe_ctx(cursor_sp->GetExecutionContextRef()), m_s(s) {};
+
+  /// Utility for indenting and writing to a stream in one line.
+  Stream &WithIndent() {
+    m_s.Indent();
+    return m_s;
+  }
 
-/// RAII-based utility for handling indentation and de-indentation of a stream.
-struct AddIndent {
-  AddIndent(Stream &s) : m_s(s) { m_s.IndentMore(); }
-  ~AddIndent() { m_s.IndentLess(); }
+  /// RAII-based utility for handling indentation and de-indentation of a stream.
+  struct AddIndent {
+    AddIndent(Stream &s) : m_s(s) { m_s.IndentMore(); }
+    ~AddIndent() { m_s.IndentLess(); }
 
-private:
-  Stream &m_s;
-};
+  private:
+    Stream &m_s;
+  };
 
-void TraceCallGraphDumper::Dump() {
-  Thread &thread = m_exe_ctx.GetThreadRef();
-  m_s.Format("thread #{0}: tid = {1}\n", thread.GetIndexID(), thread.GetID());
+  void Dump() override {
+    Thread &thread = m_exe_ctx.GetThreadRef();
+    llvm::ArrayRef<TraceCallTreeUP> trees = m_graph_sp->GetTrees();
+    m_s.Format("thread #{0}: tid = {1}\n", thread.GetIndexID(), thread.GetID());
 
-  llvm::ArrayRef<TraceCallTreeUP> trees = m_graph_sp->GetTrees();
-  AddIndent _(m_s);
-  for (size_t i = 0; i < trees.size(); i++) {
-    m_s << "\n";
-    std::visit(
-        match{[&](TraceErrorSegment &errors) {
-                WithIndent(m_s).Format("<subtrace #{0}: tracing errors>\n", i);
-                DumpErrorSegment(errors);
-              },
-              [&](TraceInstructionCallTree &tree) {
-                WithIndent(m_s).Format("<subtrace #{0}: instructions>\n", i);
-                DumpCall(tree.GetRootCall());
-              }},
-        *trees[i]);
+    AddIndent _(m_s);
+    for (size_t i = 0; i < trees.size(); i++) {
+      m_s << "\n";
+      std::visit(
+          match{[&](TraceErrorSegment &errors) {
+            WithIndent().Format("<subtrace #{0}: tracing errors>\n", i);
+            DumpErrorSegment(errors);
+          },
+          [&](TraceInstructionCallTree &tree) {
+            WithIndent().Format("<subtrace #{0}: instructions>\n", i);
+            AddIndent _(m_s);
+            DumpCall(tree.GetRootCall());
+          }},
+          *trees[i]);
+    }
   }
-}
 
-void TraceCallGraphDumper::DumpErrorSegment(TraceErrorSegment &error_segment) {
-  AddIndent _(m_s);
-
-  auto print_error = [&](lldb::user_id_t error_id) {
-    m_cursor_sp->GoToId(error_id);
-    WithIndent(m_s).Format("|{0}: {1}\n", error_id, m_cursor_sp->GetError());
-  };
+private:
+  static const char *ToDisplayString(const ModuleSP &module_sp) {
+    if (const char *str = module_sp->GetFileSpec().GetFilename().AsCString())
+      return str;
+    return "(none)";
+  }
 
-  auto [from, to] = error_segment.GetRange();
-  print_error(from);
-  if (from != to) {
-    uint64_t remaining = error_segment.GetErrorCount() - 2;
-    if (remaining >= 2) {
-      WithIndent(m_s).Format("| ... {0} error{1}\n", remaining,
-                             remaining == 1 ? "" : "s");
+  void DumpErrorSegment(TraceErrorSegment &error_segment) override {
+    AddIndent _(m_s);
+
+    auto print_error = [&](lldb::user_id_t error_id) {
+      m_cursor_sp->GoToId(error_id);
+      WithIndent().Format("|{0}: {1}\n", error_id, m_cursor_sp->GetError());
+    };
+
+    auto [from, to] = error_segment.GetRange();
+    print_error(from);
+    if (from != to) {
+      uint64_t remaining = error_segment.GetErrorCount() - 2;
+      if (remaining >= 2) {
+        WithIndent().Format("| ... {0} error{1}\n", remaining,
+            remaining == 1 ? "" : "s");
+      }
+      print_error(to);
     }
-    print_error(to);
   }
-}
 
-static const char *ToDisplayString(const ModuleSP &module_sp) {
-  if (const char *str = module_sp->GetFileSpec().GetFilename().AsCString())
-    return str;
-  return "(none)";
-}
-
-void TraceCallGraphDumper::DumpCallWrapper(
-    std::function<void()> call_description_dumper,
-    std::function<void(const TraceCursor &cursor)> insn_description_dumper,
-    TraceCall &call_wrapper) {
+  void DumpCall(TraceCall &call) override {
+    std::visit(
+        match{[&](TraceCallInlinedFunction &call) {
+                DumpInlinedFunctionCall(call);
+              },
+              [&](TraceCallFunction &call) { DumpFunctionCall(call); },
+              [&](TraceCallSymbol &call) { DumpSymbolCall(call); },
+              [&](TraceCallSection &call) { DumpSectionCall(call); },
+              [&](TraceCallUnknownRegion &call) { DumpUnknownRegion(call); }},
+        call);
+  }
 
-  WithIndent(m_s) << "-> ";
-  call_description_dumper();
-  m_s << "\n";
+  void DumpCallWrapper(
+      std::function<void()> call_description_dumper,
+      std::function<void(const TraceCursor &cursor)> insn_description_dumper,
+      TraceCall &call_wrapper) {
 
-  auto dump_insn = [&](lldb::user_id_t id) {
-    m_cursor_sp->GoToId(id);
-    WithIndent(m_s).Format(" |{0}: {1:x+16}", id,
-                           m_cursor_sp->GetLoadAddress());
-    insn_description_dumper(*m_cursor_sp);
+    WithIndent() << "-> ";
+    call_description_dumper();
     m_s << "\n";
-  };
 
-  std::visit(
-      [&](auto &&call) {
-        for (const TraceCallSegmentUP &segment_up : call.GetSegments()) {
-          AddIndent _(m_s);
-          if (auto range = segment_up->GetRange()) {
-            auto [from, to] = *range;
-            dump_insn(from);
-            if (from != to) {
-              uint64_t mid_instructions =
-                  segment_up->GetExclusiveInsnCount() - 2;
-              if (mid_instructions >= 1) {
-                WithIndent(m_s).Format(" |... {0} instruction{1}\n",
-                                       mid_instructions,
-                                       mid_instructions == 1 ? "" : "s");
+    auto dump_insn = [&](lldb::user_id_t id) {
+      m_cursor_sp->GoToId(id);
+      WithIndent().Format(" |{0}: {1:x+16}", id,
+                             m_cursor_sp->GetLoadAddress());
+      insn_description_dumper(*m_cursor_sp);
+      m_s << "\n";
+    };
+
+    std::visit(
+        [&](auto &&call) {
+          for (const TraceCallSegmentUP &segment_up : call.GetSegments()) {
+            AddIndent _(m_s);
+            if (auto range = segment_up->GetRange()) {
+              auto [from, to] = *range;
+              dump_insn(from);
+              if (from != to) {
+                uint64_t mid_instructions =
+                    segment_up->GetExclusiveInsnCount() - 2;
+                if (mid_instructions >= 1) {
+                  WithIndent().Format(" |... {0} instruction{1}\n",
+                                         mid_instructions,
+                                         mid_instructions == 1 ? "" : "s");
+                }
+                dump_insn(to);
               }
-              dump_insn(to);
+            }
+            if (TraceCall *child_call = segment_up->GetChildCall()) {
+              AddIndent _(m_s);
+              DumpCall(*child_call);
             }
           }
-          if (TraceCall *child_call = segment_up->GetChildCall()) {
-            DumpCall(*child_call);
-          }
-        }
-      },
-      call_wrapper);
-}
+        },
+        call_wrapper);
+  }
 
-void TraceCallGraphDumper::DumpSectionCall(TraceCallSection &call) {
-  Target &target = m_exe_ctx.GetTargetRef();
-  lldb::addr_t inlined_function_base_address =
-      call.GetSection()->GetLoadBaseAddress(&target);
-
-  DumpCallWrapper([&] { call.GetSection()->DumpName(m_s.AsRawOstream()); },
-                  [&](const TraceCursor &insn) {
-                    if (inlined_function_base_address != LLDB_INVALID_ADDRESS)
-                      m_s.Format(" <+{0}>", insn.GetLoadAddress() -
-                                                inlined_function_base_address);
-                  },
-                  call.GetWrappingCall());
-}
+  void DumpSectionCall(TraceCallSection &call) {
+    Target &target = m_exe_ctx.GetTargetRef();
+    lldb::addr_t inlined_function_base_address =
+        call.GetSection()->GetLoadBaseAddress(&target);
+
+    DumpCallWrapper([&] { call.GetSection()->DumpName(m_s.AsRawOstream()); },
+                    [&](const TraceCursor &insn) {
+                      if (inlined_function_base_address != LLDB_INVALID_ADDRESS)
+                        m_s.Format(" <+{0}>", insn.GetLoadAddress() -
+                                                  inlined_function_base_address);
+                    },
+                    call.GetWrappingCall());
+  }
 
-void TraceCallGraphDumper::DumpInlinedFunctionCall(
-    TraceCallInlinedFunction &call) {
-  Block &inlined_block = call.GetInlinedBlock();
-  Target &target = m_exe_ctx.GetTargetRef();
-
-  lldb::addr_t inlined_function_base_address = LLDB_INVALID_ADDRESS;
-  if (AddressRange range; inlined_block.GetRangeAtIndex(0, range))
-    inlined_function_base_address =
-        range.GetBaseAddress().GetLoadAddress(&target);
-
-  DumpCallWrapper(
-      [&] {
-        m_s.Format("[inlined] {0}`{1}",
-                   ToDisplayString(call.GetOwningFunctionCall()
-                                       .GetFunction()
-                                       .CalculateSymbolContextModule()),
-                   inlined_block.GetInlinedFunctionInfo()->GetName());
-      },
-      [&](const TraceCursor &insn) {
-        lldb::addr_t load_address = insn.GetLoadAddress();
-        AddressRange range;
-        if (inlined_function_base_address != LLDB_INVALID_ADDRESS)
-          m_s.Format(" <+{0}>", load_address - inlined_function_base_address);
-
-        Address addr;
-        if (target.ResolveLoadAddress(load_address, addr)) {
-          LineEntry line_entry;
-          addr.CalculateSymbolContextLineEntry(line_entry);
-
-          if (line_entry.IsValid()) {
-            m_s << " at ";
-            line_entry.DumpStopContext(&m_s, /*show_fullpaths*/ false);
+  void DumpInlinedFunctionCall(
+      TraceCallInlinedFunction &call) {
+    Block &inlined_block = call.GetInlinedBlock();
+    Target &target = m_exe_ctx.GetTargetRef();
+
+    lldb::addr_t inlined_function_base_address = LLDB_INVALID_ADDRESS;
+    if (AddressRange range; inlined_block.GetRangeAtIndex(0, range))
+      inlined_function_base_address =
+          range.GetBaseAddress().GetLoadAddress(&target);
+
+    DumpCallWrapper(
+        [&] {
+          m_s.Format("[inlined] {0}`{1}",
+                     ToDisplayString(call.GetOwningFunctionCall()
+                                         .GetFunction()
+                                         .CalculateSymbolContextModule()),
+                     inlined_block.GetInlinedFunctionInfo()->GetName());
+        },
+        [&](const TraceCursor &insn) {
+          lldb::addr_t load_address = insn.GetLoadAddress();
+          AddressRange range;
+          if (inlined_function_base_address != LLDB_INVALID_ADDRESS)
+            m_s.Format(" <+{0}>", load_address - inlined_function_base_address);
+
+          Address addr;
+          if (target.ResolveLoadAddress(load_address, addr)) {
+            LineEntry line_entry;
+            addr.CalculateSymbolContextLineEntry(line_entry);
+
+            if (line_entry.IsValid()) {
+              m_s << " at ";
+              line_entry.DumpStopContext(&m_s, false);
+            }
           }
-        }
-      },
-      call.GetWrappingCall());
-}
+        },
+        call.GetWrappingCall());
+  }
 
-void TraceCallGraphDumper::DumpFunctionCall(TraceCallFunction &call) {
-  Function &function = call.GetFunction();
-  Target &target = m_exe_ctx.GetTargetRef();
-  lldb::addr_t function_base_address =
-      function.GetAddressRange().GetBaseAddress().GetLoadAddress(&target);
-
-  DumpCallWrapper(
-      [&] {
-        m_s.Format("{0}`{1}",
-                   ToDisplayString(function.CalculateSymbolContextModule()),
-                   function.GetName());
-      },
-      [&](const TraceCursor &insn) {
-        lldb::addr_t load_address = insn.GetLoadAddress();
-        if (function_base_address != LLDB_INVALID_ADDRESS)
-          m_s.Format(" <+{0}>", load_address - function_base_address);
-
-        Address addr;
-        if (target.ResolveLoadAddress(load_address, addr)) {
-          LineEntry line_entry;
-          addr.CalculateSymbolContextLineEntry(line_entry);
-          if (line_entry.IsValid()) {
-            m_s << " at ";
-            line_entry.DumpStopContext(&m_s, /*show_fullpaths*/ false);
+  void DumpFunctionCall(TraceCallFunction &call) {
+    Function &function = call.GetFunction();
+    Target &target = m_exe_ctx.GetTargetRef();
+    lldb::addr_t function_base_address =
+        function.GetAddressRange().GetBaseAddress().GetLoadAddress(&target);
+
+    DumpCallWrapper(
+        [&] {
+          m_s.Format("{0}`{1}",
+                     ToDisplayString(function.CalculateSymbolContextModule()),
+                     function.GetName());
+        },
+        [&](const TraceCursor &insn) {
+          lldb::addr_t load_address = insn.GetLoadAddress();
+          if (function_base_address != LLDB_INVALID_ADDRESS)
+            m_s.Format(" <+{0}>", load_address - function_base_address);
+
+          Address addr;
+          if (target.ResolveLoadAddress(load_address, addr)) {
+            LineEntry line_entry;
+            addr.CalculateSymbolContextLineEntry(line_entry);
+            if (line_entry.IsValid()) {
+              m_s << " at ";
+              line_entry.DumpStopContext(&m_s, false);
+            }
           }
-        }
-      },
-      call.GetWrappingCall());
-}
-
-void TraceCallGraphDumper::DumpSymbolCall(TraceCallSymbol &call) {
-  Symbol &symbol = call.GetSymbol();
-  Target &target = m_exe_ctx.GetTargetRef();
+        },
+        call.GetWrappingCall());
+  }
 
-  DumpCallWrapper(
-      [&] {
-        m_s.Format("{0}`{1}",
-                   ToDisplayString(symbol.CalculateSymbolContextModule()),
-                   symbol.GetName());
-      },
-      [&](const TraceCursor &insn) {
-        lldb::addr_t load_address = insn.GetLoadAddress();
-        lldb::addr_t symbol_offset =
-            load_address - symbol.GetLoadAddress(&target);
-        m_s.Format(" <+{0}>", symbol_offset);
-
-        Address addr;
-        if (target.ResolveLoadAddress(load_address, addr)) {
-          LineEntry line_entry;
-          addr.CalculateSymbolContextLineEntry(line_entry);
-          if (line_entry.IsValid()) {
-            m_s << " at ";
-            line_entry.DumpStopContext(&m_s, /*show_fullpaths*/ false);
+  void DumpSymbolCall(TraceCallSymbol &call) {
+    Symbol &symbol = call.GetSymbol();
+    Target &target = m_exe_ctx.GetTargetRef();
+
+    DumpCallWrapper(
+        [&] {
+          m_s.Format("{0}`{1}",
+                     ToDisplayString(symbol.CalculateSymbolContextModule()),
+                     symbol.GetName());
+        },
+        [&](const TraceCursor &insn) {
+          lldb::addr_t load_address = insn.GetLoadAddress();
+          lldb::addr_t symbol_offset =
+              load_address - symbol.GetLoadAddress(&target);
+          m_s.Format(" <+{0}>", symbol_offset);
+
+          Address addr;
+          if (target.ResolveLoadAddress(load_address, addr)) {
+            LineEntry line_entry;
+            addr.CalculateSymbolContextLineEntry(line_entry);
+            if (line_entry.IsValid()) {
+              m_s << " at ";
+              line_entry.DumpStopContext(&m_s, false);
+            }
           }
+        },
+        call.GetWrappingCall());
+  }
+
+  void DumpUnknownRegion(TraceCallUnknownRegion &call) {
+    DumpCallWrapper([&] { m_s << "unknown region"; },
+                    [&](const TraceCursor &insn) {}, call.GetWrappingCall());
+  }
+
+  lldb::TraceCursorSP m_cursor_sp;
+  lldb::TraceCallGraphSP m_graph_sp;
+  ExecutionContext m_exe_ctx;
+  Stream &m_s;
+};
+
+class GraphOutputWriterJSON : public TraceCallGraphDumper::OutputWriter {
+  /* schema:
+    [                      // array
+      {
+        "error": {
+          "from": decimal,
+          "to": decimal,
+        } ||               // each element in the array is either error or call
+        "function | inline | section | symbol | unknown": { // type of call
+          "segments": [   // child calls
+            {
+              "function | inline | section | symbol | unknown": { // nested
+                ...
+              }
+            } || // each element in the segments is either nested call or insns
+            {
+              "from": start instruction id of this call
+              "to": end instruction id of this call
+            }
+            ...
+          ]
+        }
         }
       },
-      call.GetWrappingCall());
-}
+      ...
+    ]
+   */
+public:
+  GraphOutputWriterJSON(const TraceCursorSP &cursor_sp,
+      const TraceCallGraphSP &call_graph_sp, Stream &s, unsigned indent_size)
+      : m_graph_sp(call_graph_sp), m_s(s),
+        m_j(m_s.AsRawOstream(), indent_size) {
+    m_j.arrayBegin();
+  };
+
+  ~GraphOutputWriterJSON() { m_j.arrayEnd(); }
+
+  void Dump() override {
+    llvm::ArrayRef<TraceCallTreeUP> trees = m_graph_sp->GetTrees();
+
+    for (size_t i = 0; i < trees.size(); i++) {
+      std::visit(
+          match{[&](TraceErrorSegment &errors) {
+            m_j.object([&] {
+              DumpErrorSegment(errors);
+            });
+          },
+          [&](TraceInstructionCallTree &tree) {
+            m_j.object([&] {
+              DumpCall(tree.GetRootCall());
+            });
+          }},
+          *trees[i]);
+    }
+  }
+
+private:
+  void DumpErrorSegment(TraceErrorSegment &error_segment) override {
+    auto range = error_segment.GetRange();
+    m_j.attributeObject("error", [&] {
+        m_j.attribute("from", range.first);
+        m_j.attribute("to", range.second);
+    });
+  }
+
+  void DumpCall(TraceCall &call) override {
+    std::visit(
+        match{[&](TraceCallInlinedFunction &call) {
+                DumpCallWrapper("inline", call.GetWrappingCall());
+              },
+              [&](TraceCallFunction &call) {
+                DumpCallWrapper("function", call.GetWrappingCall());
+              },
+              [&](TraceCallSymbol &call) {
+                DumpCallWrapper("symbol", call.GetWrappingCall());
+              },
+              [&](TraceCallSection &call) {
+                DumpCallWrapper("section", call.GetWrappingCall());
+              },
+              [&](TraceCallUnknownRegion &call) {
+                DumpCallWrapper("unknown", call.GetWrappingCall());
+              }},
+        call);
+  }
+
+  void DumpCallWrapper(const char* name, TraceCall &call_wrapper) {
+    m_j.attributeObject(name, [&] {
+      std::visit(
+        [&](auto &&call) {
+          m_j.attributeArray("segments", [&] {
+            for (const TraceCallSegmentUP &segment_up : call.GetSegments()) {
+              // traced segments
+              if (auto range = segment_up->GetRange()) {
+                m_j.object([&] {
+                  m_j.attribute("from", range->first);
+                  m_j.attribute("to", range->second);
+                });
+              }
 
-void TraceCallGraphDumper::DumpUnknownRegion(TraceCallUnknownRegion &call) {
-  DumpCallWrapper([&] { m_s << "unknown region"; },
-                  [&](const TraceCursor &insn) {}, call.GetWrappingCall());
+              // nested
+              if (TraceCall *child_call = segment_up->GetChildCall()) {
+                m_j.object([&] {
+                  DumpCall(*child_call);
+                });
+              }
+            }
+          });
+        },
+        call_wrapper);
+    });
+  }
+
+  lldb::TraceCallGraphSP m_graph_sp;
+  Stream &m_s;
+  json::OStream m_j;
+};
+
+TraceCallGraphDumper::TraceCallGraphDumper(
+    const TraceCursorSP &cursor_sp, const TraceCallGraphSP &call_graph_sp,
+    Stream &s, const PrintStyle &print_style) {
+    if (print_style == PrintStyle::JSON)
+      m_writer_up = std::unique_ptr<TraceCallGraphDumper::OutputWriter>(
+          new GraphOutputWriterJSON(cursor_sp, call_graph_sp, s, 0));
+    else if (print_style == PrintStyle::PrettyJSON)
+      m_writer_up = std::unique_ptr<TraceCallGraphDumper::OutputWriter>(
+          new GraphOutputWriterJSON(cursor_sp, call_graph_sp, s, 2));
+    else
+      m_writer_up = std::unique_ptr<TraceCallGraphDumper::OutputWriter>(
+          new GraphOutputWriterCLI(cursor_sp, call_graph_sp, s));
 }
 
-void TraceCallGraphDumper::DumpCall(TraceCall &call) {
-  AddIndent _(m_s);
-  std::visit(
-      match{[&](TraceCallInlinedFunction &call) {
-              DumpInlinedFunctionCall(call);
-            },
-            [&](TraceCallFunction &call) { DumpFunctionCall(call); },
-            [&](TraceCallSymbol &call) { DumpSymbolCall(call); },
-            [&](TraceCallSection &call) { DumpSectionCall(call); },
-            [&](TraceCallUnknownRegion &call) { DumpUnknownRegion(call); }},
-      call);
+void TraceCallGraphDumper::Dump() {
+  m_writer_up->Dump();
 }
Index: lldb/source/Commands/CommandObjectThread.cpp
===================================================================
--- lldb/source/Commands/CommandObjectThread.cpp
+++ lldb/source/Commands/CommandObjectThread.cpp
@@ -2116,8 +2116,6 @@
 
 class CommandObjectTraceDumpFunctionCalls : public CommandObjectParsed {
 public:
-  enum class PrintStyle { Normal, JSON, PrettyJSON };
-
   class CommandOptions : public Options {
   public:
     CommandOptions() { OptionParsingStarting(nullptr); }
@@ -2234,7 +2232,8 @@
                            File::eOpenOptionTruncate);
     }
     TraceCallGraphDumper(*cursor_sp, *graph_sp,
-                         out_file ? *out_file : result.GetOutputStream())
+                         out_file ? *out_file : result.GetOutputStream(),
+                         m_options.m_options.print_style)
         .Dump();
 
     return true;
Index: lldb/include/lldb/Target/TraceDumper.h
===================================================================
--- lldb/include/lldb/Target/TraceDumper.h
+++ lldb/include/lldb/Target/TraceDumper.h
@@ -46,6 +46,9 @@
   llvm::Optional<size_t> skip = llvm::None;
 };
 
+/// Simpler dumper options for TraceCallGraphDumper.
+enum class PrintStyle { Normal, JSON, PrettyJSON };
+
 /// Class used to dump the instructions of a \a TraceCursor using its current
 /// state and granularity.
 class TraceDumper {
@@ -119,7 +122,7 @@
 
 private:
   /// Create a trace item for the current position without symbol information.
-  TraceItem CreatRawTraceItem();
+  TraceItem CreateRawTraceItem();
 
   lldb::TraceCursorSP m_cursor_sp;
   TraceDumperOptions m_options;
@@ -130,34 +133,27 @@
 class TraceCallGraphDumper {
 public:
   TraceCallGraphDumper(const lldb::TraceCursorSP &cursor_sp,
-                       const lldb::TraceCallGraphSP &call_graph_sp, Stream &s);
+                       const lldb::TraceCallGraphSP &call_graph_sp, Stream &s,
+                       const PrintStyle &print_style);
 
   void Dump();
 
-private:
-  void DumpErrorSegment(TraceErrorSegment &error_segment);
-
-  void DumpCall(TraceCall &call);
-
-  void DumpFunctionCall(TraceCallFunction &call);
-
-  void DumpSymbolCall(TraceCallSymbol &call);
-
-  void DumpInlinedFunctionCall(TraceCallInlinedFunction &call);
+  /// Interface used to abstract away the format in which the call graph
+  /// will be dumped.
+  class OutputWriter {
+  public:
+    virtual ~OutputWriter() = default;
 
-  void DumpSectionCall(TraceCallSection &call);
+    /// Dump a call graph (call tree or error)
+    virtual void Dump() = 0;
 
-  void DumpUnknownRegion(TraceCallUnknownRegion &call);
+  private:
+    virtual void DumpErrorSegment(TraceErrorSegment &error_segment) = 0;
 
-  void DumpCallWrapper(
-      std::function<void()> call_description_dumper,
-      std::function<void(const TraceCursor &insn)> insn_description_dumper,
-      TraceCall &call_wrapper);
+    virtual void DumpCall(TraceCall &call);
+  };
 
-  lldb::TraceCursorSP m_cursor_sp;
-  lldb::TraceCallGraphSP m_graph_sp;
-  Stream &m_s;
-  ExecutionContext m_exe_ctx;
+  std::unique_ptr<OutputWriter> m_writer_up;
 };
 
 } // namespace lldb_private
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
  • [Lldb-commits] [PATCH] D... Sujin Park via Phabricator via lldb-commits

Reply via email to