[Lldb-commits] [PATCH] D105717: Create "thread trace dump stats" command

2021-07-09 Thread hanbing wang via Phabricator via lldb-commits
hanbingwang created this revision.
hanbingwang added reviewers: wallace, clayborg.
Herald added a subscriber: dang.
hanbingwang requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

When the user types that command 'thread trace dump stats' and there's a 
running Trace session in LLDB, a raw trace in bytes should be printed.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D105717

Files:
  lldb/include/lldb/Target/Trace.h
  lldb/source/Commands/CommandObjectThread.cpp
  lldb/source/Commands/Options.td
  lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp
  lldb/source/Plugins/Trace/intel-pt/DecodedThread.h
  lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
  lldb/test/API/commands/trace/TestTraceDumpStats.py
  lldb/test/API/commands/trace/TestTraceLoad.py

Index: lldb/test/API/commands/trace/TestTraceLoad.py
===
--- lldb/test/API/commands/trace/TestTraceLoad.py
+++ lldb/test/API/commands/trace/TestTraceLoad.py
@@ -33,7 +33,8 @@
 # check that the Process and Thread objects were created correctly
 self.expect("thread info", substrs=["tid = 3842849"])
 self.expect("thread list", substrs=["Process 1234 stopped", "tid = 3842849"])
-
+self.expect("thread trace dump stats", substrs=['''thread #1: tid = 3842849
+raw trace size 4096'''])
 
 def testLoadInvalidTraces(self):
 src_dir = self.getSourceDir()
Index: lldb/test/API/commands/trace/TestTraceDumpStats.py
===
--- /dev/null
+++ lldb/test/API/commands/trace/TestTraceDumpStats.py
@@ -0,0 +1,39 @@
+import lldb
+from intelpt_testcase import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+from lldbsuite.test.decorators import *
+
+class TestTraceDumpStats(TraceIntelPTTestCaseBase):
+mydir = TestBase.compute_mydir(__file__)
+
+def testErrorMessages(self):
+# We first check the output when there are no targets
+self.expect("thread trace dump stats",
+substrs=["error: invalid target, create a target using the 'target create' command"],
+error=True)
+
+# We now check the output when there's a non-running target
+self.expect("target create " +
+os.path.join(self.getSourceDir(), "intelpt-trace", "a.out"))
+
+self.expect("thread trace dump stats",
+substrs=["error: invalid process"],
+error=True)
+
+# Now we check the output when there's a running target without a trace
+self.expect("b main")
+self.expect("run")
+
+self.expect("thread trace dump stats",
+substrs=["error: Process is not being traced"],
+error=True)
+
+def testDumpRawTraceSize(self):
+self.expect("trace load -v " +
+os.path.join(self.getSourceDir(), "intelpt-trace", "trace.json"),
+substrs=["intel-pt"])
+
+self.expect("thread trace dump stats",
+substrs=['''thread #1: tid = 3842849
+raw trace size 4096'''])
Index: lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
===
--- lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
+++ lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
@@ -67,6 +67,10 @@
 
   lldb::TraceCursorUP GetCursor(Thread &thread) override;
 
+  void DumpTraceStats(Thread &thread, Stream &s, bool verbose) override;
+
+  llvm::Optional GetRawTraceSize(Thread &thread);
+
   void DoRefreshLiveProcessState(
   llvm::Expected state) override;
 
Index: lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
===
--- lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
+++ lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
@@ -108,6 +108,24 @@
   return Decode(thread)->GetCursor();
 }
 
+void TraceIntelPT::DumpTraceStats(Thread &thread, Stream &s, bool verbose) {
+  Optional raw_size = GetRawTraceSize(thread);
+  s.Printf("thread #%u: tid = %" PRIu64, thread.GetIndexID(), thread.GetID());
+  if (!raw_size) {
+s.Printf(", not traced\n");
+return;
+  }
+  s.Printf("\nraw trace size %zu\n", *raw_size);
+  return;
+}
+
+Optional TraceIntelPT::GetRawTraceSize(Thread &thread) {
+  if (IsTraced(thread))
+return Decode(thread)->GetRawTraceSize();
+  else
+return None;
+}
+
 Expected TraceIntelPT::GetCPUInfoForLiveProcess() {
   Expected> cpu_info = GetLiveProcessBinaryData("cpuInfo");
   if (!cpu_info)
Index: lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp
===
--- lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp
+++ lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp
@@ -194,7 +194,7 @@
 
 static Expected>
 De

[Lldb-commits] [PATCH] D105717: [trace] [intel pt] Create a "thread trace dump stats" command

2021-07-16 Thread hanbing wang via Phabricator via lldb-commits
hanbingwang updated this revision to Diff 359253.
hanbingwang edited the summary of this revision.
hanbingwang added a comment.

1. rename "thread trace dump stats" to "thread trace dump info"
2. Additionally, print out the tracing plugin name.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D105717/new/

https://reviews.llvm.org/D105717

Files:
  lldb/include/lldb/Target/Trace.h
  lldb/source/Commands/CommandObjectThread.cpp
  lldb/source/Commands/Options.td
  lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp
  lldb/source/Plugins/Trace/intel-pt/DecodedThread.h
  lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
  lldb/test/API/commands/trace/TestTraceDumpInfo.py
  lldb/test/API/commands/trace/TestTraceLoad.py

Index: lldb/test/API/commands/trace/TestTraceLoad.py
===
--- lldb/test/API/commands/trace/TestTraceLoad.py
+++ lldb/test/API/commands/trace/TestTraceLoad.py
@@ -33,7 +33,9 @@
 # check that the Process and Thread objects were created correctly
 self.expect("thread info", substrs=["tid = 3842849"])
 self.expect("thread list", substrs=["Process 1234 stopped", "tid = 3842849"])
-
+self.expect("thread trace dump info", substrs=['''Tracing technology: intel-pt
+thread #1: tid = 3842849
+Raw trace size: 4096 bytes'''])
 
 def testLoadInvalidTraces(self):
 src_dir = self.getSourceDir()
Index: lldb/test/API/commands/trace/TestTraceDumpInfo.py
===
--- /dev/null
+++ lldb/test/API/commands/trace/TestTraceDumpInfo.py
@@ -0,0 +1,40 @@
+import lldb
+from intelpt_testcase import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+from lldbsuite.test.decorators import *
+
+class TestTraceDumpInfo(TraceIntelPTTestCaseBase):
+mydir = TestBase.compute_mydir(__file__)
+
+def testErrorMessages(self):
+# We first check the output when there are no targets
+self.expect("thread trace dump info",
+substrs=["error: invalid target, create a target using the 'target create' command"],
+error=True)
+
+# We now check the output when there's a non-running target
+self.expect("target create " +
+os.path.join(self.getSourceDir(), "intelpt-trace", "a.out"))
+
+self.expect("thread trace dump info",
+substrs=["error: invalid process"],
+error=True)
+
+# Now we check the output when there's a running target without a trace
+self.expect("b main")
+self.expect("run")
+
+self.expect("thread trace dump info",
+substrs=["error: Process is not being traced"],
+error=True)
+
+def testDumpRawTraceSize(self):
+self.expect("trace load -v " +
+os.path.join(self.getSourceDir(), "intelpt-trace", "trace.json"),
+substrs=["intel-pt"])
+
+self.expect("thread trace dump info",
+substrs=['''Tracing technology: intel-pt
+thread #1: tid = 3842849
+Raw trace size: 4096 bytes'''])
Index: lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
===
--- lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
+++ lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
@@ -67,6 +67,10 @@
 
   lldb::TraceCursorUP GetCursor(Thread &thread) override;
 
+  void DumpTraceInfo(Thread &thread, Stream &s, bool verbose, lldb_private::ConstString plugin_name) override;
+
+  llvm::Optional GetRawTraceSize(Thread &thread);
+
   void DoRefreshLiveProcessState(
   llvm::Expected state) override;
 
Index: lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
===
--- lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
+++ lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
@@ -108,6 +108,24 @@
   return Decode(thread)->GetCursor();
 }
 
