[Lldb-commits] [PATCH] D136557: [trace][intel pt] Simple detection of infinite decoding loops

2022-10-25 Thread Phabricator via lldb-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGc49d14aca5c7: [trace][intel pt] Simple detection of infinite 
decoding loops (authored by Walter Erquinigo ).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D136557

Files:
  lldb/include/lldb/Core/PluginManager.h
  lldb/source/Core/PluginManager.cpp
  lldb/source/Plugins/Trace/intel-pt/CMakeLists.txt
  lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp
  lldb/source/Plugins/Trace/intel-pt/DecodedThread.h
  lldb/source/Plugins/Trace/intel-pt/LibiptDecoder.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTProperties.td
  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
@@ -37,6 +37,12 @@
   "totalCount": 0,
   "individualCounts": {}
 },
+"errors": {
+  "totalCount": 0,
+  "libiptErrors": {},
+  "fatalErrors": 0,
+  "otherErrors": 0
+},
 "continuousExecutions": 0,
 "PSBBlocks": 0
   },
@@ -72,6 +78,12 @@
 "HW clock tick": 8
   }
 },
+"errors": {
+  "totalCount": 1,
+  "libiptErrors": {},
+  "fatalErrors": 0,
+  "otherErrors": 1
+},
 "continuousExecutions": 1,
 "PSBBlocks": 1
   },
Index: lldb/test/API/commands/trace/TestTraceDumpInfo.py
===
--- lldb/test/API/commands/trace/TestTraceDumpInfo.py
+++ lldb/test/API/commands/trace/TestTraceDumpInfo.py
@@ -78,6 +78,12 @@
 "software disabled tracing": 2,
 "trace synchronization point": 1
   }
+},
+"errors": {
+  "totalCount": 0,
+  "libiptErrors": {},
+  "fatalErrors": 0,
+  "otherErrors": 0
 }
   },
   "globalStats": {
Index: lldb/source/Plugins/Trace/intel-pt/TraceIntelPTProperties.td
===
--- /dev/null
+++ lldb/source/Plugins/Trace/intel-pt/TraceIntelPTProperties.td
@@ -0,0 +1,24 @@
+include "../../../../include/lldb/Core/PropertiesBase.td"
+
+let Definition = "traceintelpt" in {
+  def InfiniteDecodingLoopVerificationThreshold:
+  Property<"infinite-decoding-loop-verification-threshold", "UInt64">,
+Global,
+DefaultUnsignedValue<1>,
+Desc<"Specify how many instructions following an individual Intel PT "
+  "packet must have been decoded before triggering the verification of "
+  "infinite decoding loops. If no decoding loop has been found after this "
+  "threshold T, another attempt will be done after 2T instructions, then "
+  "4T, 8T and so on, which guarantees a total linear time spent checking "
+  "this anomaly. If a loop is found, then decoding of the corresponding "
+  "PSB block is stopped. An error is hence emitted in the trace and "
+  "decoding is resumed in the next PSB block.">;
+  def ExtremelyLargeDecodingThreshold:
+  Property<"extremely-large-decoding-threshold", "UInt64">,
+Global,
+DefaultUnsignedValue<50>,
+Desc<"Specify how many instructions following an individual Intel PT "
+  "packet must have been decoded before stopping the decoding of the "
+  "corresponding PSB block. An error is hence emitted in the trace and "
+  "decoding is resumed in the next PSB block.">;
+}
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
@@ -22,6 +22,23 @@
 
 class TraceIntelPT : public Trace {
 public:
+  /// Properties to be used with the `settings` command.
+  class PluginProperties : public Properties {
+  public:
+static ConstString GetSettingName();
+
+PluginProperties();
+
+~PluginProperties() override = default;
+
+uint64_t GetInfiniteDecodingLoopVerificationThreshold();
+
+uint64_t GetExtremelyLargeDecodingThreshold();
+  };
+
+  /// Return the global properties for this trace plug-in.
+  static PluginProperties &GetGlobalProperties();
+
   void Dump(Stream *s) const override;
 
   llvm::Expected SaveToDisk(FileSpec directory,
@@ -59,6 +76,8 @@
   CreateInstanceForLiveProcess(Process &process);
 
   static llvm::StringRef GetPluginNameStatic() { return "intel-pt"; }
+
+  static void DebuggerInitialize(Debugger &debugger);
   /// \}
 
   lldb::CommandObjectSP
Index: lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
===
--- lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
+++ ll

[Lldb-commits] [PATCH] D136557: [trace][intel pt] Simple detection of infinite decoding loops

2022-10-24 Thread walter erquinigo via Phabricator via lldb-commits
wallace updated this revision to Diff 470343.
wallace added a comment.

address issues and comments


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D136557

Files:
  lldb/include/lldb/Core/PluginManager.h
  lldb/source/Core/PluginManager.cpp
  lldb/source/Plugins/Trace/intel-pt/CMakeLists.txt
  lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp
  lldb/source/Plugins/Trace/intel-pt/DecodedThread.h
  lldb/source/Plugins/Trace/intel-pt/LibiptDecoder.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTProperties.td
  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
@@ -37,6 +37,12 @@
   "totalCount": 0,
   "individualCounts": {}
 },
+"errors": {
+  "totalCount": 0,
+  "libiptErrors": {},
+  "fatalErrors": 0,
+  "otherErrors": 0
+},
 "continuousExecutions": 0,
 "PSBBlocks": 0
   },
@@ -72,6 +78,12 @@
 "HW clock tick": 8
   }
 },
