[Lldb-commits] [lldb] 752e9cd - [trace][intelpt][docs] Added intel-pt build instructions for lldb
Author: Alisamar Husain Date: 2022-03-19T15:26:59+05:30 New Revision: 752e9cdbb06affae5c082c31c4f5ea53e46e92c6 URL: https://github.com/llvm/llvm-project/commit/752e9cdbb06affae5c082c31c4f5ea53e46e92c6 DIFF: https://github.com/llvm/llvm-project/commit/752e9cdbb06affae5c082c31c4f5ea53e46e92c6.diff LOG: [trace][intelpt][docs] Added intel-pt build instructions for lldb Differential Revision: https://reviews.llvm.org/D121935 Added: lldb/docs/use/intel_pt.rst Modified: lldb/docs/index.rst Removed: diff --git a/lldb/docs/index.rst b/lldb/docs/index.rst index e189c432c4fef..3b47ee52eb394 100644 --- a/lldb/docs/index.rst +++ b/lldb/docs/index.rst @@ -139,6 +139,7 @@ interesting areas to contribute to lldb. use/qemu-testing use/troubleshooting use/links + use/intel_pt .. toctree:: :hidden: diff --git a/lldb/docs/use/intel_pt.rst b/lldb/docs/use/intel_pt.rst new file mode 100644 index 0..40f9043102f76 --- /dev/null +++ b/lldb/docs/use/intel_pt.rst @@ -0,0 +1,232 @@ +Tracing with Intel Processor Trace (Intel PT) += + +.. contents:: + :local: + +Intel PT is a technology available in modern Intel CPUs that allows efficient +tracing of all the instructions executed by a process. +LLDB can collect traces and dump them using its symbolication stack. +You can read more here +https://easyperf.net/blog/2019/08/23/Intel-Processor-Trace. + +Prerequisites +- + +Confirm that your CPU supports Intel PT +(see https://www.intel.com/content/www/us/en/support/articles/56730/processors.html) +and that your operating system is Linux. + +Check for the existence of this particular file on your Linux system +:: + + $ cat /sys/bus/event_source/devices/intel_pt/type + +The output should be a number. Otherwise, try upgrading your kernel. + + +Build Instructions +-- + +Clone and build the low level Intel PT +decoder library [LibIPT library](https://github.com/intel/libipt). +:: + + $ git clone g...@github.com:intel/libipt.git + $ mkdir libipt-build + $ cmake -S libipt -B libipt-build + $ cd libipt-build + $ make + +This will generate a few files in the `/lib` +and `/libipt/include` directories. + +Configure and build LLDB with Intel PT support +:: + + $ cmake \ + -DLLDB_BUILD_INTEL_PT=ON \ + -DLIBIPT_INCLUDE_PATH="/libipt/include" \ + -DLIBIPT_LIBRARY_PATH="/lib" \ + ... other common configuration parameters + +:: + + $ cd && ninja lldb lldb-server # if using Ninja + + +How to Use +-- + +When you are debugging a process, you can turn on intel-pt tracing, +which will “record” all the instructions that the process will execute. +After turning it on, you can continue debugging, and at any breakpoint, +you can inspect the instruction list. + +For example: +:: + lldb + > b main + > run + > process trace start # start tracing on all threads, including future ones + # keep debugging until you hit a breakpoint + + > thread trace dump instructions + # this should output something like + + thread #2: tid = 2861133, total instructions = 5305673 +libc.so.6`__GI___libc_read + 45 at read.c:25:1 + [4962255] 0x7fffeb64c63dsubq $0x10, %rsp + [4962256] 0x7fffeb64c641movq %rdi, -0x18(%rbp) +libc.so.6`__GI___libc_read + 53 [inlined] __libc_read at read.c:26:10 + [4962257] 0x7fffeb64c645callq 0x7fffeb66b640; __libc_enable_asynccancel +libc.so.6`__libc_enable_asynccancel + [4962258] 0x7fffeb66b640movl %fs:0x308, %eax +libc.so.6`__libc_enable_asynccancel + 8 + [4962259] 0x7fffeb66b648movl %eax, %r11d + + # you can keep pressing ENTER to see more and more instructions + +The number between brackets is the instruction index, +and by default the current thread will be picked. + +Configuring the trace size +-- + +The CPU stores the instruction list in a compressed format in a ring buffer, +which keeps the latest information. +By default, LLDB uses a buffer of 4KB per thread, +but you can change it by running. +The size must be a power of 2 and at least 4KB. +:: + thread trace start all -s + +For reference, a 1MB trace buffer can easily store around 5M instructions. + +Printing more instructions +-- + +If you want to dump more instructions at a time, you can run +:: + thread trace dump instructions -c + +Printing the instructions of another thread +--- + +By default the current thread will be picked when dumping instructions, +but you can do +:: + thread trace dump instructions <#thread index> + #e.g. + thread trace dump instructions 8 + +to select another thread. + +Crash Analysis +-- + +What if you are debugging + tracing a process that crashes?
[Lldb-commits] [lldb] 1bcc28b - [docs] Fixed minor ordering issue
Author: Alisamar Husain Date: 2022-03-19T22:23:42+05:30 New Revision: 1bcc28b884ff4fbe2ecc011b8ea2b84e7987167b URL: https://github.com/llvm/llvm-project/commit/1bcc28b884ff4fbe2ecc011b8ea2b84e7987167b DIFF: https://github.com/llvm/llvm-project/commit/1bcc28b884ff4fbe2ecc011b8ea2b84e7987167b.diff LOG: [docs] Fixed minor ordering issue Differential Revision: https://reviews.llvm.org/D122073 Added: Modified: lldb/docs/index.rst lldb/docs/use/intel_pt.rst Removed: diff --git a/lldb/docs/index.rst b/lldb/docs/index.rst index 3b47ee52eb394..4a595590529a4 100644 --- a/lldb/docs/index.rst +++ b/lldb/docs/index.rst @@ -137,9 +137,9 @@ interesting areas to contribute to lldb. use/python-reference use/remote use/qemu-testing + use/intel_pt use/troubleshooting use/links - use/intel_pt .. toctree:: :hidden: diff --git a/lldb/docs/use/intel_pt.rst b/lldb/docs/use/intel_pt.rst index 40f9043102f76..95a13618b213f 100644 --- a/lldb/docs/use/intel_pt.rst +++ b/lldb/docs/use/intel_pt.rst @@ -1,5 +1,5 @@ -Tracing with Intel Processor Trace (Intel PT) -= +Tracing with Intel Processor Trace +== .. contents:: :local: ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] 8271220 - [trace][intelpt] Instruction count in trace info
Author: Alisamar Husain Date: 2022-03-20T11:28:16+05:30 New Revision: 8271220a9981d0cb3186e8fc25477f622ea5c2c9 URL: https://github.com/llvm/llvm-project/commit/8271220a9981d0cb3186e8fc25477f622ea5c2c9 DIFF: https://github.com/llvm/llvm-project/commit/8271220a9981d0cb3186e8fc25477f622ea5c2c9.diff LOG: [trace][intelpt] Instruction count in trace info Added a line to `thread trace dump info` results which shows total number of instructions executed until now. Differential Revision: https://reviews.llvm.org/D122076 Added: Modified: lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp lldb/test/API/commands/trace/TestTraceDumpInfo.py Removed: diff --git a/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp b/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp index 6ec957771e47d..831cd3764672c 100644 --- a/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp +++ b/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp @@ -110,7 +110,10 @@ void TraceIntelPT::DumpTraceInfo(Thread &thread, Stream &s, bool verbose) { s.Printf(", not traced\n"); return; } - s.Printf("\n Raw trace size: %zu bytes\n", *raw_size); + s.Printf("\n"); + s.Printf(" Raw trace size: %zu bytes\n", *raw_size); + s.Printf(" Total number of instructions: %zu\n", +Decode(thread)->GetInstructions().size()); return; } diff --git a/lldb/test/API/commands/trace/TestTraceDumpInfo.py b/lldb/test/API/commands/trace/TestTraceDumpInfo.py index 99877aaa27ae5..18088e07b8df3 100644 --- a/lldb/test/API/commands/trace/TestTraceDumpInfo.py +++ b/lldb/test/API/commands/trace/TestTraceDumpInfo.py @@ -38,4 +38,5 @@ def testDumpRawTraceSize(self): substrs=['''Trace technology: intel-pt thread #1: tid = 3842849 - Raw trace size: 4096 bytes''']) + Raw trace size: 4096 bytes + Total number of instructions: 21''']) ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] 37a466d - [trace][intelpt] Added total memory usage by decoded trace
Author: Alisamar Husain Date: 2022-03-21T12:36:08+05:30 New Revision: 37a466dd72b0c46090198c9f1779c384809c0662 URL: https://github.com/llvm/llvm-project/commit/37a466dd72b0c46090198c9f1779c384809c0662 DIFF: https://github.com/llvm/llvm-project/commit/37a466dd72b0c46090198c9f1779c384809c0662.diff LOG: [trace][intelpt] Added total memory usage by decoded trace This fails currently but the basics are there Differential Revision: https://reviews.llvm.org/D122093 Added: Modified: lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp lldb/source/Plugins/Trace/intel-pt/DecodedThread.h lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp lldb/test/API/commands/trace/TestTraceDumpInfo.py Removed: diff --git a/lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp b/lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp index 4822a786c68c1..a81a779302605 100644 --- a/lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp +++ b/lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp @@ -48,6 +48,8 @@ bool IntelPTInstruction::IsError() const { return (bool)m_error; } lldb::addr_t IntelPTInstruction::GetLoadAddress() const { return m_pt_insn.ip; } +size_t IntelPTInstruction::GetNonErrorMemoryUsage() { return sizeof(IntelPTInstruction); } + Optional IntelPTInstruction::GetTimestampCounter() const { return m_timestamp; } @@ -116,3 +118,9 @@ DecodedThread::DecodedThread(ThreadSP thread_sp, lldb::TraceCursorUP DecodedThread::GetCursor() { return std::make_unique(m_thread_sp, shared_from_this()); } + +size_t DecodedThread::CalculateApproximateMemoryUsage() const { + return m_raw_trace_size ++ IntelPTInstruction::GetNonErrorMemoryUsage() * m_instructions.size() ++ sizeof(DecodedThread); +} diff --git a/lldb/source/Plugins/Trace/intel-pt/DecodedThread.h b/lldb/source/Plugins/Trace/intel-pt/DecodedThread.h index 592c402cd0e50..4063012997045 100644 --- a/lldb/source/Plugins/Trace/intel-pt/DecodedThread.h +++ b/lldb/source/Plugins/Trace/intel-pt/DecodedThread.h @@ -81,6 +81,9 @@ class IntelPTInstruction { /// The instruction pointer address, or \a LLDB_INVALID_ADDRESS if it is /// an error. lldb::addr_t GetLoadAddress() const; + + /// Get the size in bytes of a non-error instance of this class + static size_t GetNonErrorMemoryUsage(); /// \return /// An \a llvm::Error object if this class corresponds to an Error, or an @@ -112,6 +115,8 @@ class IntelPTInstruction { IntelPTInstruction(const IntelPTInstruction &other) = delete; const IntelPTInstruction &operator=(const IntelPTInstruction &other) = delete; + // When adding new members to this class, make sure to update + // IntelPTInstruction::GetNonErrorMemoryUsage() if needed. pt_insn m_pt_insn; llvm::Optional m_timestamp; std::unique_ptr m_error; @@ -150,7 +155,13 @@ class DecodedThread : public std::enable_shared_from_this { /// The size of the trace. size_t GetRawTraceSize() const; + /// The approximate size in bytes used by this instance, + /// including all the already decoded instructions. + size_t CalculateApproximateMemoryUsage() const; + private: + /// When adding new members to this class, make sure + /// to update \a CalculateApproximateMemoryUsage() accordingly. lldb::ThreadSP m_thread_sp; std::vector m_instructions; size_t m_raw_trace_size; diff --git a/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp b/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp index 831cd3764672c..63318031f8893 100644 --- a/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp +++ b/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp @@ -111,9 +111,13 @@ void TraceIntelPT::DumpTraceInfo(Thread &thread, Stream &s, bool verbose) { return; } s.Printf("\n"); - s.Printf(" Raw trace size: %zu bytes\n", *raw_size); - s.Printf(" Total number of instructions: %zu\n", -Decode(thread)->GetInstructions().size()); + + size_t mem_used = Decode(thread)->CalculateApproximateMemoryUsage(); + s.Printf(" Raw trace size: %zu KiB\n", *raw_size / 1024); + s.Printf(" Total number of instructions: %zu\n", + Decode(thread)->GetInstructions().size()); + s.Printf(" Total approximate memory usage: %0.2lf KiB\n", + (double)mem_used / 1024); return; } diff --git a/lldb/test/API/commands/trace/TestTraceDumpInfo.py b/lldb/test/API/commands/trace/TestTraceDumpInfo.py index 18088e07b8df3..bc50b5274195a 100644 --- a/lldb/test/API/commands/trace/TestTraceDumpInfo.py +++ b/lldb/test/API/commands/trace/TestTraceDumpInfo.py @@ -38,5 +38,6 @@ def testDumpRawTraceSize(self): substrs=['''Trace technology: intel-pt thread #1: tid = 3842849 - Raw trace size: 4096 bytes - Total number of instructions: 21''']) + Raw trace size: 4 KiB + Total number of instructions: 21 + Total approximate memory usage: 5.38 KiB''']) ___
[Lldb-commits] [lldb] ca47011 - [tests][intelpt] Fix outdated trace load test
Author: Alisamar Husain Date: 2022-03-21T13:21:45+05:30 New Revision: ca47011e73e6ff0451b6a9c8de3d3f3044acec72 URL: https://github.com/llvm/llvm-project/commit/ca47011e73e6ff0451b6a9c8de3d3f3044acec72 DIFF: https://github.com/llvm/llvm-project/commit/ca47011e73e6ff0451b6a9c8de3d3f3044acec72.diff LOG: [tests][intelpt] Fix outdated trace load test Differential Revision: https://reviews.llvm.org/D122114 Added: Modified: lldb/test/API/commands/trace/TestTraceLoad.py Removed: diff --git a/lldb/test/API/commands/trace/TestTraceLoad.py b/lldb/test/API/commands/trace/TestTraceLoad.py index 896f0eade663f..f901e2b2d9eb6 100644 --- a/lldb/test/API/commands/trace/TestTraceLoad.py +++ b/lldb/test/API/commands/trace/TestTraceLoad.py @@ -36,7 +36,9 @@ def testLoadTrace(self): self.expect("thread trace dump info", substrs=['''Trace technology: intel-pt thread #1: tid = 3842849 - Raw trace size: 4096 bytes''']) + Raw trace size: 4 KiB + Total number of instructions: 21 + Total approximate memory usage: 5.38 KiB''']) def testLoadInvalidTraces(self): src_dir = self.getSourceDir() ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] 84caf73 - [lldb/docs] Fixed minor ugly links
Author: Alisamar Husain Date: 2022-03-23T13:00:18+05:30 New Revision: 84caf73c5287ab7ab32c669075133d3bcd719bf7 URL: https://github.com/llvm/llvm-project/commit/84caf73c5287ab7ab32c669075133d3bcd719bf7 DIFF: https://github.com/llvm/llvm-project/commit/84caf73c5287ab7ab32c669075133d3bcd719bf7.diff LOG: [lldb/docs] Fixed minor ugly links Added: Modified: lldb/docs/use/intel_pt.rst Removed: diff --git a/lldb/docs/use/intel_pt.rst b/lldb/docs/use/intel_pt.rst index a974c970d0a1a..7b46262ba52ee 100644 --- a/lldb/docs/use/intel_pt.rst +++ b/lldb/docs/use/intel_pt.rst @@ -227,5 +227,8 @@ Then it's like in the live session case References -- -- Original RFC document: https://docs.google.com/document/d/1cOVTGp1sL_HBXjP9eB7qjVtDNr5xnuZvUUtv43G5eVI. -- Some details about how Meta is using Intel Processor Trace can be found in this blog post https://engineering.fb.com/2021/04/27/developer-tools/reverse-debugging/. +- Original RFC document_ for this feature. +- Some details about how Meta is using Intel Processor Trace can be found in this blog_ post. + +.. _document: https://docs.google.com/document/d/1cOVTGp1sL_HBXjP9eB7qjVtDNr5xnuZvUUtv43G5eVI +.. _blog: https://engineering.fb.com/2021/04/27/developer-tools/reverse-debugging/ \ No newline at end of file ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] ca922a3 - [intelpt] Refactor timestamps out of `IntelPTInstruction`
Author: Alisamar Husain Date: 2022-04-01T21:51:42+05:30 New Revision: ca922a3559d7c537fefbf023b6c9fd0f8ff0ed9d URL: https://github.com/llvm/llvm-project/commit/ca922a3559d7c537fefbf023b6c9fd0f8ff0ed9d DIFF: https://github.com/llvm/llvm-project/commit/ca922a3559d7c537fefbf023b6c9fd0f8ff0ed9d.diff LOG: [intelpt] Refactor timestamps out of `IntelPTInstruction` Storing timestamps (TSCs) in a more efficient map at the decoded thread level to speed up TSC lookup, as well as reduce the amount of memory used by each decoded instruction. Also introduced TSC range which keeps the current timestamp valid for all subsequent instructions until the next timestamp is emitted. Differential Revision: https://reviews.llvm.org/D122603 Added: Modified: lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp lldb/source/Plugins/Trace/intel-pt/DecodedThread.h lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.cpp lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.h lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp lldb/test/API/commands/trace/TestTraceDumpInfo.py lldb/test/API/commands/trace/TestTraceLoad.py Removed: diff --git a/lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp b/lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp index 3c39c4d9a96d3..4ef689499188f 100644 --- a/lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp +++ b/lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp @@ -49,10 +49,6 @@ size_t IntelPTInstruction::GetMemoryUsage() { return sizeof(IntelPTInstruction); } -Optional IntelPTInstruction::GetTimestampCounter() const { - return m_timestamp; -} - Optional DecodedThread::GetRawTraceSize() const { return m_raw_trace_size; } @@ -90,6 +86,23 @@ IntelPTInstruction::GetControlFlowType(lldb::addr_t next_load_address) const { ThreadSP DecodedThread::GetThread() { return m_thread_sp; } +void DecodedThread::AppendInstruction(const pt_insn &insn) { + m_instructions.emplace_back(insn); +} + +void DecodedThread::AppendInstruction(const pt_insn &insn, uint64_t tsc) { + m_instructions.emplace_back(insn); + if (!m_last_tsc || *m_last_tsc != tsc) { +// In case the first instructions are errors or did not have a TSC, we'll +// get a first valid TSC not in position 0. We can safely force these error +// instructions to use the first valid TSC, so that all the trace has TSCs. +size_t start_index = +m_instruction_timestamps.empty() ? 0 : m_instructions.size() - 1; +m_instruction_timestamps.emplace(start_index, tsc); +m_last_tsc = tsc; + } +} + void DecodedThread::AppendError(llvm::Error &&error) { m_errors.try_emplace(m_instructions.size(), toString(std::move(error))); m_instructions.emplace_back(); @@ -99,8 +112,21 @@ ArrayRef DecodedThread::GetInstructions() const { return makeArrayRef(m_instructions); } -const char *DecodedThread::GetErrorByInstructionIndex(uint64_t idx) { - auto it = m_errors.find(idx); +Optional +DecodedThread::CalculateTscRange(size_t insn_index) const { + auto it = m_instruction_timestamps.upper_bound(insn_index); + if (it == m_instruction_timestamps.begin()) +return None; + + return TscRange(--it, *this); +} + +bool DecodedThread::IsInstructionAnError(size_t insn_idx) const { + return m_instructions[insn_idx].IsError(); +} + +const char *DecodedThread::GetErrorByInstructionIndex(size_t insn_idx) { + auto it = m_errors.find(insn_idx); if (it == m_errors.end()) return nullptr; @@ -125,7 +151,47 @@ lldb::TraceCursorUP DecodedThread::GetCursor() { } size_t DecodedThread::CalculateApproximateMemoryUsage() const { - return m_raw_trace_size.getValueOr(0) + - IntelPTInstruction::GetMemoryUsage() * m_instructions.size() + + return IntelPTInstruction::GetMemoryUsage() * m_instructions.size() + m_errors.getMemorySize(); } + +DecodedThread::TscRange::TscRange(std::map::const_iterator it, + const DecodedThread &decoded_thread) +: m_it(it), m_decoded_thread(&decoded_thread) { + auto next_it = m_it; + ++next_it; + m_end_index = (next_it == m_decoded_thread->m_instruction_timestamps.end()) +? m_decoded_thread->GetInstructions().size() - 1 +: next_it->first - 1; +} + +size_t DecodedThread::TscRange::GetTsc() const { return m_it->second; } + +size_t DecodedThread::TscRange::GetStartInstructionIndex() const { + return m_it->first; +} + +size_t DecodedThread::TscRange::GetEndInstructionIndex() const { + return m_end_index; +} + +bool DecodedThread::TscRange::InRange(size_t insn_index) { + return GetStartInstructionIndex() <= insn_index && + insn_index <= GetEndInstructionIndex(); +} + +Optional DecodedThread::TscRange::Next() { + auto next_it = m_it; + ++next_it; + if (next_it == m_decoded_thread->m_instruction_timestamps.end()) +return None; + return TscRange(n
[Lldb-commits] [lldb] d849959 - [lldb][intelpt] Remove `IntelPTInstruction` and move methods to `DecodedThread`
Author: Alisamar Husain Date: 2022-04-05T22:01:36+05:30 New Revision: d849959071c8478841a9e7b1bb625e00b848f1c7 URL: https://github.com/llvm/llvm-project/commit/d849959071c8478841a9e7b1bb625e00b848f1c7 DIFF: https://github.com/llvm/llvm-project/commit/d849959071c8478841a9e7b1bb625e00b848f1c7.diff LOG: [lldb][intelpt] Remove `IntelPTInstruction` and move methods to `DecodedThread` This is to reduce the size of the trace further and has appreciable results. Differential Revision: https://reviews.llvm.org/D122991 Added: Modified: lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp lldb/source/Plugins/Trace/intel-pt/DecodedThread.h lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.cpp lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp lldb/test/API/commands/trace/TestTraceDumpInfo.py lldb/test/API/commands/trace/TestTraceLoad.py Removed: diff --git a/lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp b/lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp index 994d068810f1e..a4bf0c725f7e6 100644 --- a/lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp +++ b/lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp @@ -35,38 +35,37 @@ void IntelPTError::log(llvm::raw_ostream &OS) const { OS << "error: " << libipt_error_message; } -IntelPTInstruction::IntelPTInstruction() { - m_pt_insn.ip = LLDB_INVALID_ADDRESS; - m_pt_insn.iclass = ptic_error; - m_is_error = true; +Optional DecodedThread::GetRawTraceSize() const { + return m_raw_trace_size; } -bool IntelPTInstruction::IsError() const { return m_is_error; } - -lldb::addr_t IntelPTInstruction::GetLoadAddress() const { return m_pt_insn.ip; } - -size_t IntelPTInstruction::GetMemoryUsage() { - return sizeof(IntelPTInstruction); +size_t DecodedThread::GetInstructionsCount() const { + return m_instruction_ips.size(); } -Optional DecodedThread::GetRawTraceSize() const { - return m_raw_trace_size; +lldb::addr_t DecodedThread::GetInstructionLoadAddress(size_t insn_index) const { + return m_instruction_ips[insn_index]; } TraceInstructionControlFlowType -IntelPTInstruction::GetControlFlowType(lldb::addr_t next_load_address) const { - if (IsError()) +DecodedThread::GetInstructionControlFlowType(size_t insn_index) const { + if (IsInstructionAnError(insn_index)) return (TraceInstructionControlFlowType)0; TraceInstructionControlFlowType mask = eTraceInstructionControlFlowTypeInstruction; - switch (m_pt_insn.iclass) { + lldb::addr_t load_address = m_instruction_ips[insn_index]; + uint8_t insn_byte_size = m_instruction_sizes[insn_index]; + pt_insn_class iclass = m_instruction_classes[insn_index]; + + switch (iclass) { case ptic_cond_jump: case ptic_jump: case ptic_far_jump: mask |= eTraceInstructionControlFlowTypeBranch; -if (m_pt_insn.ip + m_pt_insn.size != next_load_address) +if (insn_index + 1 < m_instruction_ips.size() && +load_address + insn_byte_size != m_instruction_ips[insn_index + 1]) mask |= eTraceInstructionControlFlowTypeTakenBranch; break; case ptic_return: @@ -92,14 +91,16 @@ void DecodedThread::RecordTscForLastInstruction(uint64_t tsc) { // get a first valid TSC not in position 0. We can safely force these error // instructions to use the first valid TSC, so that all the trace has TSCs. size_t start_index = -m_instruction_timestamps.empty() ? 0 : m_instructions.size() - 1; +m_instruction_timestamps.empty() ? 0 : m_instruction_ips.size() - 1; m_instruction_timestamps.emplace(start_index, tsc); m_last_tsc = tsc; } } void DecodedThread::AppendInstruction(const pt_insn &insn) { - m_instructions.emplace_back(insn); + m_instruction_ips.emplace_back(insn.ip); + m_instruction_sizes.emplace_back(insn.size); + m_instruction_classes.emplace_back(insn.iclass); } void DecodedThread::AppendInstruction(const pt_insn &insn, uint64_t tsc) { @@ -108,8 +109,10 @@ void DecodedThread::AppendInstruction(const pt_insn &insn, uint64_t tsc) { } void DecodedThread::AppendError(llvm::Error &&error) { - m_errors.try_emplace(m_instructions.size(), toString(std::move(error))); - m_instructions.emplace_back(); + m_errors.try_emplace(m_instruction_ips.size(), toString(std::move(error))); + m_instruction_ips.emplace_back(LLDB_INVALID_ADDRESS); + m_instruction_sizes.emplace_back(0); + m_instruction_classes.emplace_back(pt_insn_class::ptic_unknown); } void DecodedThread::AppendError(llvm::Error &&error, uint64_t tsc) { @@ -130,10 +133,6 @@ const DecodedThread::LibiptErrors &DecodedThread::GetTscErrors() const { return m_tsc_errors; } -ArrayRef DecodedThread::GetInstructions() const { - return makeArrayRef(m_instructions); -} - Optional DecodedThread::CalculateTscRange(size_t insn_index) const { auto it = m_instruction_timestamps.upper_bound(insn_index); @@ -144,7 +143,7 @@ DecodedThrea