+void TraceIntelPT::DumpTraceInfo(Thread &thread, Stream &s, bool verbose, lldb_private::ConstString plugin_name) {
+  Optional raw_size = GetRawTraceSize(thread);
+  s.Printf("Tracing technology: %s\nthread #%u: tid = %" PRIu64, plugin_name.AsCString(), thread.GetIndexID(), thread.GetID());
+  if (!raw_size) {
+s.Printf(", not traced\n");
+return;
+  }
+  s.Printf("\nRaw trace size: %zu bytes\n", *raw_size);
+  return;
+}
+
+Optional TraceIntelPT::GetRawTraceSize(Thread &thread) {
+  if (IsTraced(thread))
+return Decode(thread)->GetRawTraceSize();
+  else
+return None;
+}
+
 Expected TraceIntelPT::GetCPUInfoForLiveProcess() {
   Expected> cpu_info = GetLiveProcessBinaryData("cpuInfo");
   if (!cpu_info)
Index: lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp
===
--- lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp
+++ lldb/so

[Lldb-commits] [PATCH] D105717: [trace] [intel pt] Create a "thread trace dump stats" command

2021-07-16 Thread hanbing wang via Phabricator via lldb-commits
hanbingwang marked 2 inline comments as done.
hanbingwang added inline comments.



Comment at: lldb/include/lldb/Target/Trace.h:155
+  /// If \b false, print compact stats
+  virtual void DumpTraceStats(Thread &thread, Stream &s, bool verbose) = 0;
+

clayborg wrote:
> Are any statistics being dumped here? Maybe DumpTraceSummary(...) or 
> DumpTraceInfo(...) would be better?
@clayborg Sorry I didn't turn on the notification! Just saw your comments 
yesterday.
I agree "DumpTraceInfo()" is a better name.



Comment at: lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp:118
+  }
+  s.Printf("\nraw trace size %zu\n", *raw_size);
+  return;

wallace wrote:
> clayborg wrote:
> > wallace wrote:
> > > the presentation of this line could be better. Something like this would 
> > > look nicer
> > > 
> > >   thread 1: tid = 123123
> > > 
> > > - Tracing technology: Intel PT
> > > - Raw trace size: 1231232 bytes 
> > The "Tracing technology: Intel PT" should probably come before any of the 
> > thread infos if it is added:
> > ```
> > Tracing technology: Intel PT
> > thread 1: tid = 111, size = 0x1000
> > thread 2: tid = 222, size = 0x1000
> > ```
> That's a pretty good idea.
> 
> @hanbingwang , you can invoke trace_sp->GetPluginName() for getting the name 
> of the tracing technology being used
Hi @wallace @clayborg,

I'm wondering how to let the string "Tracing technology: Intel PT" printed out 
exactly once, when there are more than one threads?  It looks like that 
HandleOneThread() will be called multiple times, which will then call 
DumpTraceInfo() which does the printout.

It seems that it'll be easy to print the string if we know if a thread is the 
*first* to be handled. However the threads are not indexed though?


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D105717/new/

https://reviews.llvm.org/D105717

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D105717: [trace] [intel pt] Create a "thread trace dump stats" command

2021-07-18 Thread hanbing wang via Phabricator via lldb-commits
hanbingwang updated this revision to Diff 359671.
hanbingwang marked an inline comment as done.
hanbingwang added a comment.

F18016096: Screen Shot 2021-07-18 at 11.07.29 PM.png 


print out the tracing plugin name exactly once when there are one or more than 
one threads.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D105717/new/

https://reviews.llvm.org/D105717

Files:
  lldb/include/lldb/Target/Trace.h
  lldb/source/Commands/CommandObjectThread.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
  lldb/test/API/commands/trace/TestTraceDumpInfo.py
  lldb/test/API/commands/trace/TestTraceLoad.py

Index: lldb/test/API/commands/trace/TestTraceLoad.py
===
--- lldb/test/API/commands/trace/TestTraceLoad.py
+++ lldb/test/API/commands/trace/TestTraceLoad.py
@@ -33,7 +33,7 @@
 # check that the Process and Thread objects were created correctly
 self.expect("thread info", substrs=["tid = 3842849"])
 self.expect("thread list", substrs=["Process 1234 stopped", "tid = 3842849"])
-self.expect("thread trace dump info", substrs=['''Tracing technology: intel-pt
+self.expect("thread trace dump info", substrs=['''Trace technology: intel-pt
 thread #1: tid = 3842849
 Raw trace size: 4096 bytes'''])
 
Index: lldb/test/API/commands/trace/TestTraceDumpInfo.py
===
--- lldb/test/API/commands/trace/TestTraceDumpInfo.py
+++ lldb/test/API/commands/trace/TestTraceDumpInfo.py
@@ -35,6 +35,6 @@
 substrs=["intel-pt"])
 
 self.expect("thread trace dump info",
-substrs=['''Tracing technology: intel-pt
+substrs=['''Trace technology: intel-pt
 thread #1: tid = 3842849
 Raw trace size: 4096 bytes'''])
Index: lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
===
--- lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
+++ lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
@@ -67,7 +67,7 @@
 
   lldb::TraceCursorUP GetCursor(Thread &thread) override;
 
-  void DumpTraceInfo(Thread &thread, Stream &s, bool verbose, lldb_private::ConstString plugin_name) override;
+  void DumpTraceInfo(Thread &thread, Stream &s, bool verbose) override;
 
   llvm::Optional GetRawTraceSize(Thread &thread);
 
Index: lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
===
--- lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
+++ lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
@@ -108,9 +108,9 @@
   return Decode(thread)->GetCursor();
 }
 