+"errors": {
+  "totalCount": 1,
+  "libiptErrors": {},
+  "fatalErrors": 0,
+  "otherErrors": 1
+},
 "continuousExecutions": 1,
 "PSBBlocks": 1
   },
Index: lldb/test/API/commands/trace/TestTraceDumpInfo.py
===
--- lldb/test/API/commands/trace/TestTraceDumpInfo.py
+++ lldb/test/API/commands/trace/TestTraceDumpInfo.py
@@ -78,6 +78,12 @@
 "software disabled tracing": 2,
 "trace synchronization point": 1
   }
+},
+"errors": {
+  "totalCount": 0,
+  "libiptErrors": {},
+  "fatalErrors": 0,
+  "otherErrors": 0
 }
   },
   "globalStats": {
Index: lldb/source/Plugins/Trace/intel-pt/TraceIntelPTProperties.td
===
--- /dev/null
+++ lldb/source/Plugins/Trace/intel-pt/TraceIntelPTProperties.td
@@ -0,0 +1,24 @@
+include "../../../../include/lldb/Core/PropertiesBase.td"
+
+let Definition = "traceintelpt" in {
+  def InfiniteDecodingLoopVerificationThreshold:
+  Property<"infinite-decoding-loop-verification-threshold", "UInt64">,
+Global,
+DefaultUnsignedValue<1>,
+Desc<"Specify how many instructions following an individual Intel PT "
+  "packet must have been decoded before triggering the verification of "
+  "infinite decoding loops. If no decoding loop has been found after this "
+  "threshold T, another attempt will be done after 2T instructions, then "
+  "4T, 8T and so on, which guarantees a total linear time spent checking "
+  "this anomaly. If a loop is found, then decoding of the corresponding "
+  "PSB block is stopped. An error is hence emitted in the trace and "
+  "decoding is resumed in the next PSB block.">;
+  def ExtremelyLargeDecodingThreshold:
+  Property<"extremely-large-decoding-threshold", "UInt64">,
+Global,
+DefaultUnsignedValue<50>,
+Desc<"Specify how many instructions following an individual Intel PT "
+  "packet must have been decoded before stopping the decoding of the "
+  "corresponding PSB block. An error is hence emitted in the trace and "
+  "decoding is resumed in the next PSB block.">;
+}
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
@@ -22,6 +22,23 @@
 
 class TraceIntelPT : public Trace {
 public:
+  /// Properties to be used with the `settings` command.
+  class PluginProperties : public Properties {
+  public:
+static ConstString GetSettingName();
+
+PluginProperties();
+
+~PluginProperties() override = default;
+
+uint64_t GetInfiniteDecodingLoopVerificationThreshold();
+
+uint64_t GetExtremelyLargeDecodingThreshold();
+  };
+
+  /// Return the global properties for this trace plug-in.
+  static PluginProperties &GetGlobalProperties();
+
   void Dump(Stream *s) const override;
 
   llvm::Expected SaveToDisk(FileSpec directory,
@@ -59,6 +76,8 @@
   CreateInstanceForLiveProcess(Process &process);
 
   static llvm::StringRef GetPluginNameStatic() { return "intel-pt"; }
+
+  static void DebuggerInitialize(Debugger &debugger);
   /// \}
 
   lldb::CommandObjectSP
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
@@ -16,6 +16,7 @@
 #include "TraceIntelPTBundleSaver.h"
 #include "T

[Lldb-commits] [PATCH] D136557: [trace][intel pt] Simple detection of infinite decoding loops

2022-10-24 Thread walter erquinigo via Phabricator via lldb-commits
wallace added inline comments.



Comment at: lldb/source/Plugins/Trace/intel-pt/DecodedThread.h:123
 /// of a DenseMap because DenseMap can't understand enums.
-std::unordered_map events_counts;
-size_t total_count = 0;
+std::unordered_map events_counts;
+uint64_t total_count = 0;

jj10306 wrote:
> 
ahh good one



Comment at: lldb/source/Plugins/Trace/intel-pt/DecodedThread.h:130
+  // Struct holding counts for errors
+  struct ErrorStats {
+/// The following counters are mutually exclusive

jj10306 wrote:
> nice, I was about to add this as part of my diff (:
oh nice!



Comment at: lldb/source/Plugins/Trace/intel-pt/LibiptDecoder.cpp:206
+  }
+  m_next_infinite_decoding_loop_threshold *= 2;
+}

jj10306 wrote:
> can you explain why we are increasing the threshold?
the idea is to check for infinite loops sporadically without making the total 
checks in O(N^2) and instead do it in O(N)

If we first do a linear check in the trace, which is O(T) after T instructions 
are appended and there are no loops, we might want to check again in the 
future. We could wait for the next T instructions and then run another check, 
and if we fail, wait for the next T and so on. This result in a total time 
spent of O(T + 2T + 3T + 4T + ... + N) which is O(N^2). Instead, we can run the 
check after 2T, and then after 4T and then after 8T and so on. This gives us a 
geometric progression of (N + N/2 + N / 4 + ... + T) which is amortized total 
O(N). A similar algorithm is vector::push_back 
(https://cs.stackexchange.com/questions/9380/why-is-push-back-in-c-vectors-constant-amortized)
 which is total O(N) using a similar approach.



Comment at: lldb/source/Plugins/Trace/intel-pt/LibiptDecoder.cpp:235-241
+if (m_decoded_thread.GetInstructionLoadAddress(last_insn_index) !=
+eTraceItemKindInstruction) {
+  if (Optional prev_index = prev_insn_index(last_insn_index)) {
+last_insn_index = *prev_index;
+  } else {
+return None;
+  }

jj10306 wrote:
> if you move the `--item_index` in `prev_insn_index` lambda, would that allow 
> you to remove this duplicated `eTraceItemKindInstruction` check and instead 
> unconditionally call `prev_insn_index`?
> or would this not work because the intention of the lamda is to skip the 
> current event even if it's already an instruction
I like your idea. I think I can simplify the code



Comment at: lldb/source/Plugins/Trace/intel-pt/LibiptDecoder.cpp:281
+lldb::addr_t new_packet_offset;
+if (!IsLibiptError(pt_insn_get_offset(&m_decoder, &new_packet_offset)) &&
+new_packet_offset != m_last_packet_offset) {

jj10306 wrote:
> help me understand this please. I thought `pt_insn_get_offset` would always 
> return a new, increasing offset every time this function is called.
Not really. pt_insn_get_offset returns the offset of the last packet that was 
processed, and that single could lead to many individual sequential 
instructions until the next packet is needed.
 
Let's imagine that you have this trace

PSB with starting address of 0xAAA
TNT with 4 bits
TIP with address 0xFFF

What the decoder will do is to first read the PSB and start at IP 0xAAA. It'll 
then decode sequential instructions until it reaches the first branch or jump. 
It then needs to read the next packet, which is the TNT with 4 bits, so it will 
help decode the next 4 branches but not the fifth one. So the decoder will 
change the offset and resume decoding instructions sequentially until that 
fifth branch (or jump) is reached. Then the decoder will read the next packet, 
which is a TIP and tells the decoder to jump to address 0xFFF.
So this means that with the PSB, the decoder produced, let's say, 10 
instructions, and with the TNT maybe 1000 were produced,, and then the decoder 
moved to the offset of the TIP for the next instruction.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D136557

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


[Lldb-commits] [PATCH] D136557: [trace][intel pt] Simple detection of infinite decoding loops

2022-10-24 Thread Jakob Johnson via Phabricator via lldb-commits
jj10306 requested changes to this revision.
jj10306 added a comment.
This revision now requires changes to proceed.

looks good overall, mainly some questions and a few nits




Comment at: lldb/source/Plugins/Trace/intel-pt/DecodedThread.h:123
 /// of a DenseMap because DenseMap can't understand enums.
-std::unordered_map events_counts;
-size_t total_count = 0;
+std::unordered_map events_counts;
+uint64_t total_count = 0;





Comment at: lldb/source/Plugins/Trace/intel-pt/DecodedThread.h:130
+  // Struct holding counts for errors
+  struct ErrorStats {
+/// The following counters are mutually exclusive

nice, I was about to add this as part of my diff (:



Comment at: lldb/source/Plugins/Trace/intel-pt/LibiptDecoder.cpp:206
+  }
+  m_next_infinite_decoding_loop_threshold *= 2;
+}

can you explain why we are increasing the threshold?



Comment at: lldb/source/Plugins/Trace/intel-pt/LibiptDecoder.cpp:235-241
+if (m_decoded_thread.GetInstructionLoadAddress(last_insn_index) !=
+eTraceItemKindInstruction) {
+  if (Optional prev_index = prev_insn_index(last_insn_index)) {
+last_insn_index = *prev_index;
+  } else {
+return None;
+  }

if you move the `--item_index` in `prev_insn_index` lambda, would that allow 
you to remove this duplicated `eTraceItemKindInstruction` check and instead 
unconditionally call `prev_insn_index`?
or would this not work because the intention of the lamda is to skip the 
current event even if it's already an instruction



Comment at: lldb/source/Plugins/Trace/intel-pt/LibiptDecoder.cpp:281
+lldb::addr_t new_packet_offset;
+if (!IsLibiptError(pt_insn_get_offset(&m_decoder, &new_packet_offset)) &&
+new_packet_offset != m_last_packet_offset) {

help me understand this please. I thought `pt_insn_get_offset` would always 
return a new, increasing offset every time this function is called.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D136557

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


[Lldb-commits] [PATCH] D136557: [trace][intel pt] Simple detection of infinite decoding loops

2022-10-23 Thread walter erquinigo via Phabricator via lldb-commits
wallace updated this revision to Diff 470047.
wallace edited the summary of this revision.
wallace added a comment.

.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D136557

Files:
  lldb/include/lldb/Core/PluginManager.h
  lldb/source/Core/PluginManager.cpp
  lldb/source/Plugins/Trace/intel-pt/CMakeLists.txt
  lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp
  lldb/source/Plugins/Trace/intel-pt/DecodedThread.h
  lldb/source/Plugins/Trace/intel-pt/LibiptDecoder.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTProperties.td
  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
@@ -37,6 +37,12 @@
   "totalCount": 0,
   "individualCounts": {}
 },
+"errors": {
+  "totalCount": 0,
+  "libiptErrors": {},
+  "fatalErrors": 0,
+  "otherErrors": 0
+},
 "continuousExecutions": 0,
 "PSBBlocks": 0
   },
@@ -72,6 +78,12 @@
 "HW clock tick": 8
   }
 },
+"errors": {
+  "totalCount": 1,
+  "libiptErrors": {},
+  "fatalErrors": 0,
+  "otherErrors": 1
+},
 "continuousExecutions": 1,
 "PSBBlocks": 1
   },
Index: lldb/test/API/commands/trace/TestTraceDumpInfo.py
===
--- lldb/test/API/commands/trace/TestTraceDumpInfo.py
+++ lldb/test/API/commands/trace/TestTraceDumpInfo.py
@@ -78,6 +78,12 @@
 "software disabled tracing": 2,
 "trace synchronization point": 1
   }
+},
+"errors": {
+  "totalCount": 0,
+  "libiptErrors": {},
+  "fatalErrors": 0,
+  "otherErrors": 0
 }
   },
   "globalStats": {
Index: lldb/source/Plugins/Trace/intel-pt/TraceIntelPTProperties.td
===
--- /dev/null
+++ lldb/source/Plugins/Trace/intel-pt/TraceIntelPTProperties.td
@@ -0,0 +1,24 @@
+include "../../../../include/lldb/Core/PropertiesBase.td"
+
+let Definition = "traceintelpt" in {
+  def InfiniteDecodingLoopVerificationThreshold:
+  Property<"infinite-decoding-loop-verification-threshold", "UInt64">,
+Global,
+DefaultUnsignedValue<1>,
+Desc<"Specify how many instructions following an individual Intel PT "
+  "packet must have been decoded before triggering the verification of "
+  "infinite decoding loops. If no decoding loop has been found after this "
+  "threshold T, another attempt will be done after 2T instructions, then "
+  "4T, 8T and so on, which guarantees a total linear time spent checking "
+  "this anomaly. If a loop is found, then decoding of the corresponding "
+  "PSB block is stopped. An error is hence emitted in the trace and "
+  "decoding is resumed in the next PSB block.">;
+  def ExtremelyLargeDecodingThreshold:
+  Property<"extremely-large-decoding-threshold", "UInt64">,
+Global,
+DefaultUnsignedValue<50>,
+Desc<"Specify how many instructions following an individual Intel PT "
+  "packet must have been decoded before stopping the decoding of the "
+  "corresponding PSB block. An error is hence emitted in the trace and "
+  "decoding is resumed in the next PSB block.">;
+}
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
@@ -22,6 +22,23 @@
 
 class TraceIntelPT : public Trace {
 public:
+  /// Properties to be used with the `settings` command.
+  class PluginProperties : public Properties {
+  public:
+static ConstString GetSettingName();
+
+PluginProperties();
+
+~PluginProperties() override = default;
+
+uint64_t GetInfiniteDecodingLoopVerificationThreshold();
+
+uint64_t GetExtremelyLargeDecodingThreshold();
+  };
+
+  /// Return the global properties for this trace plug-in.
+  static PluginProperties &GetGlobalProperties();
+
   void Dump(Stream *s) const override;
 
   llvm::Expected SaveToDisk(FileSpec directory,
@@ -59,6 +76,8 @@
   CreateInstanceForLiveProcess(Process &process);
 
   static llvm::StringRef GetPluginNameStatic() { return "intel-pt"; }
+
+  static void DebuggerInitialize(Debugger &debugger);
   /// \}
 
   lldb::CommandObjectSP
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
@@ -16,6 +16,7 @@
 #include "TraceIntelPTBundleSa

[Lldb-commits] [PATCH] D136557: [trace][intel pt] Simple detection of infinite decoding loops

2022-10-23 Thread walter erquinigo via Phabricator via lldb-commits
wallace created this revision.
wallace added reviewers: jj10306, persona0220.
Herald added a project: All.
wallace requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

The low-level decoder might fall into an infinite decoding loop for
various reasons, the simplest being an infinite direct loop reached due
to wrong handling of self-modified in the kernel, e.g.

  0x0A: pause
  0x0C: jump to 0x0A

In this case, all the code is sequential and requires no packets to be
decoded. The low-level decoder would produce an output like the
following

  0x0A: pause
  0x0C: jump to 0x0A
  0x0A: pause
  0x0C: jump to 0x0A
  0x0A: pause
  0x0C: jump to 0x0A
  ... infinite amount of times

These cases are pretty much undecodable, so the least we can do is to
identify if we have found a case like this one and show then an error in
the trace.

- Add a check that breaks decoding of a single PSB once 200k

instructions have been decoding after the last packet was processed.

- Add a `settings` property for tweaking this number. This is nice

because does the basic work needed for future settings.

Some notes are added in the code. I haven't been unable to create a test
case, but it's found in the thread #12 of the trace
72533820-3eb8-4465-b8e4-4e6bf0ccca99 at Meta. We have to figure out how to
artificially create traces with this kind of anomalies.

With this change, that anomalous thread now shows:

  (lldb) thread trace dump instructions 12 -e -i 213100
  
  thread #12: tid = 8
  ...missing instructions
  213100: (error) decoding truncated: possible infinite decoding loop 
detected
vmlinux-5.12.0-0_fbk8_clang_6656_gc85768aa64da`panic_smp_self_stop + 7 at 
panic.c:87:2
  213099: 0x81342787jmp0x81342785; <+5> 
[inlined] rep_nop at processor.h:13:2
vmlinux-5.12.0-0_fbk8_clang_6656_gc85768aa64da`panic_smp_self_stop + 5 
[inlined] rep_nop at processor.h:13:2
  213098: 0x81342785pause
vmlinux-5.12.0-0_fbk8_clang_6656_gc85768aa64da`panic_smp_self_stop + 7 at 
panic.c:87:2
  213097: 0x81342787jmp0x81342785; <+5> 
[inlined] rep_nop at processor.h:13:2
vmlinux-5.12.0-0_fbk8_clang_6656_gc85768aa64da`panic_smp_self_stop + 5 
[inlined] rep_nop at processor.h:13:2
  213096: 0x81342785pause
vmlinux-5.12.0-0_fbk8_clang_6656_gc85768aa64da`panic_smp_self_stop + 7 at 
panic.c:87:2
  213095: 0x81342787jmp0x81342785; <+5> 
[inlined] rep_nop at processor.h:13:2
vmlinux-5.12.0-0_fbk8_clang_6656_gc85768aa64da`panic_smp_self_stop + 5 
[inlined] rep_nop at processor.h:13:2
  213094: 0x81342785pause
vmlinux-5.12.0-0_fbk8_clang_6656_gc85768aa64da`panic_smp_self_stop + 7 at 
panic.c:87:2
  213093: 0x81342787jmp0x81342785; <+5> 
[inlined] rep_nop at processor.h:13:2
...

It used to be in an infinite loop.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D136557

Files:
  lldb/include/lldb/Core/PluginManager.h
  lldb/source/Core/PluginManager.cpp
  lldb/source/Plugins/Trace/intel-pt/CMakeLists.txt
  lldb/source/Plugins/Trace/intel-pt/LibiptDecoder.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPTProperties.td

Index: lldb/source/Plugins/Trace/intel-pt/TraceIntelPTProperties.td
===
--- /dev/null
+++ lldb/source/Plugins/Trace/intel-pt/TraceIntelPTProperties.td
@@ -0,0 +1,13 @@
+include "../../../../include/lldb/Core/PropertiesBase.td"
+
+let Definition = "traceintelpt" in {
+  def InfiniteDecodingLoopVerificationThreshold:
+  Property<"infinite-decoding-loop-veritication-threshold", "UInt64">,
+Global,
+DefaultUnsignedValue<20>,
+Desc<"Specify how many instructions following an individual Intel PT "
+  "packet must have been decoded before triggering the verification for "
+  "infinite decoding loops, which might happen if the image is corrupted, "
+  "such as with self-modifying code. If an infinite loop is detected, an "
+  "error will be included inside the trace.">;
+}
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
@@ -22,6 +22,21 @@
 
 class TraceIntelPT : public Trace {
 public:
+  /// Properties to be used with the `settings` command.
+  class PluginProperties : public Properties {
+  public:
+static ConstString GetSettingName();
+
+PluginProperties();
+
+~PluginProperties() override = default;
+
+uint64_t GetInfiniteDecodingLoopVerificationThreshold();
+  };
+
+  /// Return the global properties for this trace plug-in.
+  static PluginProperties &