[Lldb-commits] [PATCH] D136557: [trace][intel pt] Simple detection of infinite decoding loops
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
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
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
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
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
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 &