-void TraceIntelPT::DumpTraceInfo(Thread &thread, Stream &s, bool verbose, lldb_private::ConstString plugin_name) {
+void TraceIntelPT::DumpTraceInfo(Thread &thread, Stream &s, bool verbose) {
   Optional raw_size = GetRawTraceSize(thread);
-  s.Printf("Tracing technology: %s\nthread #%u: tid = %" PRIu64, plugin_name.AsCString(), thread.GetIndexID(), thread.GetID());
+  s.Printf("thread #%u: tid = %" PRIu64, thread.GetIndexID(), thread.GetID());
   if (!raw_size) {
 s.Printf(", not traced\n");
 return;
Index: lldb/source/Commands/CommandObjectThread.cpp
===
--- lldb/source/Commands/CommandObjectThread.cpp
+++ lldb/source/Commands/CommandObjectThread.cpp
@@ -32,7 +32,6 @@
 #include "lldb/Target/ThreadPlan.h"
 #include "lldb/Target/ThreadPlanStepInRange.h"
 #include "lldb/Target/Trace.h"
-#include "lldb/Utility/ConstString.h"
 #include "lldb/Utility/State.h"
 
 using namespace lldb;
@@ -2155,10 +2154,21 @@
 bool m_verbose;
   };
 
+  bool DoExecute(Args &command, CommandReturnObject &result) override {
+Target &target = m_exe_ctx.GetTargetRef();
+result.GetOutputStream().Printf(
+"Trace technology: %s\n",
+target.GetTrace()->GetPluginName().AsCString());
+return CommandObjectIterateOverThreads::DoExecute(command, result);
+  }
+
   CommandObjectTraceDumpInfo(CommandInterpreter &interpreter)
   : CommandObjectIterateOverThreads(
 interpreter, "thread trace dump info",
-"Dump the traced info for one thread.", nullptr,
+"Dump the traced information for one or more threads.  If no "
+"threads are specified, show the current thread.  Use the "
+"thread-index \"all\" to see all threads.",
+nullptr,
 eCommandRequiresProcess | eCommandTryTargetAPILock |
 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused |
 eCommandProcessMustBeTraced),
@@ -2174,7 +2184,7 @@
 ThreadSP thread_sp =
 m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid);
 trace_sp->DumpTraceInfo(*thread_sp, result.GetOutputStream(),
- m_options.m_verbose,  trace_

[Lldb-commits] [PATCH] D105717: [trace] [intel pt] Create a "thread trace dump stats" command

2021-07-19 Thread hanbing wang via Phabricator via lldb-commits
hanbingwang updated this revision to Diff 359994.
hanbingwang added a comment.

{F18030885 }add two spaces before the 
string "Raw trace size : xxx"; add new line between each thread.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D105717/new/

https://reviews.llvm.org/D105717

Files:
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp


Index: lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
===
--- lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
+++ lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
@@ -110,12 +110,12 @@
 
 void TraceIntelPT::DumpTraceInfo(Thread &thread, Stream &s, bool verbose) {
   Optional raw_size = GetRawTraceSize(thread);
-  s.Printf("thread #%u: tid = %" PRIu64, thread.GetIndexID(), thread.GetID());
+  s.Printf("\nthread #%u: tid = %" PRIu64, thread.GetIndexID(), 
thread.GetID());
   if (!raw_size) {
 s.Printf(", not traced\n");
 return;
   }
-  s.Printf("\nRaw trace size: %zu bytes\n", *raw_size);
+  s.Printf("\n  Raw trace size: %zu bytes\n", *raw_size);
   return;
 }
 


Index: lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
===
--- lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
+++ lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
@@ -110,12 +110,12 @@
 
 void TraceIntelPT::DumpTraceInfo(Thread &thread, Stream &s, bool verbose) {
   Optional raw_size = GetRawTraceSize(thread);
-  s.Printf("thread #%u: tid = %" PRIu64, thread.GetIndexID(), thread.GetID());
+  s.Printf("\nthread #%u: tid = %" PRIu64, thread.GetIndexID(), thread.GetID());
   if (!raw_size) {
 s.Printf(", not traced\n");
 return;
   }
-  s.Printf("\nRaw trace size: %zu bytes\n", *raw_size);
+  s.Printf("\n  Raw trace size: %zu bytes\n", *raw_size);
   return;
 }
 
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D105717: [trace] [intel pt] Create a "thread trace dump stats" command

2021-07-20 Thread hanbing wang via Phabricator via lldb-commits
hanbingwang updated this revision to Diff 360035.
hanbingwang edited the summary of this revision.
hanbingwang added a comment.

Create a "thread trace dump info" command


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D105717/new/

https://reviews.llvm.org/D105717

Files:
  lldb/include/lldb/Target/Trace.h
  lldb/source/Commands/CommandObjectThread.cpp
  lldb/source/Commands/Options.td
  lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp
  lldb/source/Plugins/Trace/intel-pt/DecodedThread.h
  lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
  lldb/test/API/commands/trace/TestTraceDumpInfo.py
  lldb/test/API/commands/trace/TestTraceLoad.py
  lldb/tools/lldb-vscode/ProgressEvent.cpp

Index: lldb/tools/lldb-vscode/ProgressEvent.cpp
===
--- lldb/tools/lldb-vscode/ProgressEvent.cpp
+++ lldb/tools/lldb-vscode/ProgressEvent.cpp
@@ -47,6 +47,7 @@
   m_percentage = 100;
   } else {
 // Update event
+m_event_type = progressUpdate;
 m_percentage = std::min(
 (uint32_t)((double)completed / (double)total * 100.0), (uint32_t)99);
 if (prev_event->Reported()) {
Index: lldb/test/API/commands/trace/TestTraceLoad.py
===
--- lldb/test/API/commands/trace/TestTraceLoad.py
+++ lldb/test/API/commands/trace/TestTraceLoad.py
@@ -33,7 +33,9 @@
 # check that the Process and Thread objects were created correctly
 self.expect("thread info", substrs=["tid = 3842849"])
 self.expect("thread list", substrs=["Process 1234 stopped", "tid = 3842849"])
-
+self.expect("thread trace dump info", substrs=['''Trace technology: intel-pt
+thread #1: tid = 3842849
+Raw trace size: 4096 bytes'''])
 
 def testLoadInvalidTraces(self):
 src_dir = self.getSourceDir()
Index: lldb/test/API/commands/trace/TestTraceDumpInfo.py
===
--- /dev/null
+++ lldb/test/API/commands/trace/TestTraceDumpInfo.py
@@ -0,0 +1,40 @@
+import lldb
+from intelpt_testcase import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+from lldbsuite.test.decorators import *
+
+class TestTraceDumpInfo(TraceIntelPTTestCaseBase):
+mydir = TestBase.compute_mydir(__file__)
+
+def testErrorMessages(self):
+# We first check the output when there are no targets
+self.expect("thread trace dump info",
+substrs=["error: invalid target, create a target using the 'target create' command"],
+error=True)
+
+# We now check the output when there's a non-running target
+self.expect("target create " +
+os.path.join(self.getSourceDir(), "intelpt-trace", "a.out"))
+
+self.expect("thread trace dump info",
+substrs=["error: invalid process"],
+error=True)
+
+# Now we check the output when there's a running target without a trace
+self.expect("b main")
+self.expect("run")
+
+self.expect("thread trace dump info",
+substrs=["error: Process is not being traced"],
+error=True)
+
+def testDumpRawTraceSize(self):
+self.expect("trace load -v " +
+os.path.join(self.getSourceDir(), "intelpt-trace", "trace.json"),
+substrs=["intel-pt"])
+
+self.expect("thread trace dump info",
+substrs=['''Trace technology: intel-pt
+thread #1: tid = 3842849
+Raw trace size: 4096 bytes'''])
Index: lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
===
--- lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
+++ lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
@@ -67,6 +67,10 @@
 
   lldb::TraceCursorUP GetCursor(Thread &thread) override;
 
+  void DumpTraceInfo(Thread &thread, Stream &s, bool verbose) override;
+
+  llvm::Optional GetRawTraceSize(Thread &thread);
+
   void DoRefreshLiveProcessState(
   llvm::Expected state) override;
 
Index: lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
===
--- lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
+++ lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
@@ -108,6 +108,24 @@
   return Decode(thread)->GetCursor();
 }
 
+void TraceIntelPT::DumpTraceInfo(Thread &thread, Stream &s, bool verbose) {
+  Optional raw_size = GetRawTraceSize(thread);
+  s.Printf("\nthread #%u: tid = %" PRIu64, thread.GetIndexID(), thread.GetID());
+  if (!raw_size) {
+s.Printf(", not traced\n");
+return;
+  }
+  s.Printf("\n  Raw trace size: %zu bytes\n", *raw_size);
+  return;
+}
+
+Optional TraceIntelPT::GetRawTraceSize(Thread &thread) {
+  if (IsTraced(thread))
+return Decode(thread)->GetRawTraceSize();
+  else
+return None;
+}
+
 Expected TraceIntelPT::

[Lldb-commits] [PATCH] D105717: [trace] [intel pt] Create a "thread trace dump stats" command

2021-07-20 Thread hanbing wang via Phabricator via lldb-commits
hanbingwang updated this revision to Diff 360037.
hanbingwang added a comment.

Create a "thread trace dump info" command


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D105717/new/

https://reviews.llvm.org/D105717

Files:
  lldb/include/lldb/Target/Trace.h
  lldb/source/Commands/CommandObjectThread.cpp
  lldb/source/Commands/Options.td
  lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp
  lldb/source/Plugins/Trace/intel-pt/DecodedThread.h
  lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
  lldb/test/API/commands/trace/TestTraceDumpInfo.py
  lldb/test/API/commands/trace/TestTraceLoad.py

Index: lldb/test/API/commands/trace/TestTraceLoad.py
===
--- lldb/test/API/commands/trace/TestTraceLoad.py
+++ lldb/test/API/commands/trace/TestTraceLoad.py
@@ -33,7 +33,9 @@
 # check that the Process and Thread objects were created correctly
 self.expect("thread info", substrs=["tid = 3842849"])
 self.expect("thread list", substrs=["Process 1234 stopped", "tid = 3842849"])
-
+self.expect("thread trace dump info", substrs=['''Trace technology: intel-pt
+thread #1: tid = 3842849
+Raw trace size: 4096 bytes'''])
 
 def testLoadInvalidTraces(self):
 src_dir = self.getSourceDir()
Index: lldb/test/API/commands/trace/TestTraceDumpInfo.py
===
--- /dev/null
+++ lldb/test/API/commands/trace/TestTraceDumpInfo.py
@@ -0,0 +1,40 @@
+import lldb
+from intelpt_testcase import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+from lldbsuite.test.decorators import *
+
+class TestTraceDumpInfo(TraceIntelPTTestCaseBase):
+mydir = TestBase.compute_mydir(__file__)
+
+def testErrorMessages(self):
+# We first check the output when there are no targets
+self.expect("thread trace dump info",
+substrs=["error: invalid target, create a target using the 'target create' command"],
+error=True)
+
+# We now check the output when there's a non-running target
+self.expect("target create " +
+os.path.join(self.getSourceDir(), "intelpt-trace", "a.out"))
+
+self.expect("thread trace dump info",
+substrs=["error: invalid process"],
+error=True)
+
+# Now we check the output when there's a running target without a trace
+self.expect("b main")
+self.expect("run")
+
+self.expect("thread trace dump info",
+substrs=["error: Process is not being traced"],
+error=True)
+
+def testDumpRawTraceSize(self):
+self.expect("trace load -v " +
+os.path.join(self.getSourceDir(), "intelpt-trace", "trace.json"),
+substrs=["intel-pt"])
+
+self.expect("thread trace dump info",
+substrs=['''Trace technology: intel-pt
+thread #1: tid = 3842849
+Raw trace size: 4096 bytes'''])
Index: lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
===
--- lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
+++ lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
@@ -67,6 +67,10 @@
 
   lldb::TraceCursorUP GetCursor(Thread &thread) override;
 
+  void DumpTraceInfo(Thread &thread, Stream &s, bool verbose) override;
+
+  llvm::Optional GetRawTraceSize(Thread &thread);
+
   void DoRefreshLiveProcessState(
   llvm::Expected state) override;
 
Index: lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
===
--- lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
+++ lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
@@ -108,6 +108,24 @@
   return Decode(thread)->GetCursor();
 }
 
+void TraceIntelPT::DumpTraceInfo(Thread &thread, Stream &s, bool verbose) {
+  Optional raw_size = GetRawTraceSize(thread);
+  s.Printf("\nthread #%u: tid = %" PRIu64, thread.GetIndexID(), thread.GetID());
+  if (!raw_size) {
+s.Printf(", not traced\n");
+return;
+  }
+  s.Printf("\n  Raw trace size: %zu bytes\n", *raw_size);
+  return;
+}
+
+Optional TraceIntelPT::GetRawTraceSize(Thread &thread) {
+  if (IsTraced(thread))
+return Decode(thread)->GetRawTraceSize();
+  else
+return None;
+}
+
 Expected TraceIntelPT::GetCPUInfoForLiveProcess() {
   Expected> cpu_info = GetLiveProcessBinaryData("cpuInfo");
   if (!cpu_info)
Index: lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp
===
--- lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp
+++ lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp
@@ -194,7 +194,7 @@
 
 static Expected>
 DecodeTraceFile(Process &process, TraceIntelPT &trace_intel_pt,
-const FileSpec &trace_file) {
+const FileSpec &trace_file, size_t

[Lldb-commits] [PATCH] D105717: [trace] [intel pt] Create a "thread trace dump stats" command

2021-07-20 Thread hanbing wang via Phabricator via lldb-commits
hanbingwang updated this revision to Diff 360044.

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D105717/new/

https://reviews.llvm.org/D105717

Files:
  lldb/include/lldb/Target/Trace.h
  lldb/source/Commands/CommandObjectThread.cpp
  lldb/source/Commands/Options.td
  lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp
  lldb/source/Plugins/Trace/intel-pt/DecodedThread.h
  lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
  lldb/test/API/commands/trace/TestTraceDumpInfo.py
  lldb/test/API/commands/trace/TestTraceLoad.py

Index: lldb/test/API/commands/trace/TestTraceLoad.py
===
--- lldb/test/API/commands/trace/TestTraceLoad.py
+++ lldb/test/API/commands/trace/TestTraceLoad.py
@@ -33,7 +33,10 @@
 # check that the Process and Thread objects were created correctly
 self.expect("thread info", substrs=["tid = 3842849"])
 self.expect("thread list", substrs=["Process 1234 stopped", "tid = 3842849"])
+self.expect("thread trace dump info", substrs=['''Trace technology: intel-pt
 
+thread #1: tid = 3842849
+  Raw trace size: 4096 bytes'''])
 
 def testLoadInvalidTraces(self):
 src_dir = self.getSourceDir()
Index: lldb/test/API/commands/trace/TestTraceDumpInfo.py
===
--- /dev/null
+++ lldb/test/API/commands/trace/TestTraceDumpInfo.py
@@ -0,0 +1,41 @@
+import lldb
+from intelpt_testcase import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+from lldbsuite.test.decorators import *
+
+class TestTraceDumpInfo(TraceIntelPTTestCaseBase):
+mydir = TestBase.compute_mydir(__file__)
+
+def testErrorMessages(self):
+# We first check the output when there are no targets
+self.expect("thread trace dump info",
+substrs=["error: invalid target, create a target using the 'target create' command"],
+error=True)
+
+# We now check the output when there's a non-running target
+self.expect("target create " +
+os.path.join(self.getSourceDir(), "intelpt-trace", "a.out"))
+
+self.expect("thread trace dump info",
+substrs=["error: invalid process"],
+error=True)
+
+# Now we check the output when there's a running target without a trace
+self.expect("b main")
+self.expect("run")
+
+self.expect("thread trace dump info",
+substrs=["error: Process is not being traced"],
+error=True)
+
+def testDumpRawTraceSize(self):
+self.expect("trace load -v " +
+os.path.join(self.getSourceDir(), "intelpt-trace", "trace.json"),
+substrs=["intel-pt"])
+
+self.expect("thread trace dump info",
+substrs=['''Trace technology: intel-pt
+
+thread #1: tid = 3842849
+  Raw trace size: 4096 bytes'''])
Index: lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
===
--- lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
+++ lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
@@ -67,6 +67,10 @@
 
   lldb::TraceCursorUP GetCursor(Thread &thread) override;
 
+  void DumpTraceInfo(Thread &thread, Stream &s, bool verbose) override;
+
+  llvm::Optional GetRawTraceSize(Thread &thread);
+
   void DoRefreshLiveProcessState(
   llvm::Expected state) override;
 
Index: lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
===
--- lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
+++ lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
@@ -108,6 +108,24 @@
   return Decode(thread)->GetCursor();
 }
 
+void TraceIntelPT::DumpTraceInfo(Thread &thread, Stream &s, bool verbose) {
+  Optional raw_size = GetRawTraceSize(thread);
+  s.Printf("\nthread #%u: tid = %" PRIu64, thread.GetIndexID(), thread.GetID());
+  if (!raw_size) {
+s.Printf(", not traced\n");
+return;
+  }
+  s.Printf("\n  Raw trace size: %zu bytes\n", *raw_size);
+  return;
+}
+
+Optional TraceIntelPT::GetRawTraceSize(Thread &thread) {
+  if (IsTraced(thread))
+return Decode(thread)->GetRawTraceSize();
+  else
+return None;
+}
+
 Expected TraceIntelPT::GetCPUInfoForLiveProcess() {
   Expected> cpu_info = GetLiveProcessBinaryData("cpuInfo");
   if (!cpu_info)
Index: lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp
===
--- lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp
+++ lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp
@@ -194,7 +194,7 @@
 
 static Expected>
 DecodeTraceFile(Process &process, TraceIntelPT &trace_intel_pt,
-const FileSpec &trace_file) {
+const FileSpec &trace_file, size_t &raw_trace_size) {
   ErrorOr> trace_or_error =
   MemoryBuff

[Lldb-commits] [PATCH] D107669: Create "process trace save" command

2021-08-06 Thread hanbing wang via Phabricator via lldb-commits
hanbingwang created this revision.
hanbingwang added reviewers: wallace, clayborg.
Herald added subscribers: dang, mgorny.
hanbingwang requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

added new command "process trace save -d ".
-it only support Intel-pt right now.
-it saves a JSON file as /trace.json, with the main properties of 
the trace session.
-it saves binary Intel-PT trace as /thread_id.trace; each file saves 
each thread.

Example:
b main
run
process trace start
n
process trace save -d /tmp/mytrace
A file named trace.json and xxx.trace should be generated in /tmp/mytrace. To 
load the trace that was just saved:
trace load /tmp/mytrace
thread trace dump instructions
You should see the instructions of the trace got printed.

To run a test:
./bin/lldb-dotest -p TestTraceSave


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D107669

Files:
  lldb/include/lldb/Target/Trace.h
  lldb/source/Commands/CommandObjectProcess.cpp
  lldb/source/Commands/Options.td
  lldb/source/Plugins/Trace/common/CMakeLists.txt
  lldb/source/Plugins/Trace/common/TraceJSONStructs.cpp
  lldb/source/Plugins/Trace/common/TraceJSONStructs.h
  lldb/source/Plugins/Trace/common/TraceSessionFileParser.cpp
  lldb/source/Plugins/Trace/common/TraceSessionFileParser.h
  lldb/source/Plugins/Trace/intel-pt/CMakeLists.txt
  lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp
  lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.h
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTJSONStructs.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTJSONStructs.h
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTOptions.td
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.h
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileSaver.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileSaver.h
  lldb/test/API/commands/trace/TestTraceSave.py

Index: lldb/test/API/commands/trace/TestTraceSave.py
===
--- /dev/null
+++ lldb/test/API/commands/trace/TestTraceSave.py
@@ -0,0 +1,70 @@
+import lldb
+from intelpt_testcase import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+from lldbsuite.test.decorators import *
+
+class TestTraceSave(TraceIntelPTTestCaseBase):
+mydir = TestBase.compute_mydir(__file__)
+
+def testErrorMessages(self):
+# We first check the output when there are no targets
+self.expect("process trace save",
+substrs=["error: invalid target, create a target using the 'target create' command"],
+error=True)
+
+# We now check the output when there's a non-running target
+self.expect("target create " +
+os.path.join(self.getSourceDir(), "intelpt-trace", "a.out"))
+
+self.expect("process trace save",
+substrs=["error: invalid process"],
+error=True)
+
+# Now we check the output when there's a running target without a trace
+self.expect("b main")
+self.expect("run")
+
+self.expect("process trace save",
+substrs=["error: Process is not being traced"],
+error=True)
+
+def testSaveTrace(self):
+# Load a trace
+self.expect("trace load -v " +
+os.path.join(self.getSourceDir(), "intelpt-trace", "trace.json"),
+substrs=["intel-pt"])
+# Save the trace to 
+self.expect("process trace save -d " +
+os.path.join(self.getSourceDir(), "intelpt-trace", "trace_copy_dir"))
+# Load the trace just saved
+self.expect("trace load -v " +
+os.path.join(self.getSourceDir(), "intelpt-trace", "trace_copy_dir", "trace.json"),
+substrs=["intel-pt"])
+#dump instructions and check
+self.expect("thread trace dump instructions --raw --count 21 --forwards",
+substrs=['''thread #1: tid = 3842849
+[ 0] 0x00400511
+[ 1] 0x00400518
+[ 2] 0x0040051f
+[ 3] 0x00400529
+[ 4] 0x0040052d
+[ 5] 0x00400521
+[ 6] 0x00400525
+[ 7] 0x00400529
+[ 8] 0x0040052d
+[ 9] 0x00400521
+[10] 0x00400525
+[11] 0x00400529
+[12] 0x0040052d
+[13] 0x00400521
+[14] 0x00400525
+[15] 0x00400529
+[16] 0x0040052d
+[17] 0x00400521
+[18] 0x00400525
+[19] 0x00400529
+[20] 0x0040052d'''])
+
+#remove 
+shutil.rmtree(os.path.join(self.getSourceDir(), "intelpt-trace", "trace_copy_dir"))
Index: lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileSaver.h

[Lldb-commits] [PATCH] D107669: [trace] [intel pt] Create a "process trace save" command

2021-08-06 Thread hanbing wang via Phabricator via lldb-commits
hanbingwang updated this revision to Diff 364893.
hanbingwang added a comment.

fix a typo. change a string "the trace of ..." from "the trace or ..."


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D107669/new/

https://reviews.llvm.org/D107669

Files:
  lldb/include/lldb/Target/Trace.h
  lldb/source/Commands/CommandObjectProcess.cpp
  lldb/source/Commands/Options.td
  lldb/source/Plugins/Trace/common/CMakeLists.txt
  lldb/source/Plugins/Trace/common/TraceJSONStructs.cpp
  lldb/source/Plugins/Trace/common/TraceJSONStructs.h
  lldb/source/Plugins/Trace/common/TraceSessionFileParser.cpp
  lldb/source/Plugins/Trace/common/TraceSessionFileParser.h
  lldb/source/Plugins/Trace/intel-pt/CMakeLists.txt
  lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp
  lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.h
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTJSONStructs.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTJSONStructs.h
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTOptions.td
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.h
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileSaver.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileSaver.h
  lldb/test/API/commands/trace/TestTraceSave.py

Index: lldb/test/API/commands/trace/TestTraceSave.py
===
--- /dev/null
+++ lldb/test/API/commands/trace/TestTraceSave.py
@@ -0,0 +1,70 @@
+import lldb
+from intelpt_testcase import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+from lldbsuite.test.decorators import *
+
+class TestTraceSave(TraceIntelPTTestCaseBase):
+mydir = TestBase.compute_mydir(__file__)
+
+def testErrorMessages(self):
+# We first check the output when there are no targets
+self.expect("process trace save",
+substrs=["error: invalid target, create a target using the 'target create' command"],
+error=True)
+
+# We now check the output when there's a non-running target
+self.expect("target create " +
+os.path.join(self.getSourceDir(), "intelpt-trace", "a.out"))
+
+self.expect("process trace save",
+substrs=["error: invalid process"],
+error=True)
+
+# Now we check the output when there's a running target without a trace
+self.expect("b main")
+self.expect("run")
+
+self.expect("process trace save",
+substrs=["error: Process is not being traced"],
+error=True)
+
+def testSaveTrace(self):
+# Load a trace
+self.expect("trace load -v " +
+os.path.join(self.getSourceDir(), "intelpt-trace", "trace.json"),
+substrs=["intel-pt"])
+# Save the trace to 
+self.expect("process trace save -d " +
+os.path.join(self.getSourceDir(), "intelpt-trace", "trace_copy_dir"))
+# Load the trace just saved
+self.expect("trace load -v " +
+os.path.join(self.getSourceDir(), "intelpt-trace", "trace_copy_dir", "trace.json"),
+substrs=["intel-pt"])
+#dump instructions and check
+self.expect("thread trace dump instructions --raw --count 21 --forwards",
+substrs=['''thread #1: tid = 3842849
+[ 0] 0x00400511
+[ 1] 0x00400518
+[ 2] 0x0040051f
+[ 3] 0x00400529
+[ 4] 0x0040052d
+[ 5] 0x00400521
+[ 6] 0x00400525
+[ 7] 0x00400529
+[ 8] 0x0040052d
+[ 9] 0x00400521
+[10] 0x00400525
+[11] 0x00400529
+[12] 0x0040052d
+[13] 0x00400521
+[14] 0x00400525
+[15] 0x00400529
+[16] 0x0040052d
+[17] 0x00400521
+[18] 0x00400525
+[19] 0x00400529
+[20] 0x0040052d'''])
+
+#remove 
+shutil.rmtree(os.path.join(self.getSourceDir(), "intelpt-trace", "trace_copy_dir"))
Index: lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileSaver.h
===
--- /dev/null
+++ lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileSaver.h
@@ -0,0 +1,124 @@
+//===-- TraceIntelPTSessionFileSaver.h ---*- C++ //-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTSESSIONFILESAVER_H
+#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTSESSIONFILESAVER_H
+
+#i

[Lldb-commits] [PATCH] D107669: [trace] [intel pt] Create a "process trace save" command

2021-08-11 Thread hanbing wang via Phabricator via lldb-commits
hanbingwang updated this revision to Diff 365883.
hanbingwang marked an inline comment as done.
hanbingwang added a comment.

*trace.h: 
-rename SaveToDisk() to SaveLiveTraceToDisk()

*IntelPTDecoder.h, IntelPTDecoder.cpp: 
-removed GetRawTrace()

*TraceIntelPT.h, TraceIntelPT.cpp: 
-removed GetThreadBuffer()
-in function SaveToDisk(), replace "process_sp" with "m_live_process"

*TraceIntelPTSessionFileSaver.h, TraceIntelPTSessionFileSaver.cpp:
-renamed to TraceIntelPTSessionSaver.h and TraceIntelPTSessionSaver.cpp
-the function BuildModulesSection() copies modules inside /modules
-create new constructors for struct JSONTraceIntelPTCPUInfo
-error checking for writing stream to file


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D107669/new/

https://reviews.llvm.org/D107669

Files:
  lldb/include/lldb/Target/Trace.h
  lldb/source/Commands/CommandObjectProcess.cpp
  lldb/source/Commands/Options.td
  lldb/source/Plugins/Trace/common/CMakeLists.txt
  lldb/source/Plugins/Trace/common/TraceJSONStructs.cpp
  lldb/source/Plugins/Trace/common/TraceJSONStructs.h
  lldb/source/Plugins/Trace/common/TraceSessionFileParser.cpp
  lldb/source/Plugins/Trace/common/TraceSessionFileParser.h
  lldb/source/Plugins/Trace/intel-pt/CMakeLists.txt
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTJSONStructs.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTJSONStructs.h
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTOptions.td
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.h
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionSaver.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionSaver.h
  lldb/test/API/commands/trace/TestTraceSave.py

Index: lldb/test/API/commands/trace/TestTraceSave.py
===
--- /dev/null
+++ lldb/test/API/commands/trace/TestTraceSave.py
@@ -0,0 +1,49 @@
+import lldb
+from intelpt_testcase import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+from lldbsuite.test.decorators import *
+
+class TestTraceSave(TraceIntelPTTestCaseBase):
+mydir = TestBase.compute_mydir(__file__)
+
+def testErrorMessages(self):
+# We first check the output when there are no targets
+self.expect("process trace save",
+substrs=["error: invalid target, create a target using the 'target create' command"],
+error=True)
+
+# We now check the output when there's a non-running target
+self.expect("target create " +
+os.path.join(self.getSourceDir(), "intelpt-trace", "a.out"))
+
+self.expect("process trace save",
+substrs=["error: invalid process"],
+error=True)
+
+# Now we check the output when there's a running target without a trace
+self.expect("b main")
+self.expect("run")
+
+self.expect("process trace save",
+substrs=["error: Process is not being traced"],
+error=True)
+
+def testSaveTrace(self):
+self.expect("target create " +
+os.path.join(self.getSourceDir(), "intelpt-trace", "a.out"))
+self.expect("b main")
+self.expect("r")
+self.expect("thread trace start")
+self.expect("n")
+self.expect("thread trace dump instructions", substrs=["""0x00400511movl   $0x0, -0x4(%rbp)
+no more data"""])
+# Save the trace to 
+self.expect("process trace save -d " +
+os.path.join(self.getBuildDir(), "intelpt-trace", "trace_copy_dir"))
+# Load the trace just saved
+self.expect("trace load -v " +
+os.path.join(self.getBuildDir(), "intelpt-trace", "trace_copy_dir", "trace.json"),
+substrs=["intel-pt"])
+self.expect("thread trace dump instructions", substrs=["""0x00400511movl   $0x0, -0x4(%rbp)
+no more data"""])
Index: lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionSaver.h
===
--- /dev/null
+++ lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionSaver.h
@@ -0,0 +1,140 @@
+//===-- TraceIntelPTSessionSaver.h ---*- C++ //-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTSESSIONSAVER_H
+#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTSESSIONSAVER_H
+
+#include "TraceIntelPT.h"
+
+#include "../common/TraceSessionFileParser.h"
+
+namespace lldb_private {
+namespace trace_intel_pt {
+
+class TraceIntelPT;
+
+class Tra

[Lldb-commits] [PATCH] D107669: [trace] [intel pt] Create a "process trace save" command

2021-08-11 Thread hanbing wang via Phabricator via lldb-commits
hanbingwang added inline comments.



Comment at: 
lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileSaver.cpp:87
+llvm::Expected
+TraceIntelPTSessionFileSaver::BuildProcessesSection(lldb::ProcessSP 
&process_sp,
+TraceIntelPT &trace_ipt,

wallace wrote:
> you could move BuildProcessesSection, BuildThreadsSection and 
> BuildModulesSection to TraceSessionSaver.h/cpp if you provide a callback that 
> receives a thread_id and returns a raw trace. Then almost all the code would 
> be reusable by other Trace plug-ins
Sorry I did not make changes here. A bit unsure how to "provide a callback that 
receives a thread_id and returns a raw trace" and how would it work?



Comment at: lldb/test/API/commands/trace/TestTraceSave.py:34-36
+self.expect("trace load -v " +
+os.path.join(self.getSourceDir(), "intelpt-trace", "trace.json"),
+substrs=["intel-pt"])

wallace wrote:
> now that we are changing to live processes, this won't work. Instead, trace 
> one of the existing binary files in the test folder, run it, get the first 
> and last 20 instructions, save the contents in strings, then save the trace, 
> then load it and dump the instructions again, finally assert that the outputs 
> are the same
I'm not sure how to "save the contents in strings"?


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D107669/new/

https://reviews.llvm.org/D107669

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D107669: [trace] [intel pt] Create a "process trace save" command

2021-08-12 Thread hanbing wang via Phabricator via lldb-commits
hanbingwang updated this revision to Diff 366151.
hanbingwang edited the summary of this revision.
hanbingwang added a comment.
Herald added a subscriber: pengfei.

*TraceSessionSaver.h, TraceSessionSaver.cpp:
-move BuildModulesSection(), BuildThreadsSection(), BuildProcessesSection(), 
WriteSessionToFile() from TraceIntelPTSessionSaver.cpp to this file. These 
functions are generic for all trace plug-ins.

*TestTraceSave.py:
-new test case for "process trace save" command

*TraceIntelPT.h, Trace.h

- change IsTraced(const Thread &thread) to IsTraced(lldb::tid_t tid)

*TraceIntelPTJSONStructs.h
-rename JSONTraceIntelPTSchema to JSONTraceIntelPTSession


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D107669/new/

https://reviews.llvm.org/D107669

Files:
  lldb/include/lldb/Target/Trace.h
  lldb/source/Commands/CommandObjectProcess.cpp
  lldb/source/Commands/Options.td
  lldb/source/Plugins/Trace/common/CMakeLists.txt
  lldb/source/Plugins/Trace/common/TraceJSONStructs.cpp
  lldb/source/Plugins/Trace/common/TraceJSONStructs.h
  lldb/source/Plugins/Trace/common/TraceSessionFileParser.cpp
  lldb/source/Plugins/Trace/common/TraceSessionFileParser.h
  lldb/source/Plugins/Trace/common/TraceSessionSaver.cpp
  lldb/source/Plugins/Trace/common/TraceSessionSaver.h
  lldb/source/Plugins/Trace/intel-pt/CMakeLists.txt
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTJSONStructs.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTJSONStructs.h
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTOptions.td
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.h
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionSaver.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionSaver.h
  lldb/test/API/commands/trace/TestTraceSave.py

Index: lldb/test/API/commands/trace/TestTraceSave.py
===
--- /dev/null
+++ lldb/test/API/commands/trace/TestTraceSave.py
@@ -0,0 +1,75 @@
+import lldb
+from intelpt_testcase import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+from lldbsuite.test.decorators import *
+
+class TestTraceSave(TraceIntelPTTestCaseBase):
+mydir = TestBase.compute_mydir(__file__)
+
+def testErrorMessages(self):
+# We first check the output when there are no targets
+self.expect("process trace save",
+substrs=["error: invalid target, create a target using the 'target create' command"],
+error=True)
+
+# We now check the output when there's a non-running target
+self.expect("target create " +
+os.path.join(self.getSourceDir(), "intelpt-trace", "a.out"))
+
+self.expect("process trace save",
+substrs=["error: invalid process"],
+error=True)
+
+# Now we check the output when there's a running target without a trace
+self.expect("b main")
+self.expect("run")
+
+self.expect("process trace save",
+substrs=["error: Process is not being traced"],
+error=True)
+
+def testSaveTrace(self):
+self.expect("target create " +
+os.path.join(self.getSourceDir(), "intelpt-trace", "a.out"))
+self.expect("b main")
+self.expect("r")
+self.expect("thread trace start")
+self.expect("n")
+self.expect("n")
+self.expect("n")
+self.expect("n")
+self.expect("n")
+self.expect("n")
+self.expect("n")
+self.expect("n")
+self.expect("n")
+
+ci = self.dbg.GetCommandInterpreter()
+res = lldb.SBCommandReturnObject()
+
+ci.HandleCommand("thread trace dump instructions -c 10 --forwards", res)
+self.assertEqual(res.Succeeded(), True)
+first_ten_instructions = res.GetOutput()
+
+ci.HandleCommand("thread trace dump instructions -c 10", res)
+self.assertEqual(res.Succeeded(), True)
+last_ten_instructions = res.GetOutput()
+
+# Save the trace to 
+self.expect("process trace save -d " +
+os.path.join(self.getBuildDir(), "intelpt-trace", "trace_copy_dir"))
+
+# Load the trace just saved
+self.expect("trace load -v " +
+os.path.join(self.getBuildDir(), "intelpt-trace", "trace_copy_dir", "trace.json"),
+substrs=["intel-pt"])
+
+# Compare with instructions saved at the first time
+ci.HandleCommand("thread trace dump instructions -c 10 --forwards", res)
+self.assertEqual(res.Succeeded(), True)
+self.assertEqual(res.GetOutput(), first_ten_instructions)
+
+ci.HandleCommand("thread trace dump instructions -c 10", res)
+self.assertEqual(res.Succeeded(), True)
+self.assertEqual(res.GetOutput(), last_ten_instructions)
In

[Lldb-commits] [PATCH] D107669: [trace] [intel pt] Create a "process trace save" command

2021-08-16 Thread hanbing wang via Phabricator via lldb-commits
hanbingwang updated this revision to Diff 366690.
hanbingwang added a comment.

*TraceIntelPT.h, TraceIntelPT.cpp:
-add new function GetLiveProcess()
*TraceIntelPTSessionSaver.h, TraceIntelPTSessionSaver.cpp

- the function SaveToDisk() no longer requires "m_live_process" as input param.

*TestTraceSave.py:
-added new test cases.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D107669/new/

https://reviews.llvm.org/D107669

Files:
  lldb/include/lldb/Target/Trace.h
  lldb/source/Commands/CommandObjectProcess.cpp
  lldb/source/Commands/Options.td
  lldb/source/Plugins/Trace/common/CMakeLists.txt
  lldb/source/Plugins/Trace/common/TraceJSONStructs.cpp
  lldb/source/Plugins/Trace/common/TraceJSONStructs.h
  lldb/source/Plugins/Trace/common/TraceSessionFileParser.cpp
  lldb/source/Plugins/Trace/common/TraceSessionFileParser.h
  lldb/source/Plugins/Trace/common/TraceSessionSaver.cpp
  lldb/source/Plugins/Trace/common/TraceSessionSaver.h
  lldb/source/Plugins/Trace/intel-pt/CMakeLists.txt
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTJSONStructs.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTJSONStructs.h
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTOptions.td
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.h
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionSaver.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionSaver.h
  lldb/test/API/commands/trace/TestTraceSave.py

Index: lldb/test/API/commands/trace/TestTraceSave.py
===
--- /dev/null
+++ lldb/test/API/commands/trace/TestTraceSave.py
@@ -0,0 +1,97 @@
+import lldb
+from intelpt_testcase import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+from lldbsuite.test.decorators import *
+
+class TestTraceSave(TraceIntelPTTestCaseBase):
+mydir = TestBase.compute_mydir(__file__)
+
+def testErrorMessages(self):
+# We first check the output when there are no targets
+self.expect("process trace save",
+substrs=["error: invalid target, create a target using the 'target create' command"],
+error=True)
+
+# We now check the output when there's a non-running target
+self.expect("target create " +
+os.path.join(self.getSourceDir(), "intelpt-trace", "a.out"))
+
+self.expect("process trace save",
+substrs=["error: invalid process"],
+error=True)
+
+# Now we check the output when there's a running target without a trace
+self.expect("b main")
+self.expect("run")
+
+self.expect("process trace save",
+substrs=["error: Process is not being traced"],
+error=True)
+
+def testSaveToInvalidDir(self):
+self.expect("target create " +
+os.path.join(self.getSourceDir(), "intelpt-trace", "a.out"))
+self.expect("b main")
+self.expect("r")
+self.expect("thread trace start")
+self.expect("n")
+
+# Check the output when saving without providing the directory argument
+self.expect("process trace save -d",
+substrs=["error: last option requires an argument"],
+error=True)
+
+# Check the output when saving to an invalid directory
+self.expect("process trace save -d /",
+substrs=["error: couldn't write to the file"],
+error=True)
+
+def testSaveWhenNotLiveTrace(self):
+self.expect("trace load -v " +
+os.path.join(self.getSourceDir(), "intelpt-trace", "trace.json"),
+substrs=["intel-pt"])
+
+# Check the output when not doing live tracing
+self.expect("process trace save -d " +
+os.path.join(self.getBuildDir(), "intelpt-trace", "trace_not_live_dir"),
+substrs=["error: Saving a trace requires a live process."],
+error=True)
+
+
+def testSaveTrace(self):
+self.expect("target create " +
+os.path.join(self.getSourceDir(), "intelpt-trace", "a.out"))
+self.expect("b main")
+self.expect("r")
+self.expect("thread trace start")
+self.expect("b 7")
+
+ci = self.dbg.GetCommandInterpreter()
+res = lldb.SBCommandReturnObject()
+
+ci.HandleCommand("thread trace dump instructions -c 10 --forwards", res)
+self.assertEqual(res.Succeeded(), True)
+first_ten_instructions = res.GetOutput()
+
+ci.HandleCommand("thread trace dump instructions -c 10", res)
+self.assertEqual(res.Succeeded(), True)
+last_ten_instructions = res.GetOutput()
+
+# Now, save the trace to 
+self.expect("process trace save -d " +
+os.path.join(self.getBuildDir(), "intelpt-trace", "trace_copy_dir"))
+
+

[Lldb-commits] [PATCH] D107669: [trace] [intel pt] Create a "process trace save" command

2021-08-16 Thread hanbing wang via Phabricator via lldb-commits
hanbingwang updated this revision to Diff 366713.
hanbingwang marked an inline comment as not done.
hanbingwang added a comment.

merge into one line: "json_module["loadAddress"] = oss.str();"


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D107669/new/

https://reviews.llvm.org/D107669

Files:
  lldb/include/lldb/Target/Trace.h
  lldb/source/Commands/CommandObjectProcess.cpp
  lldb/source/Commands/Options.td
  lldb/source/Plugins/Trace/common/CMakeLists.txt
  lldb/source/Plugins/Trace/common/TraceJSONStructs.cpp
  lldb/source/Plugins/Trace/common/TraceJSONStructs.h
  lldb/source/Plugins/Trace/common/TraceSessionFileParser.cpp
  lldb/source/Plugins/Trace/common/TraceSessionFileParser.h
  lldb/source/Plugins/Trace/common/TraceSessionSaver.cpp
  lldb/source/Plugins/Trace/common/TraceSessionSaver.h
  lldb/source/Plugins/Trace/intel-pt/CMakeLists.txt
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTJSONStructs.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTJSONStructs.h
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTOptions.td
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.h
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionSaver.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionSaver.h
  lldb/test/API/commands/trace/TestTraceSave.py

Index: lldb/test/API/commands/trace/TestTraceSave.py
===
--- /dev/null
+++ lldb/test/API/commands/trace/TestTraceSave.py
@@ -0,0 +1,97 @@
+import lldb
+from intelpt_testcase import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+from lldbsuite.test.decorators import *
+
+class TestTraceSave(TraceIntelPTTestCaseBase):
+mydir = TestBase.compute_mydir(__file__)
+
+def testErrorMessages(self):
+# We first check the output when there are no targets
+self.expect("process trace save",
+substrs=["error: invalid target, create a target using the 'target create' command"],
+error=True)
+
+# We now check the output when there's a non-running target
+self.expect("target create " +
+os.path.join(self.getSourceDir(), "intelpt-trace", "a.out"))
+
+self.expect("process trace save",
+substrs=["error: invalid process"],
+error=True)
+
+# Now we check the output when there's a running target without a trace
+self.expect("b main")
+self.expect("run")
+
+self.expect("process trace save",
+substrs=["error: Process is not being traced"],
+error=True)
+
+def testSaveToInvalidDir(self):
+self.expect("target create " +
+os.path.join(self.getSourceDir(), "intelpt-trace", "a.out"))
+self.expect("b main")
+self.expect("r")
+self.expect("thread trace start")
+self.expect("n")
+
+# Check the output when saving without providing the directory argument
+self.expect("process trace save -d",
+substrs=["error: last option requires an argument"],
+error=True)
+
+# Check the output when saving to an invalid directory
+self.expect("process trace save -d /",
+substrs=["error: couldn't write to the file"],
+error=True)
+
+def testSaveWhenNotLiveTrace(self):
+self.expect("trace load -v " +
+os.path.join(self.getSourceDir(), "intelpt-trace", "trace.json"),
+substrs=["intel-pt"])
+
+# Check the output when not doing live tracing
+self.expect("process trace save -d " +
+os.path.join(self.getBuildDir(), "intelpt-trace", "trace_not_live_dir"),
+substrs=["error: Saving a trace requires a live process."],
+error=True)
+
+
+def testSaveTrace(self):
+self.expect("target create " +
+os.path.join(self.getSourceDir(), "intelpt-trace", "a.out"))
+self.expect("b main")
+self.expect("r")
+self.expect("thread trace start")
+self.expect("b 7")
+
+ci = self.dbg.GetCommandInterpreter()
+res = lldb.SBCommandReturnObject()
+
+ci.HandleCommand("thread trace dump instructions -c 10 --forwards", res)
+self.assertEqual(res.Succeeded(), True)
+first_ten_instructions = res.GetOutput()
+
+ci.HandleCommand("thread trace dump instructions -c 10", res)
+self.assertEqual(res.Succeeded(), True)
+last_ten_instructions = res.GetOutput()
+
+# Now, save the trace to 
+self.expect("process trace save -d " +
+os.path.join(self.getBuildDir(), "intelpt-trace", "trace_copy_dir"))
+
+# Load the trace just saved
+self.expect("trace load -v " +
+os.path.join(self.getBuildDir(), "intelpt-trace",