[Lldb-commits] [lldb] d36ae49 - Add string conversion for InstructionControlFlowKind enum
Author: Jakob Johnson Date: 2022-07-26T16:09:57-07:00 New Revision: d36ae4952d709cf303a92cd4dfe38650c1c49bb1 URL: https://github.com/llvm/llvm-project/commit/d36ae4952d709cf303a92cd4dfe38650c1c49bb1 DIFF: https://github.com/llvm/llvm-project/commit/d36ae4952d709cf303a92cd4dfe38650c1c49bb1.diff LOG: Add string conversion for InstructionControlFlowKind enum Refactor the string conversion of the `lldb::InstructionControlFlowKind` enum out of `Instruction::Dump` to enable reuse of this logic by the JSON TraceDumper (to be implemented in separate diff). Will coordinate the landing of this change with D130320 since there will be a minor merge conflict between these changes. Test Plan: Run unittests ``` > ninja check-lldb [4/5] Running lldb unit test suite Testing Time: 10.13s Passed: 1084 ``` Verify '-k' flag's output ``` (lldb) thread trace dump instructions -k thread #1: tid = 1375377 libstdc++.so.6`std::ostream::flush() + 43 7048: 0x77b54dabreturn retq 7047: 0x77b54daaother popq %rbx 7046: 0x77b54da7other movq %rbx, %rax 7045: 0x77b54da5cond jump je 0x11adb0 ; <+48> 7044: 0x77b54da2other cmpl $-0x1, %eax libc.so.6`_IO_fflush + 249 7043: 0x77161729return retq 7042: 0x77161728other popq %rbp 7041: 0x77161727other popq %rbx 7040: 0x77161725other movl %edx, %eax 7039: 0x77161721other addq $0x8, %rsp 7038: 0x77161709cond jump je 0x87721 ; <+241> 7037: 0x77161707other decl (%rsi) 7036: 0x771616fecond jump je 0x87707 ; <+215> 7035: 0x771616f7other cmpl $0x0, 0x33de92(%rip) ; __libc_multiple_threads 7034: 0x771616efother movq $0x0, 0x8(%rsi) 7033: 0x771616edcond jump jne0x87721 ; <+241> 7032: 0x771616e9other subl $0x1, 0x4(%rsi) 7031: 0x771616e2other movq 0x88(%rbx), %rsi 7030: 0x771616e0cond jump jne0x87721 ; <+241> 7029: 0x771616daother testl $0x8000, (%rbx) ; imm = 0x8000 ``` Differential Revision: https://reviews.llvm.org/D130580 Added: Modified: lldb/include/lldb/Core/Disassembler.h lldb/source/Core/Disassembler.cpp Removed: diff --git a/lldb/include/lldb/Core/Disassembler.h b/lldb/include/lldb/Core/Disassembler.h index 99d1b45ea5998..b9ac0a5bca39c 100644 --- a/lldb/include/lldb/Core/Disassembler.h +++ b/lldb/include/lldb/Core/Disassembler.h @@ -226,6 +226,9 @@ class Instruction { virtual bool IsCall() { return false; } + static const char *GetNameForInstructionControlFlowKind( + lldb::InstructionControlFlowKind instruction_control_flow_kind); + protected: Address m_address; // The section offset address of this instruction // We include an address class in the Instruction class to diff --git a/lldb/source/Core/Disassembler.cpp b/lldb/source/Core/Disassembler.cpp index 81a0e1e74642e..4c57be44dc9c5 100644 --- a/lldb/source/Core/Disassembler.cpp +++ b/lldb/source/Core/Disassembler.cpp @@ -577,6 +577,30 @@ AddressClass Instruction::GetAddressClass() { return m_address_class; } +const char *Instruction::GetNameForInstructionControlFlowKind( +lldb::InstructionControlFlowKind instruction_control_flow_kind) { + switch (instruction_control_flow_kind) { + case eInstructionControlFlowKindUnknown: +return "unknown"; + case eInstructionControlFlowKindOther: +return "other"; + case eInstructionControlFlowKindCall: +return "call"; + case eInstructionControlFlowKindReturn: +return "return"; + case eInstructionControlFlowKindJump: +return "jump"; + case eInstructionControlFlowKindCondJump: +return "cond jump"; + case eInstructionControlFlowKindFarCall: +return "far call"; + case eInstructionControlFlowKindFarReturn: +return "far return"; + case eInstructionControlFlowKindFarJump: +return "far jump"; + } +} + void Instruction::Dump(lldb_private::Stream *s, uint32_t max_opcode_byte_size, bool show_address, bool show_bytes, bool show_control_flow_kind, @@ -618,35 +642,10 @@ void Instruction::Dump(lldb_private::Stream *s, uint32_t max_opcode_byte_size, } if (show_control_flow_kind) { -switch (GetControlFlowKind(exe_ctx)) { -case eInstructionControlFlowKindUnknown: - ss.Printf("%-12s", "unknown"); - break; -case eInstructionControlFlowKindOther: - ss.Printf("%-12s", "other"); - break; -case eInstructionControlFlowKindCall: - ss.Printf("%-12s", "call"
[Lldb-commits] [lldb] dde3cf2 - [trace] Add instruction control flow kind to JSON trace dumper's output
Author: Jakob Johnson Date: 2022-07-27T05:23:59-07:00 New Revision: dde3cf2e83d2a2aec5b46bdac64efbc28a3b2b20 URL: https://github.com/llvm/llvm-project/commit/dde3cf2e83d2a2aec5b46bdac64efbc28a3b2b20 DIFF: https://github.com/llvm/llvm-project/commit/dde3cf2e83d2a2aec5b46bdac64efbc28a3b2b20.diff LOG: [trace] Add instruction control flow kind to JSON trace dumper's output D128477 adds a '-k' flag which displays each instruction's control flow in the `thread trace dump instructions` command's non-json output (ie no '-j' or '-J' flag) This diff adds the instruction control flow kind to the `thread trace dump instructions` command's JSON output (ie '-j' or '-J' flag) Test Plan: Confirm "controlFlowKind" is present in JSON when '-k' is provided ``` (lldb) thread trace dump instructions -J -k [ { [141/1952] "id": 7755, "loadAddress": "0x400868", "module": "test.out", "symbol": "main", "mnemonic": "jmp", "controlFlowKind": "jump", "source": "/home/jakobjohnson/jakob-dev/test.cpp", "line": 41, "column": 29 }, { "id": 7753, "loadAddress": "0x77b54dab", "module": "libstdc++.so.6", "symbol": "std::ostream::flush()", "mnemonic": "retq", "controlFlowKind": "return" }, { "id": 7752, "loadAddress": "0x77b54daa", "module": "libstdc++.so.6", "symbol": "std::ostream::flush()", "mnemonic": "popq", "controlFlowKind": "other" }, ... ] ``` Confirm "controlFlowKind" is not present when '-k' isn't provided ``` (lldb) thread trace dump instructions -J [ { "id": 7755, "loadAddress": "0x400868", "module": "test.out", "symbol": "main", "mnemonic": "jmp", "source": "/home/jakobjohnson/jakob-dev/test.cpp", "line": 41, "column": 29 }, { "id": 7753, "loadAddress": "0x77b54dab", "module": "libstdc++.so.6", "symbol": "std::ostream::flush()", "mnemonic": "retq" }, { "id": 7752, "loadAddress": "0x77b54daa", "module": "libstdc++.so.6", "symbol": "std::ostream::flush()", "mnemonic": "popq" }, ``` Differential Revision: https://reviews.llvm.org/D130607 Added: Modified: lldb/source/Target/TraceDumper.cpp Removed: diff --git a/lldb/source/Target/TraceDumper.cpp b/lldb/source/Target/TraceDumper.cpp index 5b71e9e4e97a8..872530b657a1b 100644 --- a/lldb/source/Target/TraceDumper.cpp +++ b/lldb/source/Target/TraceDumper.cpp @@ -199,6 +199,7 @@ class OutputWriterJSON : public TraceDumper::OutputWriter { "column"?: decimal, "source"?: string, "mnemonic"?: string, + "controlFlowKind"?: string, } */ public: @@ -234,10 +235,18 @@ class OutputWriterJSON : public TraceDumper::OutputWriter { "symbol", ToOptionalString(item.symbol_info->sc.GetFunctionName().AsCString())); - if (item.symbol_info->instruction) { + if (lldb::InstructionSP instruction = item.symbol_info->instruction) { +ExecutionContext exe_ctx = item.symbol_info->exe_ctx; m_j.attribute("mnemonic", - ToOptionalString(item.symbol_info->instruction->GetMnemonic( - &item.symbol_info->exe_ctx))); + ToOptionalString(instruction->GetMnemonic(&exe_ctx))); +if (m_options.show_control_flow_kind) { + lldb::InstructionControlFlowKind instruction_control_flow_kind = + instruction->GetControlFlowKind(&exe_ctx); + m_j.attribute("controlFlowKind", +ToOptionalString( +Instruction::GetNameForInstructionControlFlowKind( +instruction_control_flow_kind))); +} } if (IsLineEntryValid(item.symbol_info->sc.line_entry)) { ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] 9bab358 - [trace][intelpt] Update TraceIntelPTBundleSaver.cpp to accommodate FileSpec API changes
Author: Jakob Johnson Date: 2022-08-01T11:52:15-07:00 New Revision: 9bab358e39225a657be829962d7f9532b492ca93 URL: https://github.com/llvm/llvm-project/commit/9bab358e39225a657be829962d7f9532b492ca93 DIFF: https://github.com/llvm/llvm-project/commit/9bab358e39225a657be829962d7f9532b492ca93.diff LOG: [trace][intelpt] Update TraceIntelPTBundleSaver.cpp to accommodate FileSpec API changes D130309 introduced changes to the FileSpec API which broke usages of `GetCString()` in TraceIntelPTBundleSaver.cpp. This diff replaces usages of `GetCString()` with `GetPath().c_str()` as suggested by D130309. Test Plan: Building with the trace plug-in now succeeds Differential Revision: https://reviews.llvm.org/D130924 Added: Modified: lldb/source/Plugins/Trace/intel-pt/TraceIntelPTBundleSaver.cpp Removed: diff --git a/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTBundleSaver.cpp b/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTBundleSaver.cpp index 8be70dc2139be..f35914f26ab7c 100644 --- a/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTBundleSaver.cpp +++ b/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTBundleSaver.cpp @@ -103,7 +103,7 @@ BuildThreadsSection(Process &process, FileSpec directory) { FileSpec threads_dir = directory; threads_dir.AppendPathComponent("threads"); - sys::fs::create_directories(threads_dir.GetCString()); + sys::fs::create_directories(threads_dir.GetPath().c_str()); for (ThreadSP thread_sp : process.Threads()) { lldb::tid_t tid = thread_sp->GetID(); @@ -200,7 +200,7 @@ BuildCpusSection(TraceIntelPT &trace_ipt, FileSpec directory, bool compact) { std::vector json_cpus; FileSpec cpus_dir = directory; cpus_dir.AppendPathComponent("cpus"); - sys::fs::create_directories(cpus_dir.GetCString()); + sys::fs::create_directories(cpus_dir.GetPath().c_str()); for (lldb::cpu_id_t cpu_id : trace_ipt.GetTracedCpus()) { JSONCpu json_cpu; ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] 3bec33b - [trace] Replace TraceCursorUP with TraceCursorSP
Author: Jakob Johnson Date: 2022-08-01T13:53:53-07:00 New Revision: 3bec33b16db11c67d43bda134520a2132ff606c9 URL: https://github.com/llvm/llvm-project/commit/3bec33b16db11c67d43bda134520a2132ff606c9 DIFF: https://github.com/llvm/llvm-project/commit/3bec33b16db11c67d43bda134520a2132ff606c9.diff LOG: [trace] Replace TraceCursorUP with TraceCursorSP The use of `std::unique_ptr` with `TraceCursor` adds unnecessary complexity to adding `SBTraceCursor` bindings Specifically, since `TraceCursor` is an abstract class there's no clean way to provide "deep clone" semantics for `TraceCursorUP` short of creating a pure virtual `clone()` method (afaict). After discussing with @wallace, we decided there is no strong reason to favor wrapping `TraceCursor` with `std::unique_ptr` over `std::shared_ptr`, thus this diff replaces all usages of `std::unique_ptr` with `std::shared_ptr`. This sets the stage for future diffs to introduce `SBTraceCursor` bindings in a more clean fashion. Test Plan: Differential Revision: https://reviews.llvm.org/D130925 Added: Modified: lldb/include/lldb/Target/Trace.h lldb/include/lldb/Target/TraceCursor.h lldb/include/lldb/Target/TraceDumper.h lldb/include/lldb/lldb-forward.h lldb/source/Commands/CommandObjectThread.cpp lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.cpp lldb/source/Target/TraceDumper.cpp Removed: diff --git a/lldb/include/lldb/Target/Trace.h b/lldb/include/lldb/Target/Trace.h index beae9e28417d..917e66992ad1 100644 --- a/lldb/include/lldb/Target/Trace.h +++ b/lldb/include/lldb/Target/Trace.h @@ -169,9 +169,9 @@ class Trace : public PluginInterface, /// Get a \a TraceCursor for the given thread's trace. /// /// \return - /// A \a TraceCursorUP. If the thread is not traced or its trace + /// A \a TraceCursorSP. If the thread is not traced or its trace /// information failed to load, an \a llvm::Error is returned. - virtual llvm::Expected + virtual llvm::Expected CreateNewCursor(Thread &thread) = 0; /// Dump general info about a given thread's trace. Each Trace plug-in diff --git a/lldb/include/lldb/Target/TraceCursor.h b/lldb/include/lldb/Target/TraceCursor.h index 95b022331634..4e405aeaab7c 100644 --- a/lldb/include/lldb/Target/TraceCursor.h +++ b/lldb/include/lldb/Target/TraceCursor.h @@ -52,7 +52,7 @@ namespace lldb_private { /// /// Sample usage: /// -/// TraceCursorUP cursor = trace.GetTrace(thread); +/// TraceCursorSP cursor = trace.GetTrace(thread); /// /// for (; cursor->HasValue(); cursor->Next()) { /// TraceItemKind kind = cursor->GetItemKind(); diff --git a/lldb/include/lldb/Target/TraceDumper.h b/lldb/include/lldb/Target/TraceDumper.h index ada779990e07..ab3f77916751 100644 --- a/lldb/include/lldb/Target/TraceDumper.h +++ b/lldb/include/lldb/Target/TraceDumper.h @@ -93,7 +93,7 @@ class TraceDumper { /// /// \param[in] options /// Additional options for configuring the dumping. - TraceDumper(lldb::TraceCursorUP &&cursor_up, Stream &s, + TraceDumper(lldb::TraceCursorSP cursor_sp, Stream &s, const TraceDumperOptions &options); /// Dump \a count instructions of the thread trace starting at the current @@ -114,7 +114,7 @@ class TraceDumper { /// Create a trace item for the current position without symbol information. TraceItem CreatRawTraceItem(); - lldb::TraceCursorUP m_cursor_up; + lldb::TraceCursorSP m_cursor_sp; TraceDumperOptions m_options; std::unique_ptr m_writer_up; }; diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h index c51e1850338f..fd88a45ba06f 100644 --- a/lldb/include/lldb/lldb-forward.h +++ b/lldb/include/lldb/lldb-forward.h @@ -420,7 +420,7 @@ typedef std::weak_ptr ThreadPlanWP; typedef std::shared_ptr ThreadPlanTracerSP; typedef std::shared_ptr TraceSP; typedef std::unique_ptr TraceExporterUP; -typedef std::unique_ptr TraceCursorUP; +typedef std::shared_ptr TraceCursorSP; typedef std::shared_ptr TypeSP; typedef std::weak_ptr TypeWP; typedef std::shared_ptr TypeCategoryImplSP; diff --git a/lldb/source/Commands/CommandObjectThread.cpp b/lldb/source/Commands/CommandObjectThread.cpp index fe0cb0945cde..9aa128aaa288 100644 --- a/lldb/source/Commands/CommandObjectThread.cpp +++ b/lldb/source/Commands/CommandObjectThread.cpp @@ -2269,17 +2269,17 @@ class CommandObjectTraceDumpInstructions : public CommandObjectParsed { m_options.m_dumper_options.id = m_last_id; } -llvm::Expected cursor_or_error = +llvm::Expected cursor_or_error = m_exe_ctx.GetTargetSP()->GetTrace()->CreateNewCursor(*thread_sp); if (!cursor_or_error) { result.AppendError(llvm::toString(cursor_or_error.takeError())); return f
[Lldb-commits] [lldb] 6cbc6e9 - [LLDB] Add SBInstruction::GetControlFlowKind()
Author: Jakob Johnson Date: 2022-08-02T15:42:45-07:00 New Revision: 6cbc6e9a6d5f0ef9c406f718dd0c3e6dd6dffeef URL: https://github.com/llvm/llvm-project/commit/6cbc6e9a6d5f0ef9c406f718dd0c3e6dd6dffeef DIFF: https://github.com/llvm/llvm-project/commit/6cbc6e9a6d5f0ef9c406f718dd0c3e6dd6dffeef.diff LOG: [LLDB] Add SBInstruction::GetControlFlowKind() D128477 adds the control flow kind for `Instruction` and displays this in the `thread trace dump instruction -k` command. This diff exposes the control flow kind via the new `SBInstruction::GetControlFlowKind` method. I've expanded `TestDisassembleRawData` to test this method, but please let me know if there are any other unittests that should also be updated. Test Plan: `./bin/lldb-dotest -p TestDisassembleRawData` Differential Revision: https://reviews.llvm.org/D131005 Added: Modified: lldb/bindings/interface/SBInstruction.i lldb/include/lldb/API/SBInstruction.h lldb/source/API/SBInstruction.cpp lldb/test/API/python_api/disassemble-raw-data/TestDisassembleRawData.py Removed: diff --git a/lldb/bindings/interface/SBInstruction.i b/lldb/bindings/interface/SBInstruction.i index e9e018b7deed0..a467a6f0d93db 100644 --- a/lldb/bindings/interface/SBInstruction.i +++ b/lldb/bindings/interface/SBInstruction.i @@ -44,6 +44,9 @@ public: const char * GetComment (lldb::SBTarget target); +lldb::InstructionControlFlowKind +GetControlFlowKind(lldb::SBTarget target); + lldb::SBData GetData (lldb::SBTarget target); diff --git a/lldb/include/lldb/API/SBInstruction.h b/lldb/include/lldb/API/SBInstruction.h index b9d781550b5da..def9482b02ed0 100644 --- a/lldb/include/lldb/API/SBInstruction.h +++ b/lldb/include/lldb/API/SBInstruction.h @@ -43,6 +43,8 @@ class LLDB_API SBInstruction { const char *GetComment(lldb::SBTarget target); + lldb::InstructionControlFlowKind GetControlFlowKind(lldb::SBTarget target); + lldb::SBData GetData(lldb::SBTarget target); size_t GetByteSize(); diff --git a/lldb/source/API/SBInstruction.cpp b/lldb/source/API/SBInstruction.cpp index ced22628a2979..b03d8f73d66eb 100644 --- a/lldb/source/API/SBInstruction.cpp +++ b/lldb/source/API/SBInstruction.cpp @@ -164,6 +164,25 @@ const char *SBInstruction::GetComment(SBTarget target) { return nullptr; } +lldb::InstructionControlFlowKind SBInstruction::GetControlFlowKind(lldb::SBTarget target) { + LLDB_INSTRUMENT_VA(this, target); + + lldb::InstructionSP inst_sp(GetOpaque()); + if (inst_sp) { +ExecutionContext exe_ctx; +TargetSP target_sp(target.GetSP()); +std::unique_lock lock; +if (target_sp) { + lock = std::unique_lock(target_sp->GetAPIMutex()); + + target_sp->CalculateExecutionContext(exe_ctx); + exe_ctx.SetProcessSP(target_sp->GetProcessSP()); +} +return inst_sp->GetControlFlowKind(&exe_ctx); + } + return lldb::eInstructionControlFlowKindUnknown; +} + size_t SBInstruction::GetByteSize() { LLDB_INSTRUMENT_VA(this); diff --git a/lldb/test/API/python_api/disassemble-raw-data/TestDisassembleRawData.py b/lldb/test/API/python_api/disassemble-raw-data/TestDisassembleRawData.py index 677559c4a5160..4186e6b330f08 100644 --- a/lldb/test/API/python_api/disassemble-raw-data/TestDisassembleRawData.py +++ b/lldb/test/API/python_api/disassemble-raw-data/TestDisassembleRawData.py @@ -52,16 +52,26 @@ def test_disassemble_raw_data(self): self.assertEqual(inst.GetMnemonic(target), "move") self.assertEqual(inst.GetOperands(target), '$' + "fp, " + '$' + "sp") +self.assertEqual(inst.GetControlFlowKind(target), +lldb.eInstructionControlFlowKindUnknown) elif re.match("powerpc64le", arch): self.assertEqual(inst.GetMnemonic(target), "li") self.assertEqual(inst.GetOperands(target), "4, 0") +self.assertEqual(inst.GetControlFlowKind(target), +lldb.eInstructionControlFlowKindUnknown) elif arch in ("aarch64", "arm64"): self.assertEqual(inst.GetMnemonic(target), "mov") self.assertEqual(inst.GetOperands(target), "w0, #0x63") +self.assertEqual(inst.GetControlFlowKind(target), +lldb.eInstructionControlFlowKindUnknown) elif arch == "arm": self.assertEqual(inst.GetMnemonic(target), "mov") self.assertEqual(inst.GetOperands(target), "r3, #99") +self.assertEqual(inst.GetControlFlowKind(target), +lldb.eInstructionControlFlowKindUnknown) else: self.assertEqual(inst.GetMnemonic(target), "movq") self.assertEqual(inst.GetOperands(target), '%' + "rsp, " + '%' + "rbp") +self.assertEqual(inst.GetControlFlowKind(target), +
[Lldb-commits] [lldb] f9b4ea0 - [trace] Add SBTraceCursor bindings
Author: Jakob Johnson Date: 2022-08-02T16:55:33-07:00 New Revision: f9b4ea0ce9efb4132a75551c40b2efc049e5b9f7 URL: https://github.com/llvm/llvm-project/commit/f9b4ea0ce9efb4132a75551c40b2efc049e5b9f7 DIFF: https://github.com/llvm/llvm-project/commit/f9b4ea0ce9efb4132a75551c40b2efc049e5b9f7.diff LOG: [trace] Add SBTraceCursor bindings Add bindings for the `TraceCursor` to allow for programatic traversal of traces. This diff adds bindings for all public `TraceCursor` methods except `GetHwClock` and also adds `SBTrace::CreateNewCursor`. A new unittest has been added to TestTraceLoad.py that uses the new `SBTraceCursor` API to test that the sequential and random access APIs of the `TraceCursor` are equivalent. This diff depends on D130925. Test Plan: `ninja lldb-dotest && ./bin/lldb-dotest -p TestTraceLoad` Differential Revision: https://reviews.llvm.org/D130930 Added: lldb/bindings/interface/SBTraceCursor.i lldb/include/lldb/API/SBTraceCursor.h lldb/source/API/SBTraceCursor.cpp Modified: lldb/bindings/interface/SBTrace.i lldb/bindings/interfaces.swig lldb/include/lldb/API/SBDefines.h lldb/include/lldb/API/SBTrace.h lldb/include/lldb/Target/TraceCursor.h lldb/include/lldb/lldb-defines.h lldb/include/lldb/lldb-enumerations.h lldb/source/API/CMakeLists.txt lldb/source/API/SBTrace.cpp lldb/source/Commands/CommandObjectThread.cpp 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/TraceExporter/common/TraceHTR.cpp lldb/source/Target/TraceDumper.cpp lldb/test/API/commands/trace/TestTraceLoad.py Removed: diff --git a/lldb/bindings/interface/SBTrace.i b/lldb/bindings/interface/SBTrace.i index 0d74881a3f3d8..e947572c0f848 100644 --- a/lldb/bindings/interface/SBTrace.i +++ b/lldb/bindings/interface/SBTrace.i @@ -15,6 +15,8 @@ class LLDB_API SBTrace { public: SBTrace(); + SBTraceCursor CreateNewCursor(SBError &error, SBThread &thread); + const char *GetStartConfigurationHelp(); SBFileSpec SaveToDisk(SBError &error, const SBFileSpec &bundle_dir, bool compact = false); diff --git a/lldb/bindings/interface/SBTraceCursor.i b/lldb/bindings/interface/SBTraceCursor.i new file mode 100644 index 0..c1c73de311031 --- /dev/null +++ b/lldb/bindings/interface/SBTraceCursor.i @@ -0,0 +1,58 @@ +//===-- SWIG Interface for SBTraceCursor.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 +// +//===--===// + +namespace lldb { + +%feature("docstring", +"Represents a trace cursor." +) SBTrace; +class LLDB_API SBTraceCursor { +public: + SBTraceCursor(); + + SBTraceCursor(lldb::TraceCursorSP trace_cursor_sp); + + void SetForwards(bool forwards); + + bool IsForwards() const; + + void Next(); + + bool HasValue(); + + bool GoToId(lldb::user_id_t id); + + bool HasId(lldb::user_id_t id) const; + + lldb::user_id_t GetId() const; + + bool Seek(int64_t offset, lldb::TraceCursorSeekType origin); + + lldb::TraceItemKind GetItemKind() const; + + bool IsError() const; + + const char *GetError() const; + + bool IsEvent() const; + + lldb::TraceEvent GetEventType() const; + + const char *GetEventTypeAsString() const; + + bool IsInstruction() const; + + lldb::addr_t GetLoadAddress() const; + + lldb::cpu_id_t GetCPU() const; + + bool IsValid() const; + + explicit operator bool() const; +}; +} // namespace lldb diff --git a/lldb/bindings/interfaces.swig b/lldb/bindings/interfaces.swig index c9a6d0f060568..fb75513a0df1b 100644 --- a/lldb/bindings/interfaces.swig +++ b/lldb/bindings/interfaces.swig @@ -69,6 +69,7 @@ %include "./interface/SBThreadCollection.i" %include "./interface/SBThreadPlan.i" %include "./interface/SBTrace.i" +%include "./interface/SBTraceCursor.i" %include "./interface/SBType.i" %include "./interface/SBTypeCategory.i" %include "./interface/SBTypeEnumMember.i" diff --git a/lldb/include/lldb/API/SBDefines.h b/lldb/include/lldb/API/SBDefines.h index ecf1dc34d8c58..6833c0542c168 100644 --- a/lldb/include/lldb/API/SBDefines.h +++ b/lldb/include/lldb/API/SBDefines.h @@ -88,6 +88,7 @@ class LLDB_API SBThread; class LLDB_API SBThreadCollection; class LLDB_API SBThreadPlan; class LLDB_API SBTrace; +class LLDB_API SBTraceCursor; class LLDB_API SBType; class LLDB_API SBTypeCategory; class LLDB_API SBTypeEnumMember; diff --git a/lldb/include/lldb/API/SBTrace.h b/lldb/include/lldb/API/SBTrace.h index 19d759013955c..7929d217ef268 100644 --- a/lldb/include/lldb/
[Lldb-commits] [lldb] 2207762 - Minor refactor and renaming:
Author: Jakob Johnson Date: 2022-03-16T15:35:36-07:00 New Revision: 22077627ae20d5a6e50f43337e8ad2e23f1fa3ff URL: https://github.com/llvm/llvm-project/commit/22077627ae20d5a6e50f43337e8ad2e23f1fa3ff DIFF: https://github.com/llvm/llvm-project/commit/22077627ae20d5a6e50f43337e8ad2e23f1fa3ff.diff LOG: Minor refactor and renaming: - Rename IntelPTManager class and files to IntelPTCollector - Change GetTimestampCounter API to general trace counter API, GetCounter Differential Revision: https://reviews.llvm.org/D121711 Added: lldb/source/Plugins/Process/Linux/IntelPTCollector.cpp lldb/source/Plugins/Process/Linux/IntelPTCollector.h lldb/unittests/Process/Linux/IntelPTCollectorTests.cpp Modified: lldb/include/lldb/Target/TraceCursor.h lldb/include/lldb/lldb-enumerations.h lldb/source/Plugins/Process/Linux/CMakeLists.txt lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp lldb/source/Plugins/Process/Linux/NativeProcessLinux.h lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.cpp lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.h lldb/source/Target/TraceInstructionDumper.cpp lldb/unittests/Process/Linux/CMakeLists.txt Removed: lldb/source/Plugins/Process/Linux/IntelPTManager.cpp lldb/source/Plugins/Process/Linux/IntelPTManager.h lldb/unittests/Process/Linux/IntelPTManagerTests.cpp diff --git a/lldb/include/lldb/Target/TraceCursor.h b/lldb/include/lldb/Target/TraceCursor.h index 14fc00d5f95b1..83ab22b367c53 100644 --- a/lldb/include/lldb/Target/TraceCursor.h +++ b/lldb/include/lldb/Target/TraceCursor.h @@ -180,14 +180,16 @@ class TraceCursor { /// LLDB_INVALID_ADDRESS. virtual lldb::addr_t GetLoadAddress() = 0; - /// Get the timestamp counter associated with the current instruction. - /// Modern Intel, ARM and AMD processors support this counter. However, a - /// trace plugin might decide to use a diff erent time unit instead of an - /// actual TSC. + /// Get the hardware counter of a given type associated with the current + /// instruction. Each architecture might support diff erent counters. It might + /// happen that only some instructions of an entire trace have a given counter + /// associated with them. /// + /// \param[in] counter_type + ///The counter type. /// \return - /// The timestamp or \b llvm::None if not available. - virtual llvm::Optional GetTimestampCounter() = 0; + /// The value of the counter or \b llvm::None if not available. + virtual llvm::Optional GetCounter(lldb::TraceCounter counter_type) = 0; /// \return /// The \a lldb::TraceInstructionControlFlowType categories the diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h index 529ab001a761f..294c68d54fd0c 100644 --- a/lldb/include/lldb/lldb-enumerations.h +++ b/lldb/include/lldb/lldb-enumerations.h @@ -1141,6 +1141,12 @@ enum SaveCoreStyle { eSaveCoreStackOnly = 3, }; +// Type of counter values associated with instructions in a trace. +enum TraceCounter { + // Timestamp counter, like the one offered by Intel CPUs (TSC). + eTraceCounterTSC, +}; + } // namespace lldb #endif // LLDB_LLDB_ENUMERATIONS_H diff --git a/lldb/source/Plugins/Process/Linux/CMakeLists.txt b/lldb/source/Plugins/Process/Linux/CMakeLists.txt index c4edc57a8a2d8..60958bb913960 100644 --- a/lldb/source/Plugins/Process/Linux/CMakeLists.txt +++ b/lldb/source/Plugins/Process/Linux/CMakeLists.txt @@ -1,5 +1,5 @@ add_lldb_library(lldbPluginProcessLinux - IntelPTManager.cpp + IntelPTCollector.cpp NativeProcessLinux.cpp NativeRegisterContextLinux.cpp NativeRegisterContextLinux_arm.cpp diff --git a/lldb/source/Plugins/Process/Linux/IntelPTManager.cpp b/lldb/source/Plugins/Process/Linux/IntelPTCollector.cpp similarity index 96% rename from lldb/source/Plugins/Process/Linux/IntelPTManager.cpp rename to lldb/source/Plugins/Process/Linux/IntelPTCollector.cpp index 794689b1d3791..0e65c88a1f765 100644 --- a/lldb/source/Plugins/Process/Linux/IntelPTManager.cpp +++ b/lldb/source/Plugins/Process/Linux/IntelPTCollector.cpp @@ -1,4 +1,4 @@ -//===-- IntelPTManager.cpp ===// +//===-- IntelPTCollector.cpp ===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -14,7 +14,7 @@ #include "llvm/Support/Error.h" #include "llvm/Support/MathExtras.h" -#include "IntelPTManager.h" +#include "IntelPTCollector.h" #include "Plugins/Process/POSIX/ProcessPOSIXLog.h" #include "lldb/Host/linux/Support.h" #include "lldb/Utility/StreamString.h" @@ -564,15 +564,15 @@ IntelPTProcessTrace::GetThreadTraces() const { return m_thread_traces; } -/// IntelPTManager +/// IntelPTCollector -Error IntelPTManager
[Lldb-commits] [lldb] e6c84f8 - Add thin wrapper for perf_event_open API
Author: Jakob Johnson Date: 2022-03-21T13:38:52-07:00 New Revision: e6c84f82b87576a57d1fa1c7e8c289d3d4fa7ab1 URL: https://github.com/llvm/llvm-project/commit/e6c84f82b87576a57d1fa1c7e8c289d3d4fa7ab1 DIFF: https://github.com/llvm/llvm-project/commit/e6c84f82b87576a57d1fa1c7e8c289d3d4fa7ab1.diff LOG: Add thin wrapper for perf_event_open API - Add PerfEvent class to handle creating ring buffers and handle the resources associated with a perf_event - Refactor IntelPT collection code to use this new API - Add TSC to timestamp conversion logic with unittest Differential Revision: https://reviews.llvm.org/D121734 Added: lldb/source/Plugins/Process/Linux/Perf.cpp lldb/source/Plugins/Process/Linux/Perf.h lldb/unittests/Process/Linux/PerfTests.cpp Modified: lldb/source/Plugins/Process/Linux/CMakeLists.txt lldb/source/Plugins/Process/Linux/IntelPTCollector.cpp lldb/source/Plugins/Process/Linux/IntelPTCollector.h lldb/unittests/Process/Linux/CMakeLists.txt lldb/unittests/Process/Linux/IntelPTCollectorTests.cpp Removed: diff --git a/lldb/source/Plugins/Process/Linux/CMakeLists.txt b/lldb/source/Plugins/Process/Linux/CMakeLists.txt index 60958bb913960..cc70edba3483e 100644 --- a/lldb/source/Plugins/Process/Linux/CMakeLists.txt +++ b/lldb/source/Plugins/Process/Linux/CMakeLists.txt @@ -8,6 +8,7 @@ add_lldb_library(lldbPluginProcessLinux NativeRegisterContextLinux_s390x.cpp NativeRegisterContextLinux_x86_64.cpp NativeThreadLinux.cpp + Perf.cpp SingleStepCheck.cpp LINK_LIBS diff --git a/lldb/source/Plugins/Process/Linux/IntelPTCollector.cpp b/lldb/source/Plugins/Process/Linux/IntelPTCollector.cpp index 0e65c88a1f765..5f31c10f8b88b 100644 --- a/lldb/source/Plugins/Process/Linux/IntelPTCollector.cpp +++ b/lldb/source/Plugins/Process/Linux/IntelPTCollector.cpp @@ -6,19 +6,23 @@ // //===--===// -#include -#include -#include +#include "IntelPTCollector.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/Error.h" -#include "llvm/Support/MathExtras.h" +#include "Perf.h" -#include "IntelPTCollector.h" #include "Plugins/Process/POSIX/ProcessPOSIXLog.h" #include "lldb/Host/linux/Support.h" #include "lldb/Utility/StreamString.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/MathExtras.h" + +#include +#include +#include +#include +#include #include #include @@ -53,6 +57,21 @@ enum IntelPTConfigFileType { BitOffset }; +/// Get the content of /proc/cpuinfo that can be later used to decode traces. +static Expected> GetCPUInfo() { + static llvm::Optional> cpu_info; + if (!cpu_info) { +auto buffer_or_error = errorOrToExpected(getProcFile("cpuinfo")); +if (!buffer_or_error) + return buffer_or_error.takeError(); +MemoryBuffer &buffer = **buffer_or_error; +cpu_info = std::vector( +reinterpret_cast(buffer.getBufferStart()), +reinterpret_cast(buffer.getBufferEnd())); + } + return *cpu_info; +} + static Expected ReadIntelPTConfigFile(const char *file, IntelPTConfigFileType type) { ErrorOr> stream = @@ -106,6 +125,7 @@ static Expected ReadIntelPTConfigFile(const char *file, } return value; } + /// Return the Linux perf event type for Intel PT. static Expected GetOSEventType() { return ReadIntelPTConfigFile(kOSEventIntelPTTypeFile, @@ -148,7 +168,7 @@ size_t IntelPTThreadTrace::GetTraceBufferSize() const { #ifndef PERF_ATTR_SIZE_VER5 llvm_unreachable("Intel PT Linux perf event not supported"); #else - return m_mmap_meta->aux_size; + return m_perf_event.GetAuxBuffer().size(); #endif } @@ -176,30 +196,9 @@ GeneratePerfEventConfigValue(bool enable_tsc, Optional psb_period) { return config; } -Error IntelPTThreadTrace::StartTrace(lldb::pid_t pid, lldb::tid_t tid, - uint64_t buffer_size, bool enable_tsc, - Optional psb_period) { -#ifndef PERF_ATTR_SIZE_VER5 - llvm_unreachable("Intel PT Linux perf event not supported"); -#else - Log *log = GetLog(POSIXLog::Ptrace); - - m_tid = tid; - LLDB_LOG(log, "called thread id {0}", tid); - uint64_t page_size = getpagesize(); - - if (__builtin_popcount(buffer_size) != 1 || buffer_size < 4096) { -return createStringError( -inconvertibleErrorCode(), -"The trace buffer size must be a power of 2 greater than or equal to " -"4096 (2^12) bytes. It was %" PRIu64 ".", -buffer_size); - } - uint64_t numpages = static_cast( - llvm::PowerOf2Floor((buffer_size + page_size - 1) / page_size)); - numpages = std::max(1, numpages); - buffer_size = page_size * numpages; - +llvm::Expected +IntelPTThreadTrace::CreateIntelPTPerfEventConfiguration( +bool enable_tsc, Optional psb_p
[Lldb-commits] [lldb] e412529 - Fix e6c84f82b87576a57d1fa1c7e8c289d3d4fa7ab1
Author: Jakob Johnson Date: 2022-03-21T14:00:39-07:00 New Revision: e412529c93ae86d580b8212e07a0a2a0a8ab5cda URL: https://github.com/llvm/llvm-project/commit/e412529c93ae86d580b8212e07a0a2a0a8ab5cda DIFF: https://github.com/llvm/llvm-project/commit/e412529c93ae86d580b8212e07a0a2a0a8ab5cda.diff LOG: Fix e6c84f82b87576a57d1fa1c7e8c289d3d4fa7ab1 Failed buildbot: https://lab.llvm.org/buildbot/#/builders/17/builds/19480 The fix seems to be simply be adding some type casts to make the compiler happy Added: Modified: lldb/source/Plugins/Process/Linux/Perf.cpp Removed: diff --git a/lldb/source/Plugins/Process/Linux/Perf.cpp b/lldb/source/Plugins/Process/Linux/Perf.cpp index 944076784b36d..455a81fbcbaff 100644 --- a/lldb/source/Plugins/Process/Linux/Perf.cpp +++ b/lldb/source/Plugins/Process/Linux/Perf.cpp @@ -171,11 +171,11 @@ ArrayRef PerfEvent::GetDataBuffer() const { perf_event_mmap_page &mmap_metadata = GetMetadataPage(); return {reinterpret_cast(m_metadata_data_base.get()) + mmap_metadata.data_offset, - mmap_metadata.data_size}; + static_cast(mmap_metadata.data_size)}; } ArrayRef PerfEvent::GetAuxBuffer() const { perf_event_mmap_page &mmap_metadata = GetMetadataPage(); return {reinterpret_cast(m_aux_base.get()), - mmap_metadata.aux_size}; + static_cast(mmap_metadata.aux_size)}; } ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] d137528 - Fix e6c84f82b87576a57d1fa1c7e8c289d3d4fa7ab1
Author: Jakob Johnson Date: 2022-03-21T14:35:14-07:00 New Revision: d13752851a4e134708f365a5b238e8ff375accaa URL: https://github.com/llvm/llvm-project/commit/d13752851a4e134708f365a5b238e8ff375accaa DIFF: https://github.com/llvm/llvm-project/commit/d13752851a4e134708f365a5b238e8ff375accaa.diff LOG: Fix e6c84f82b87576a57d1fa1c7e8c289d3d4fa7ab1 Failed buildbot: https://lab.llvm.org/buildbot/#/builders/68/builds/29250 Use toString() to consume the Error Added: Modified: lldb/unittests/Process/Linux/PerfTests.cpp Removed: diff --git a/lldb/unittests/Process/Linux/PerfTests.cpp b/lldb/unittests/Process/Linux/PerfTests.cpp index f8467d7042ef7..3a1c08c11cdfb 100644 --- a/lldb/unittests/Process/Linux/PerfTests.cpp +++ b/lldb/unittests/Process/Linux/PerfTests.cpp @@ -61,7 +61,7 @@ TEST(Perf, TscConversion) { // Skip the test if the conversion parameters aren't available. if (!params) -GTEST_SKIP() << params.takeError(); +GTEST_SKIP() << toString(params.takeError()); Expected tsc_before_sleep = readTsc(); sleep(SLEEP_SECS); @@ -69,9 +69,9 @@ TEST(Perf, TscConversion) { // Skip the test if we are unable to read the TSC value. if (!tsc_before_sleep) -GTEST_SKIP() << tsc_before_sleep.takeError(); +GTEST_SKIP() << toString(tsc_before_sleep.takeError()); if (!tsc_after_sleep) -GTEST_SKIP() << tsc_after_sleep.takeError(); +GTEST_SKIP() << toString(tsc_after_sleep.takeError()); std::chrono::nanoseconds converted_tsc_ diff = params->ToWallTime(*tsc_after_sleep) - ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] 45d9aab - Fix e6c84f82b87576a57d1fa1c7e8c289d3d4fa7ab1
Author: Jakob Johnson Date: 2022-03-21T15:02:02-07:00 New Revision: 45d9aab7a5a76b7317ec5571bc557158045a34df URL: https://github.com/llvm/llvm-project/commit/45d9aab7a5a76b7317ec5571bc557158045a34df DIFF: https://github.com/llvm/llvm-project/commit/45d9aab7a5a76b7317ec5571bc557158045a34df.diff LOG: Fix e6c84f82b87576a57d1fa1c7e8c289d3d4fa7ab1 Failed buildbot: https://lab.llvm.org/buildbot/#/builders/17/builds/19490 Only run perf event tsc conversion test on x86_64. Added: Modified: lldb/unittests/Process/Linux/PerfTests.cpp Removed: diff --git a/lldb/unittests/Process/Linux/PerfTests.cpp b/lldb/unittests/Process/Linux/PerfTests.cpp index 3a1c08c11cdfb..934d680e8c38b 100644 --- a/lldb/unittests/Process/Linux/PerfTests.cpp +++ b/lldb/unittests/Process/Linux/PerfTests.cpp @@ -6,6 +6,8 @@ // //===--===// +#ifdef __x86_64__ + #include "Perf.h" #include "llvm/Support/Error.h" @@ -83,3 +85,5 @@ TEST(Perf, TscConversion) { ASSERT_LT(converted_tsc_ diff .count(), (SLEEP_NANOS + acceptable_overhead).count()); } + +#endif // __x86_64__ ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] 9b79187 - [trace][intelpt] Server side changes for TSC to wall time conversion
Author: Jakob Johnson Date: 2022-03-24T05:36:21-07:00 New Revision: 9b79187c96a3bc2c245ab54d49accc12336f0cee URL: https://github.com/llvm/llvm-project/commit/9b79187c96a3bc2c245ab54d49accc12336f0cee DIFF: https://github.com/llvm/llvm-project/commit/9b79187c96a3bc2c245ab54d49accc12336f0cee.diff LOG: [trace][intelpt] Server side changes for TSC to wall time conversion Update the response schema of the TraceGetState packet and add Intel PT specific response structure that contains the TSC conversion, if it exists. The IntelPTCollector loads the TSC conversion and caches it to prevent unnecessary calls to perf_event_open. Move the TSC conversion calculation from Perf.h to TraceIntelPTGDBRemotePackets.h to remove dependency on Linux specific headers. Differential Revision: https://reviews.llvm.org/D122246 Added: lldb/unittests/Utility/TraceGDBRemotePacketsTest.cpp Modified: lldb/docs/lldb-gdb-remote.txt lldb/include/lldb/Utility/TraceGDBRemotePackets.h lldb/include/lldb/Utility/TraceIntelPTGDBRemotePackets.h lldb/source/Plugins/Process/Linux/IntelPTCollector.cpp lldb/source/Plugins/Process/Linux/IntelPTCollector.h lldb/source/Plugins/Process/Linux/Perf.cpp lldb/source/Plugins/Process/Linux/Perf.h lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.h lldb/source/Utility/TraceIntelPTGDBRemotePackets.cpp lldb/unittests/Process/Linux/PerfTests.cpp lldb/unittests/Utility/CMakeLists.txt Removed: diff --git a/lldb/docs/lldb-gdb-remote.txt b/lldb/docs/lldb-gdb-remote.txt index 980dc77c86f53..2ddc3183b80e7 100644 --- a/lldb/docs/lldb-gdb-remote.txt +++ b/lldb/docs/lldb-gdb-remote.txt @@ -451,7 +451,12 @@ read packet: OK/E;A //"size": , //Size in bytes of this thread data. // }, -//}] +//], +//"counters"?: { +// "info_kind": {...parameters specific to the provided counter info kind}, +// Each entry includes information related to counters associated with the trace. +// They are described below. +//} // } // // NOTES @@ -463,6 +468,26 @@ read packet: OK/E;A // Binary data kinds: //- threadTraceBuffer: trace buffer for a thread. //- cpuInfo: contents of the /proc/cpuinfo file. +// +// Counter info kinds: +//tsc-perf-zero-conversion: +// +//This field allows converting Intel processor's TSC values to a wall time. +//It is available through the Linux perf_event API when cap_user_time and cap_user_time_zero +//are set. +//See the documentation of time_zero in +//https://man7.org/linux/man-pages/man2/perf_event_open.2.html for more information about +//the calculation and the meaning of the values in the schema below. +/// +//Sub-schema for this field: +// +//{ +// "tsc-perf-zero-conversion": { +//"time_mult": , +//"time_shift": , +//"time_zero": , +// } +//} //-- send packet: jLLDBTraceGetState:{"type":}] diff --git a/lldb/include/lldb/Utility/TraceGDBRemotePackets.h b/lldb/include/lldb/Utility/TraceGDBRemotePackets.h index 1d2448b05f2a4..b2669ee3d813d 100644 --- a/lldb/include/lldb/Utility/TraceGDBRemotePackets.h +++ b/lldb/include/lldb/Utility/TraceGDBRemotePackets.h @@ -10,6 +10,7 @@ #define LLDB_UTILITY_TRACEGDBREMOTEPACKETS_H #include "llvm/Support/JSON.h" +#include #include "lldb/lldb-defines.h" #include "lldb/lldb-enumerations.h" @@ -116,6 +117,31 @@ bool fromJSON(const llvm::json::Value &value, TraceThreadState &packet, llvm::json::Value toJSON(const TraceThreadState &packet); +/// Interface for diff erent algorithms used to convert trace +/// counters into diff erent units. +template class TraceCounterConversion { +public: + virtual ~TraceCounterConversion() = default; + + /// Convert from raw counter value to the target type. + /// + /// \param[in] raw_counter_value + /// The raw counter value to be converted. + /// + /// \return + /// The converted counter value. + virtual ToType Convert(uint64_t raw_counter_value) = 0; + + /// Serialize trace counter conversion values to JSON. + /// + /// \return + /// \a llvm::json::Value representing the trace counter conversion object. + virtual llvm::json::Value toJSON() = 0; +}; + +using TraceTscConversionUP = +std::unique_ptr>; + struct TraceGetStateResponse { std::vector tracedThreads; std::vector processBinaryData; diff --git a/lldb/include/lldb/Utility/TraceIntelPTGDBRemotePackets.h b/lldb/include/lldb/Utility/TraceIntelPTGDBRemotePackets.h index 8f4947b1f189c..8960949f2039f 100644 --- a/lldb/include/lldb/Utility/TraceIntelPTGDBRemotePackets.h +++ b/lldb/include/lldb/Utility/TraceIntelPTGDBRemotePackets.h @@ -11,6 +11,10 @@ #include "lldb/Utility/TraceGDBRemotePackets.h" +#include "llvm/Support/JSON.h" + +#include + ///
[Lldb-commits] [lldb] 50f9367 - Add LoadTraceFromFile to SBDebugger and SBTrace
Author: Jakob Johnson Date: 2022-06-20T11:54:47-07:00 New Revision: 50f9367960725b450a9ef779d73e32a35031ee70 URL: https://github.com/llvm/llvm-project/commit/50f9367960725b450a9ef779d73e32a35031ee70 DIFF: https://github.com/llvm/llvm-project/commit/50f9367960725b450a9ef779d73e32a35031ee70.diff LOG: Add LoadTraceFromFile to SBDebugger and SBTrace Add trace load functionality to SBDebugger via the `LoadTraceFromFile` method. Update intelpt test case class to have `testTraceLoad` method so we can take advantage of the testApiAndSB decorator to test both the CLI and SB without duplicating code. Differential Revision: https://reviews.llvm.org/D128107 Added: Modified: lldb/bindings/interface/SBDebugger.i lldb/include/lldb/API/SBDebugger.h lldb/include/lldb/API/SBFileSpec.h lldb/include/lldb/API/SBTrace.h lldb/include/lldb/Target/Trace.h lldb/packages/Python/lldbsuite/test/tools/intelpt/intelpt_testcase.py lldb/source/API/SBDebugger.cpp lldb/source/API/SBTrace.cpp lldb/source/Commands/CommandObjectTrace.cpp lldb/source/Target/Trace.cpp lldb/test/API/commands/trace/TestTraceLoad.py Removed: diff --git a/lldb/bindings/interface/SBDebugger.i b/lldb/bindings/interface/SBDebugger.i index 2239f049c6514..5d51a6ac20d2f 100644 --- a/lldb/bindings/interface/SBDebugger.i +++ b/lldb/bindings/interface/SBDebugger.i @@ -542,6 +542,8 @@ Example: :: lldb::SBError RunREPL (lldb::LanguageType language, const char *repl_options); +SBTrace LoadTraceFromFile(SBError &error, const SBFileSpec &trace_description_file); + #ifdef SWIGPYTHON %pythoncode%{ def __iter__(self): diff --git a/lldb/include/lldb/API/SBDebugger.h b/lldb/include/lldb/API/SBDebugger.h index 6a23077175b92..b9a9b593d0ad4 100644 --- a/lldb/include/lldb/API/SBDebugger.h +++ b/lldb/include/lldb/API/SBDebugger.h @@ -391,6 +391,17 @@ class LLDB_API SBDebugger { SBError RunREPL(lldb::LanguageType language, const char *repl_options); + /// Load a trace from a trace description file and create Targets, + /// Processes and Threads based on the contents of such file. + /// + /// \param[out] error + /// An error if the trace could not be created. + /// + /// \param[in] trace_description_file + /// The file containing the necessary information to load the trace. + SBTrace LoadTraceFromFile(SBError &error, +const SBFileSpec &trace_description_file); + private: friend class SBCommandInterpreter; friend class SBInputReader; @@ -398,6 +409,7 @@ class LLDB_API SBDebugger { friend class SBProcess; friend class SBSourceManager; friend class SBTarget; + friend class SBTrace; lldb::SBTarget FindTargetWithLLDBProcess(const lldb::ProcessSP &processSP); diff --git a/lldb/include/lldb/API/SBFileSpec.h b/lldb/include/lldb/API/SBFileSpec.h index a2f02ac78208b..a286912f109e5 100644 --- a/lldb/include/lldb/API/SBFileSpec.h +++ b/lldb/include/lldb/API/SBFileSpec.h @@ -74,6 +74,7 @@ class LLDB_API SBFileSpec { friend class SBSourceManager; friend class SBTarget; friend class SBThread; + friend class SBTrace; SBFileSpec(const lldb_private::FileSpec &fspec); diff --git a/lldb/include/lldb/API/SBTrace.h b/lldb/include/lldb/API/SBTrace.h index 1685caaf4efa3..d5cf30f56637f 100644 --- a/lldb/include/lldb/API/SBTrace.h +++ b/lldb/include/lldb/API/SBTrace.h @@ -12,8 +12,6 @@ #include "lldb/API/SBDefines.h" #include "lldb/API/SBError.h" -class TraceImpl; - namespace lldb { class LLDB_API SBTrace { @@ -23,6 +21,10 @@ class LLDB_API SBTrace { SBTrace(const lldb::TraceSP &trace_sp); + /// See SBDebugger::LoadTraceFromFile. + static SBTrace LoadTraceFromFile(SBError &error, SBDebugger &debugger, + const SBFileSpec &trace_description_file); + /// \return /// A description of the parameters to use for the \a SBTrace::Start /// method, or \b null if the object is invalid. diff --git a/lldb/include/lldb/Target/Trace.h b/lldb/include/lldb/Target/Trace.h index 2fee3c9274959..216394bdd1847 100644 --- a/lldb/include/lldb/Target/Trace.h +++ b/lldb/include/lldb/Target/Trace.h @@ -137,6 +137,23 @@ class Trace : public PluginInterface, static llvm::Expected FindPluginSchema(llvm::StringRef plugin_name); + /// Load a trace from a trace description file and create Targets, + /// Processes and Threads based on the contents of such file. + /// + /// \param[in] debugger + /// The debugger instance where new Targets will be created as part of the + /// JSON data parsing. + /// + /// \param[in] trace_description_file + /// The file containing the necessary information to load the trace. + /// + /// \return + /// A \a TraceSP instance, or an \a llvm::Error if loading the trace + /// fails. + static llvm::Expected + LoadPostMortemTraceFromFile(Debu
[Lldb-commits] [lldb] f6eb089 - [trace][intelpt] Fix multi CPU decoding TSC assertion error
Author: Jakob Johnson Date: 2022-10-26T11:37:30-07:00 New Revision: f6eb089734ddbd7f9b9935a122ff4ad658f06360 URL: https://github.com/llvm/llvm-project/commit/f6eb089734ddbd7f9b9935a122ff4ad658f06360 DIFF: https://github.com/llvm/llvm-project/commit/f6eb089734ddbd7f9b9935a122ff4ad658f06360.diff LOG: [trace][intelpt] Fix multi CPU decoding TSC assertion error Occasionally the assertion that enforces increasing TSC values in `DecodedThread::NotifyTsc` would get tripped during large multi CPU trace decoding. The root cause of this issue was an assumption that all the data of a PSB will fit within the start,end TSC of the "owning" `ThreadContinuousExecution`. After investigating, this is not the case because PSBs can have multiple TSCs. This diff works around this issue by introducing a TSC upper bound for each `PSBBlockDecoder`. This fixes the assertion failure by simply "dropping" the remaining data of PSB whenever the TSC upper bound is exceeded during decoding. Future work will do a larger refactor of the multi CPU decoding to remove the dependencies on this incorrect assumption so that PSB blocks that span multiple `ThreadContinuousExecutions` are correctly handled. correctly Test Plan: Differential Revision: https://reviews.llvm.org/D136610 Added: Modified: lldb/source/Plugins/Trace/intel-pt/LibiptDecoder.cpp Removed: diff --git a/lldb/source/Plugins/Trace/intel-pt/LibiptDecoder.cpp b/lldb/source/Plugins/Trace/intel-pt/LibiptDecoder.cpp index 10f0bbe42b274..b85c4f3bacf3d 100644 --- a/lldb/source/Plugins/Trace/intel-pt/LibiptDecoder.cpp +++ b/lldb/source/Plugins/Trace/intel-pt/LibiptDecoder.cpp @@ -329,12 +329,18 @@ class PSBBlockDecoder { /// \param[in] decoded_thread /// A \a DecodedThread object where the decoded instructions will be /// appended to. It might have already some instructions. + /// + /// \param[in] tsc_upper_bound + /// Maximum allowed value of TSCs decoded from this PSB block. + /// Any of this PSB's data occurring after this TSC will be excluded. PSBBlockDecoder(PtInsnDecoderUP &&decoder_up, const PSBBlock &psb_block, Optional next_block_ip, - DecodedThread &decoded_thread, TraceIntelPT &trace_intel_pt) + DecodedThread &decoded_thread, TraceIntelPT &trace_intel_pt, + llvm::Optional tsc_upper_bound) : m_decoder_up(std::move(decoder_up)), m_psb_block(psb_block), m_next_block_ip(next_block_ip), m_decoded_thread(decoded_thread), -m_anomaly_detector(*m_decoder_up, trace_intel_pt, decoded_thread) {} +m_anomaly_detector(*m_decoder_up, trace_intel_pt, decoded_thread), +m_tsc_upper_bound(tsc_upper_bound) {} /// \param[in] trace_intel_pt /// The main Trace object that own the PSB block. @@ -362,14 +368,15 @@ class PSBBlockDecoder { static Expected Create(TraceIntelPT &trace_intel_pt, const PSBBlock &psb_block, ArrayRef buffer, Process &process, - Optional next_block_ip, DecodedThread &decoded_thread) { + Optional next_block_ip, DecodedThread &decoded_thread, + llvm::Optional tsc_upper_bound) { Expected decoder_up = CreateInstructionDecoder(trace_intel_pt, buffer, process); if (!decoder_up) return decoder_up.takeError(); return PSBBlockDecoder(std::move(*decoder_up), psb_block, next_block_ip, - decoded_thread, trace_intel_pt); + decoded_thread, trace_intel_pt, tsc_upper_bound); } void DecodePSBBlock() { @@ -451,6 +458,41 @@ class PSBBlockDecoder { } } + /// Process the TSC of a decoded PT event. Specifically, check if this TSC + /// is below the TSC upper bound for this PSB. If the TSC exceeds the upper + /// bound, return an error to abort decoding. Otherwise add the it to the + /// underlying DecodedThread and decoding should continue as expected. + /// + /// \param[in] tsc + /// The TSC of the a decoded event. + Error ProcessPTEventTSC(DecodedThread::TSC tsc) { +if (m_tsc_upper_bound && tsc >= *m_tsc_upper_bound) { + // This event and all the remaining events of this PSB have a TSC + // outside the range of the "owning" ThreadContinuousExecution. For + // now we drop all of these events/instructions, future work can + // improve upon this by determining the "owning" + // ThreadContinuousExecution of the remaining PSB data. + std::string err_msg = formatv("decoding truncated: TSC {0} exceeds " +"maximum TSC value {1}, will skip decoding" +" the remaining data of the PSB", +tsc, *m_tsc_upper_bound) +.str(); + + uint64_t offset; + int status = pt_insn_get_offset(m_decoder_up.get(), &offset); + if (!IsLi
[Lldb-commits] [lldb] 17c65e5 - [intelpt] Update Python tests to account for new errrors
Author: Jakob Johnson Date: 2022-10-27T05:09:08-07:00 New Revision: 17c65e51b91620181662302e9abd7e9694154c5d URL: https://github.com/llvm/llvm-project/commit/17c65e51b91620181662302e9abd7e9694154c5d DIFF: https://github.com/llvm/llvm-project/commit/17c65e51b91620181662302e9abd7e9694154c5d.diff LOG: [intelpt] Update Python tests to account for new errrors Update the Python tests (ie tests run via `lldb-dotest -p TestTrace`) to handle new error introduced in D136610. Test Plan: `lldb-dotest -p TestTrace` Differential Revision: https://reviews.llvm.org/D136801 Added: Modified: lldb/test/API/commands/trace/TestTraceDumpFunctionCalls.py lldb/test/API/commands/trace/TestTraceLoad.py Removed: diff --git a/lldb/test/API/commands/trace/TestTraceDumpFunctionCalls.py b/lldb/test/API/commands/trace/TestTraceDumpFunctionCalls.py index 0a8b4f4d2a3dd..a022dd3b31522 100644 --- a/lldb/test/API/commands/trace/TestTraceDumpFunctionCalls.py +++ b/lldb/test/API/commands/trace/TestTraceDumpFunctionCalls.py @@ -44,7 +44,7 @@ def testFunctionCallsWithErrors(self): m.out`foo() + 65 at multi_thread.cpp:12:21 to 12:21 [4, 19524] [call tree #1] - [19532, 19532]''']) + [19526, 19526]''']) self.expect("thread trace dump function-calls 2 -J", substrs=['''[ @@ -59,8 +59,8 @@ def testFunctionCallsWithErrors(self): { "tracedSegments": [ { -"firstInstructionId": "19532", -"lastInstructionId": "19532" +"firstInstructionId": "19526", +"lastInstructionId": "19526" } ] } @@ -73,7 +73,7 @@ def testFunctionCallsWithErrors(self): m.out`bar() + 30 at multi_thread.cpp:19:3 to 20:6 [5, 61831] [call tree #1] - [61834, 61834]''']) + [61833, 61833]''']) self.expect("thread trace dump function-calls 3 -J", substrs=['''[ @@ -88,8 +88,8 @@ def testFunctionCallsWithErrors(self): { "tracedSegments": [ { -"firstInstructionId": "61834", -"lastInstructionId": "61834" +"firstInstructionId": "61833", +"lastInstructionId": "61833" } ] } diff --git a/lldb/test/API/commands/trace/TestTraceLoad.py b/lldb/test/API/commands/trace/TestTraceLoad.py index 298be086b2046..09d7e0b7aabe5 100644 --- a/lldb/test/API/commands/trace/TestTraceLoad.py +++ b/lldb/test/API/commands/trace/TestTraceLoad.py @@ -13,11 +13,11 @@ def testLoadMultiCoreTrace(self): trace_description_file_path = os.path.join(src_dir, "intelpt-multi-core-trace", "trace.json") self.traceLoad(traceDescriptionFilePath=trace_description_file_path, substrs=["intel-pt"]) self.expect("thread trace dump instructions 2 -t", - substrs=["19532: [20456513.000 ns] (error) expected tracing enabled event", + substrs=["19526: [19691636.212 ns] (error) decoding truncated: TSC 40450075478109270 exceeds maximum TSC value 40450075477704372, will skip decoding the remaining data of the PSB (skipping 774 of 825 bytes)", "m.out`foo() + 65 at multi_thread.cpp:12:21", - "9524: [19691630.226 ns] 0x00400ba7jg 0x400bb3"]) + "9524: [19691632.221 ns] 0x00400ba7jg 0x400bb3"]) self.expect("thread trace dump instructions 3 -t", - substrs=["61831: [19736134.073 ns] 0x00400bd7addl $0x1, -0x4(%rbp)", + substrs=["61831: [19736132.088 ns] 0x00400bd7addl $0x1, -0x4(%rbp)", "m.out`bar() + 26 at multi_thread.cpp:20:6"]) self.expect("thread trace dump info --json", @@ -62,20 +62,20 @@ def testLoadMultiCoreTrace(self): "traceTechnology": "intel-pt", "threadStats": { "tid": 3497496, -"traceItemsCount": 19533, +"traceItemsCount": 19527, "memoryUsage": { - "totalInBytes": "176065", - "avgPerItemInBytes": 9.''', '''}, + "totalInBytes": "175819", + "avgPerItemInBytes": 9.0038920469094084''', '''}, "timingInSeconds": { "Decoding instructions": ''', ''' }, "events": { - "totalCount": 11, + "totalCount": 5, "individualCounts": { "software disabled tracing": 1, "trace synchronization point": 1, "CPU core changed": 1, -"HW clock tick": 8 +"HW clock tick": 2 } }, "errors": { @@ -116,11 +116,12 @@ def testLoadCompactMultiCoreTrace(self): # we'll load the compact trace and make sure it works self.traceLoad(os.path.join(compact_trace_bundle_dir, "trace.json"), substrs=["intel-pt"]) self.expect("thread trace dump instructions 2 -t", - substrs=["19532: [20456513.000 ns] (error) expected tracing enabled event", + substrs=["19526: [19691636.212 ns] (error) decoding truncated: TSC 40450075478109270 exceeds maximum TSC value 40450075477704372, will skip decoding the remai
[Lldb-commits] [lldb] df766fb - [NFC][intelpt] Improve IntelPT trace bundle documentation
Author: Jakob Johnson Date: 2022-11-08T05:16:28-08:00 New Revision: df766fb65cc939bd88c25cb8e478b07f7b4ce123 URL: https://github.com/llvm/llvm-project/commit/df766fb65cc939bd88c25cb8e478b07f7b4ce123 DIFF: https://github.com/llvm/llvm-project/commit/df766fb65cc939bd88c25cb8e478b07f7b4ce123.diff LOG: [NFC][intelpt] Improve IntelPT trace bundle documentation Mention that the LLVM/clang triple must be provided if the trace will be consumed via `SBTraceCursor` Test Plan: Differential Revision: https://reviews.llvm.org/D137509 Added: Modified: lldb/source/Plugins/Trace/intel-pt/TraceIntelPTBundleLoader.cpp Removed: diff --git a/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTBundleLoader.cpp b/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTBundleLoader.cpp index cac91e801c926..0e664fd91d80f 100644 --- a/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTBundleLoader.cpp +++ b/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTBundleLoader.cpp @@ -241,6 +241,8 @@ StringRef TraceIntelPTBundleLoader::GetSchema() { "pid": integer, "triple"?: string, // Optional clang/llvm target triple. + // This must be provided if the trace will be created not using the + // CLI or on a machine other than where the target was traced. "threads": [ // A list of known threads for the given process. When context switch // data is provided, LLDB will automatically create threads for the ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits