diff --git a/lldb/test/API/tools/intel-features/intel-pt/test/TestIntelPTSimpleBinary.py b/lldb/test/API/tools/intel-features/intel-pt/test/TestIntelPTSimpleBinary.py --- a/lldb/test/API/tools/intel-features/intel-pt/test/TestIntelPTSimpleBinary.py +++ b/lldb/test/API/tools/intel-features/intel-pt/test/TestIntelPTSimpleBinary.py @@ -95,19 +95,19 @@ # We will start tracing from main lldbutil.run_to_name_breakpoint(self, "main", exe_name=exe) - decoder = lldbIntelFeatures.PTDecoder(self.dbg) - target = self.dbg.GetSelectedTarget() process = target.GetProcess() tid = process.GetProcessID() + ptprocess = lldbIntelFeatures.SBPTProcess(process) + # We configure the tracing options - trace_opts = lldbIntelFeatures.PTDecoder.GetDefaultTraceOptions() + trace_opts = lldbIntelFeatures.SBPTProcess.GetDefaultTraceOptions() trace_opts.setThreadID(tid) # We start tracing error = lldb.SBError() - decoder.StartProcessorTrace(process, trace_opts, error) + ptprocess.StartProcessorTrace(trace_opts, error) self.assertSuccess(error) # We check the trace after the for loop @@ -117,8 +117,8 @@ # We'll check repeteadly until the trace is available def getInstructions(): instruction_list = lldbIntelFeatures.PTInstructionList() - decoder.GetInstructionLogAtOffset( - process, tid, offset=99, count=100, result_list=instruction_list, sberror=error) + ptprocess.GetInstructionLogAtOffset( + tid, offset=99, count=100, result_list=instruction_list, sberror=error) if error.Fail() or instruction_list.GetSize() == 0: return None return instruction_list @@ -133,5 +133,5 @@ self.assertIn(self.find_start_address_of_function(target, "fun"), addresses) # We assert stopping the trace works - decoder.StopProcessorTrace(process, error, tid) + ptprocess.StopProcessorTrace(error, tid) self.assertSuccess(error) diff --git a/lldb/tools/intel-features/intel-pt/include/intel-pt/API/PTDecoder.h b/lldb/tools/intel-features/intel-pt/include/intel-pt/API/SBPTProcess.h rename from lldb/tools/intel-features/intel-pt/include/intel-pt/API/PTDecoder.h rename to lldb/tools/intel-features/intel-pt/include/intel-pt/API/SBPTProcess.h --- a/lldb/tools/intel-features/intel-pt/include/intel-pt/API/PTDecoder.h +++ b/lldb/tools/intel-features/intel-pt/include/intel-pt/API/SBPTProcess.h @@ -1,4 +1,4 @@ -//===-- PTDecoder.h ---------------------------------------------*- C++ -*-===// +//===-- SBPTProcess.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. @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_INTEL_PT_API_PT_DECODER_H -#define LLDB_INTEL_PT_API_PT_DECODER_H +#ifndef LLDB_INTEL_PT_API_SB_PT_PROCESS_H +#define LLDB_INTEL_PT_API_SB_PT_PROCESS_H // C/C++ Includes #include @@ -24,7 +24,7 @@ class Instruction; class InstructionList; class TraceOptions; -class Decoder; +class PTProcess; } // namespace intelpt_private namespace intelpt { @@ -89,7 +89,7 @@ void Clear(); private: - friend class PTDecoder; + friend class SBPTProcess; void SetSP(const std::shared_ptr &ptr); @@ -119,14 +119,14 @@ lldb::SBStructuredData GetTraceParams(lldb::SBError &error); private: - friend class PTDecoder; + friend class SBPTProcess; void SetSP(const std::shared_ptr &ptr); std::shared_ptr m_opaque_sp; }; -/// \class PTDecoder +/// \class PTProcess /// This class makes use of Intel(R) Processor Trace hardware feature /// (implememted inside LLDB) to gather trace data for an inferior (being /// debugged with LLDB) to provide meaningful information out of it. @@ -138,17 +138,15 @@ /// - stop the trace for a thread/process, /// - get the execution flow (assembly instructions) for a thread and /// - get trace specific information for a thread -class PTDecoder { +class SBPTProcess { public: - PTDecoder(lldb::SBDebugger &sbdebugger); + SBPTProcess(lldb::SBProcess &process); + + SBPTProcess(); /// Start Intel(R) Processor Trace on a thread or complete process with /// Intel(R) Processor Trace specific configuration options /// - /// \param[in] sbprocess - /// A valid process on which this operation will be performed. An error is - /// returned in case of an invalid process. - /// /// \param[in] sbtraceoptions /// Contains thread id information and configuration options: /// @@ -180,16 +178,11 @@ /// /// \param[out] sberror /// An error with the failure reason if API fails. Else success. - void StartProcessorTrace(lldb::SBProcess &sbprocess, - lldb::SBTraceOptions &sbtraceoptions, + void StartProcessorTrace(lldb::SBTraceOptions &sbtraceoptions, lldb::SBError &sberror); /// Stop Intel(R) Processor Trace on a thread or complete process. /// - /// \param[in] sbprocess - /// A valid process on which this operation will be performed. An error is - /// returned in case of an invalid process. - /// /// \param[in] tid /// Case 1: To stop tracing a single thread, provide a valid thread id. If /// sbprocess doesn't contain the thread tid, error will be returned. @@ -198,16 +191,12 @@ /// /// \param[out] sberror /// An error with the failure reason if API fails. Else success. - void StopProcessorTrace(lldb::SBProcess &sbprocess, lldb::SBError &sberror, + void StopProcessorTrace(lldb::SBError &sberror, lldb::tid_t tid = LLDB_INVALID_THREAD_ID); /// Get instruction log containing the execution flow for a thread of a /// process in terms of assembly instructions executed. /// - /// \param[in] sbprocess - /// A valid process on which this operation will be performed. An error is - /// returned in case of an invalid process. - /// /// \param[in] tid /// A valid thread id of the thread for which instruction log is desired. /// If sbprocess doesn't contain the thread tid, error will be returned. @@ -234,19 +223,14 @@ /// /// \param[out] sberror /// An error with the failure reason if API fails. Else success. - void GetInstructionLogAtOffset(lldb::SBProcess &sbprocess, lldb::tid_t tid, - uint32_t offset, uint32_t count, - PTInstructionList &result_list, + void GetInstructionLogAtOffset(lldb::tid_t tid, uint32_t offset, + uint32_t count, PTInstructionList &result_list, lldb::SBError &sberror); /// Get Intel(R) Processor Trace specific information for a thread of a /// process. The information contains the actual configuration options with /// which the trace was started for this thread. /// - /// \param[in] sbprocess - /// A valid process on which this operation will be performed. An error is - /// returned in case of an invalid process. - /// /// \param[in] tid /// A valid thread id of the thread for which the trace specific /// information is required. If sbprocess doesn't contain the thread tid, @@ -259,12 +243,12 @@ /// /// \param[out] sberror /// An error with the failure reason if API fails. Else success. - void GetProcessorTraceInfo(lldb::SBProcess &sbprocess, lldb::tid_t tid, - PTTraceOptions &options, lldb::SBError &sberror); + void GetProcessorTraceInfo(lldb::tid_t tid, PTTraceOptions &options, + lldb::SBError &sberror); /// Get an instance of an \a lldb::SBTraceOptions object with a default /// configuration for tracing with Intel(R) Processor Trace. This object - /// is ready to be passed as argument to \a PTDecoder::StartProcessorTrace. + /// is ready to be passed as argument to \a SBPTProcess::StartProcessorTrace. /// /// The default configuration sets 4096 bytes as trace buffer size per thread. /// Besides, this configuration traces all the running threads of the target @@ -276,8 +260,8 @@ static lldb::SBTraceOptions GetDefaultTraceOptions(); private: - std::shared_ptr m_opaque_sp; + std::shared_ptr m_opaque_sp; }; } // namespace intelpt -#endif // LLDB_INTEL_PT_API_PT_DECODER_H +#endif // LLDB_INTEL_PT_API_SB_PT_PROCESS_H diff --git a/lldb/tools/intel-features/intel-pt/include/intel-pt/API/cli-wrapper-pt.h b/lldb/tools/intel-features/intel-pt/include/intel-pt/API/cli-wrapper-pt.h --- a/lldb/tools/intel-features/intel-pt/include/intel-pt/API/cli-wrapper-pt.h +++ b/lldb/tools/intel-features/intel-pt/include/intel-pt/API/cli-wrapper-pt.h @@ -4,7 +4,7 @@ // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // -// CLI Wrapper of PTDecoder Tool to enable it to be used through LLDB's CLI. +// CLI Wrapper of PTProcess Tool to enable it to be used through LLDB's CLI. //===----------------------------------------------------------------------===// #include "lldb/API/SBDebugger.h" diff --git a/lldb/tools/intel-features/intel-pt/include/intel-pt/Core/Decoder.h b/lldb/tools/intel-features/intel-pt/include/intel-pt/Core/PTProcess.h rename from lldb/tools/intel-features/intel-pt/include/intel-pt/Core/Decoder.h rename to lldb/tools/intel-features/intel-pt/include/intel-pt/Core/PTProcess.h --- a/lldb/tools/intel-features/intel-pt/include/intel-pt/Core/Decoder.h +++ b/lldb/tools/intel-features/intel-pt/include/intel-pt/Core/PTProcess.h @@ -1,4 +1,4 @@ -//===-- Decoder.h -----------------------------------------------*- C++ -*-===// +//===-- PTProcess.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. @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_INTEL_PT_CORE_DECODER_H -#define LLDB_INTEL_PT_CORE_DECODER_H +#ifndef LLDB_INTEL_PT_CORE_PT_PROCESS_H +#define LLDB_INTEL_PT_CORE_PT_PROCESS_H // C/C++ Includes #include @@ -133,9 +133,9 @@ uint32_t m_insn_log_size; }; -/// \class Decoder +/// \class PTProcess /// This class makes use of Intel(R) Processor Trace hardware feature -/// (implememted inside LLDB) to gather trace data for an inferior (being +/// (implemented inside LLDB) to gather trace data for an process (being /// debugged with LLDB) to provide meaningful information out of it. /// /// Currently the meaningful information comprises of the execution flow @@ -145,31 +145,28 @@ /// - stop the trace for a thread/process, /// - get the execution flow (assembly instructions) for a thread and /// - get trace specific information for a thread -class Decoder { +class PTProcess { public: typedef std::vector Instructions; - Decoder(lldb::SBDebugger &sbdebugger) - : m_mapProcessUID_mapThreadID_TraceInfo_mutex(), - m_mapProcessUID_mapThreadID_TraceInfo(), - m_debugger_user_id(sbdebugger.GetID()) {} + PTProcess(lldb::SBProcess &process) + : m_mapThreadID_TraceInfo_mutex(), m_mapThreadID_TraceInfo(), + m_process(process) {} - ~Decoder() {} + ~PTProcess() {} - void StartProcessorTrace(lldb::SBProcess &sbprocess, - lldb::SBTraceOptions &sbtraceoptions, + void StartProcessorTrace(lldb::SBTraceOptions &sbtraceoptions, lldb::SBError &sberror); - void StopProcessorTrace(lldb::SBProcess &sbprocess, lldb::SBError &sberror, + void StopProcessorTrace(lldb::SBError &sberror, lldb::tid_t tid = LLDB_INVALID_THREAD_ID); - void GetInstructionLogAtOffset(lldb::SBProcess &sbprocess, lldb::tid_t tid, - uint32_t offset, uint32_t count, - InstructionList &result_list, + void GetInstructionLogAtOffset(lldb::tid_t tid, uint32_t offset, + uint32_t count, InstructionList &result_list, lldb::SBError &sberror); - void GetProcessorTraceInfo(lldb::SBProcess &sbprocess, lldb::tid_t tid, - TraceOptions &traceinfo, lldb::SBError &sberror); + void GetProcessorTraceInfo(lldb::tid_t tid, TraceOptions &traceinfo, + lldb::SBError &sberror); static lldb::SBTraceOptions GetDefaultTraceOptions(); @@ -195,12 +192,8 @@ typedef struct pt_cpu CPUInfo; typedef std::vector ReadExecuteSectionInfos; - // Check whether the provided SBProcess belongs to the same SBDebugger with - // which Decoder class instance was constructed. - void CheckDebuggerID(lldb::SBProcess &sbprocess, lldb::SBError &sberror); - - // Function to remove entries of finished processes/threads in the class - void RemoveDeadProcessesAndThreads(lldb::SBProcess &sbprocess); + // Function to remove entries of finished threads in the class + void RemoveDeadThreads(); // Parse cpu information from trace configuration received from LLDB void ParseCPUInfo(CPUInfo &pt_cpu, lldb::SBStructuredData &s, @@ -213,27 +206,23 @@ /// - fetches trace and other necessary information from LLDB (using /// ReadTraceDataAndImageInfo()) and decodes the trace (using /// DecodeProcessorTrace()) - void FetchAndDecode(lldb::SBProcess &sbprocess, lldb::tid_t tid, - lldb::SBError &sberror, + void FetchAndDecode(lldb::tid_t tid, lldb::SBError &sberror, ThreadTraceInfo **threadTraceInfo); // Helper function of FetchAndDecode() to get raw trace data and memory image // info of inferior from LLDB - void ReadTraceDataAndImageInfo(lldb::SBProcess &sbprocess, lldb::tid_t tid, - lldb::SBError &sberror, + void ReadTraceDataAndImageInfo(lldb::tid_t tid, lldb::SBError &sberror, ThreadTraceInfo &threadTraceInfo); // Helper function of FetchAndDecode() to initialize raw trace decoder and // start trace decoding - void DecodeProcessorTrace(lldb::SBProcess &sbprocess, lldb::tid_t tid, - lldb::SBError &sberror, + void DecodeProcessorTrace(lldb::tid_t tid, lldb::SBError &sberror, ThreadTraceInfo &threadTraceInfo); // Helper function of ReadTraceDataAndImageInfo() function for gathering // inferior's memory image info along with all dynamic libraries linked with // it - void GetTargetModulesInfo(lldb::SBTarget &sbtarget, - ReadExecuteSectionInfos &readExecuteSectionInfos, + void GetTargetModulesInfo(ReadExecuteSectionInfos &readExecuteSectionInfos, lldb::SBError &sberror); /// Helper functions of DecodeProcessorTrace() function for: @@ -298,8 +287,6 @@ void SetUniqueTraceInstance(lldb::SBTrace &trace) { m_trace = trace; } - friend class Decoder; - private: Buffer m_pt_buffer; // raw trace buffer ReadExecuteSectionInfos @@ -310,18 +297,15 @@ Instructions m_instruction_log; // complete instruction log }; - typedef std::map MapThreadID_TraceInfo; - typedef std::map - MapProcessUID_MapThreadID_TraceInfo; - - std::mutex m_mapProcessUID_mapThreadID_TraceInfo_mutex; - MapProcessUID_MapThreadID_TraceInfo - m_mapProcessUID_mapThreadID_TraceInfo; // to store trace information for - // each process and its associated - // threads - lldb::user_id_t m_debugger_user_id; // SBDebugger instance which is associated - // to this Decoder instance + // typedef std::map MapThreadID_TraceInfo; + // typedef std::map + // MapProcessUID_MapThreadID_TraceInfo; + + std::mutex m_mapThreadID_TraceInfo_mutex; + std::map m_mapThreadID_TraceInfo; + + lldb::SBProcess m_process; }; } // namespace intelpt_private -#endif // LLDB_INTEL_PT_CORE_DECODER_H +#endif // LLDB_INTEL_PT_CORE_PT_PROCESS_H diff --git a/lldb/tools/intel-features/intel-pt/interface/PTDecoder.i b/lldb/tools/intel-features/intel-pt/interface/SBPTProcess.i rename from lldb/tools/intel-features/intel-pt/interface/PTDecoder.i rename to lldb/tools/intel-features/intel-pt/interface/SBPTProcess.i --- a/lldb/tools/intel-features/intel-pt/interface/PTDecoder.i +++ b/lldb/tools/intel-features/intel-pt/interface/SBPTProcess.i @@ -7,4 +7,4 @@ %include "lldb/API/SBDefines.h" -%include "intel-pt/API/PTDecoder.h" +%include "intel-pt/API/SBPTProcess.h" diff --git a/lldb/tools/intel-features/intel-pt/source/API/CMakeLists.txt b/lldb/tools/intel-features/intel-pt/source/API/CMakeLists.txt --- a/lldb/tools/intel-features/intel-pt/source/API/CMakeLists.txt +++ b/lldb/tools/intel-features/intel-pt/source/API/CMakeLists.txt @@ -1,5 +1,5 @@ add_lldb_library(lldbIntelPT - PTDecoder.cpp + SBPTProcess.cpp cli-wrapper-pt.cpp LINK_LIBS diff --git a/lldb/tools/intel-features/intel-pt/source/API/PTDecoder.cpp b/lldb/tools/intel-features/intel-pt/source/API/SBPTProcess.cpp rename from lldb/tools/intel-features/intel-pt/source/API/PTDecoder.cpp rename to lldb/tools/intel-features/intel-pt/source/API/SBPTProcess.cpp --- a/lldb/tools/intel-features/intel-pt/source/API/PTDecoder.cpp +++ b/lldb/tools/intel-features/intel-pt/source/API/SBPTProcess.cpp @@ -1,4 +1,4 @@ -//===-- PTDecoder.cpp -------------------------------------------*- C++ -*-===// +//===-- SBPTProcess.cpp -----------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#include "intel-pt/API/PTDecoder.h" -#include "intel-pt/Core/Decoder.h" +#include "intel-pt/API/SBPTProcess.h" +#include "intel-pt/Core/PTProcess.h" using namespace intelpt; using namespace intelpt_private; @@ -85,69 +85,67 @@ m_opaque_sp = ptr; } -// PTDecoder class member functions definitions -PTDecoder::PTDecoder(lldb::SBDebugger &sbdebugger) - : m_opaque_sp(new intelpt_private::Decoder(sbdebugger)) {} +// SBPTProcess class member functions definitions +SBPTProcess::SBPTProcess(lldb::SBProcess &process) + : m_opaque_sp(new intelpt_private::PTProcess(process)) {} -void PTDecoder::StartProcessorTrace(lldb::SBProcess &sbprocess, - lldb::SBTraceOptions &sbtraceoptions, - lldb::SBError &sberror) { +SBPTProcess::SBPTProcess() : m_opaque_sp(nullptr) {} + +void SBPTProcess::StartProcessorTrace(lldb::SBTraceOptions &sbtraceoptions, + lldb::SBError &sberror) { if (m_opaque_sp == nullptr) { - sberror.SetErrorStringWithFormat("invalid PTDecoder instance"); + sberror.SetErrorStringWithFormat("invalid SBPTProcess instance"); return; } - m_opaque_sp->StartProcessorTrace(sbprocess, sbtraceoptions, sberror); + m_opaque_sp->StartProcessorTrace(sbtraceoptions, sberror); } -void PTDecoder::StopProcessorTrace(lldb::SBProcess &sbprocess, - lldb::SBError &sberror, lldb::tid_t tid) { +void SBPTProcess::StopProcessorTrace(lldb::SBError &sberror, lldb::tid_t tid) { if (m_opaque_sp == nullptr) { - sberror.SetErrorStringWithFormat("invalid PTDecoder instance"); + sberror.SetErrorStringWithFormat("invalid SBPTProcess instance"); return; } - m_opaque_sp->StopProcessorTrace(sbprocess, sberror, tid); + m_opaque_sp->StopProcessorTrace(sberror, tid); } -void PTDecoder::GetInstructionLogAtOffset(lldb::SBProcess &sbprocess, - lldb::tid_t tid, uint32_t offset, - uint32_t count, - PTInstructionList &result_list, - lldb::SBError &sberror) { +void SBPTProcess::GetInstructionLogAtOffset(lldb::tid_t tid, uint32_t offset, + uint32_t count, + PTInstructionList &result_list, + lldb::SBError &sberror) { if (m_opaque_sp == nullptr) { - sberror.SetErrorStringWithFormat("invalid PTDecoder instance"); + sberror.SetErrorStringWithFormat("invalid SBPTProcess instance"); return; } std::shared_ptr insn_list_ptr( new InstructionList()); - m_opaque_sp->GetInstructionLogAtOffset(sbprocess, tid, offset, count, - *insn_list_ptr, sberror); + m_opaque_sp->GetInstructionLogAtOffset(tid, offset, count, *insn_list_ptr, + sberror); if (!sberror.Success()) return; result_list.SetSP(insn_list_ptr); } -void PTDecoder::GetProcessorTraceInfo(lldb::SBProcess &sbprocess, - lldb::tid_t tid, PTTraceOptions &options, - lldb::SBError &sberror) { +void SBPTProcess::GetProcessorTraceInfo(lldb::tid_t tid, + PTTraceOptions &options, + lldb::SBError &sberror) { if (m_opaque_sp == nullptr) { - sberror.SetErrorStringWithFormat("invalid PTDecoder instance"); + sberror.SetErrorStringWithFormat("invalid SBPTProcess instance"); return; } std::shared_ptr trace_options_ptr( new TraceOptions()); - m_opaque_sp->GetProcessorTraceInfo(sbprocess, tid, *trace_options_ptr, - sberror); + m_opaque_sp->GetProcessorTraceInfo(tid, *trace_options_ptr, sberror); if (!sberror.Success()) return; options.SetSP(trace_options_ptr); } -lldb::SBTraceOptions PTDecoder::GetDefaultTraceOptions() { - return Decoder::GetDefaultTraceOptions(); +lldb::SBTraceOptions SBPTProcess::GetDefaultTraceOptions() { + return PTProcess::GetDefaultTraceOptions(); } diff --git a/lldb/tools/intel-features/intel-pt/source/API/cli-wrapper-pt.cpp b/lldb/tools/intel-features/intel-pt/source/API/cli-wrapper-pt.cpp --- a/lldb/tools/intel-features/intel-pt/source/API/cli-wrapper-pt.cpp +++ b/lldb/tools/intel-features/intel-pt/source/API/cli-wrapper-pt.cpp @@ -4,7 +4,7 @@ // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // -// CLI Wrapper of PTDecoder Tool to enable it to be used through LLDB's CLI. The +// CLI Wrapper of PTProcess Tool to enable it to be used through LLDB's CLI. The // wrapper provides a new command called processor-trace with 4 child // subcommands as follows: // processor-trace start @@ -17,10 +17,11 @@ #include #include #include +#include #include #include -#include "intel-pt/API/PTDecoder.h" +#include "intel-pt/API/SBPTProcess.h" #include "intel-pt/API/cli-wrapper-pt.h" #include "lldb/API/SBCommandInterpreter.h" #include "lldb/API/SBCommandReturnObject.h" @@ -31,9 +32,11 @@ #include "lldb/API/SBTarget.h" #include "lldb/API/SBThread.h" -static bool GetProcess(lldb::SBDebugger &debugger, - lldb::SBCommandReturnObject &result, - lldb::SBProcess &process) { +static bool GetPTProcess(lldb::SBDebugger &debugger, + lldb::SBCommandReturnObject &result, + lldb::SBProcess &process, + intelpt::SBPTProcess &ptprocess) { + static std::map puid_ptprocess_map; if (!debugger.IsValid()) { result.Printf("error: invalid debugger\n"); result.SetStatus(lldb::eReturnStatusFailed); @@ -56,6 +59,14 @@ result.SetStatus(lldb::eReturnStatusFailed); return false; } + uint32_t uid = process.GetUniqueID(); + auto it = puid_ptprocess_map.find(uid); + if (it != puid_ptprocess_map.end()) + ptprocess = it->second; + else { + ptprocess = intelpt::SBPTProcess(process); + puid_ptprocess_map[uid] = ptprocess; + } return true; } @@ -123,8 +134,7 @@ class ProcessorTraceStart : public lldb::SBCommandPluginInterface { public: - ProcessorTraceStart(std::shared_ptr &pt_decoder) - : SBCommandPluginInterface(), pt_decoder_sp(pt_decoder) {} + ProcessorTraceStart() : SBCommandPluginInterface() {} ~ProcessorTraceStart() {} @@ -132,12 +142,13 @@ lldb::SBCommandReturnObject &result) { lldb::SBProcess process; lldb::SBThread thread; - if (!GetProcess(debugger, result, process)) + intelpt::SBPTProcess ptprocess; + if (!GetPTProcess(debugger, result, process, ptprocess)) return false; // Default initialize API's arguments lldb::SBTraceOptions lldb_SBTraceOptions = - intelpt::PTDecoder::GetDefaultTraceOptions(); + intelpt::SBPTProcess::GetDefaultTraceOptions(); uint32_t trace_buffer_size = lldb_SBTraceOptions.getTraceBufferSize(); lldb::tid_t thread_id; @@ -175,7 +186,7 @@ // Start trace lldb::SBError error; - pt_decoder_sp->StartProcessorTrace(process, lldb_SBTraceOptions, error); + ptprocess.StartProcessorTrace(lldb_SBTraceOptions, error); if (!error.Success()) { result.Printf("error: %s\n", error.GetCString()); result.SetStatus(lldb::eReturnStatusFailed); @@ -186,14 +197,12 @@ } private: - std::shared_ptr pt_decoder_sp; const uint32_t m_max_trace_buff_size = 0x3fff; }; class ProcessorTraceInfo : public lldb::SBCommandPluginInterface { public: - ProcessorTraceInfo(std::shared_ptr &pt_decoder) - : SBCommandPluginInterface(), pt_decoder_sp(pt_decoder) {} + ProcessorTraceInfo() : SBCommandPluginInterface() {} ~ProcessorTraceInfo() {} @@ -201,7 +210,8 @@ lldb::SBCommandReturnObject &result) { lldb::SBProcess process; lldb::SBThread thread; - if (!GetProcess(debugger, result, process)) + intelpt::SBPTProcess ptprocess; + if (!GetPTProcess(debugger, result, process, ptprocess)) return false; lldb::tid_t thread_id; @@ -247,7 +257,7 @@ thread_id = thread.GetThreadID(); intelpt::PTTraceOptions options; - pt_decoder_sp->GetProcessorTraceInfo(process, thread_id, options, error); + ptprocess.GetProcessorTraceInfo(thread_id, options, error); if (!error.Success()) { res.Printf("thread #%" PRIu32 ": tid=%" PRIu64 ", error: %s", thread.GetIndexID(), thread_id, error.GetCString()); @@ -283,15 +293,11 @@ result.SetStatus(lldb::eReturnStatusSuccessFinishResult); return true; } - -private: - std::shared_ptr pt_decoder_sp; }; class ProcessorTraceShowInstrLog : public lldb::SBCommandPluginInterface { public: - ProcessorTraceShowInstrLog(std::shared_ptr &pt_decoder) - : SBCommandPluginInterface(), pt_decoder_sp(pt_decoder) {} + ProcessorTraceShowInstrLog() : SBCommandPluginInterface() {} ~ProcessorTraceShowInstrLog() {} @@ -299,7 +305,8 @@ lldb::SBCommandReturnObject &result) { lldb::SBProcess process; lldb::SBThread thread; - if (!GetProcess(debugger, result, process)) + intelpt::SBPTProcess ptprocess; + if (!GetPTProcess(debugger, result, process, ptprocess)) return false; // Default initialize API's arguments @@ -364,8 +371,8 @@ // Get the instruction log intelpt::PTInstructionList insn_list; - pt_decoder_sp->GetInstructionLogAtOffset(process, thread_id, offset, - count, insn_list, error); + ptprocess.GetInstructionLogAtOffset(thread_id, offset, count, insn_list, + error); if (!error.Success()) { res.Printf("thread #%" PRIu32 ": tid=%" PRIu64 ", error: %s", thread.GetIndexID(), thread_id, error.GetCString()); @@ -424,14 +431,12 @@ } private: - std::shared_ptr pt_decoder_sp; const uint32_t m_default_count = 10; }; class ProcessorTraceStop : public lldb::SBCommandPluginInterface { public: - ProcessorTraceStop(std::shared_ptr &pt_decoder) - : SBCommandPluginInterface(), pt_decoder_sp(pt_decoder) {} + ProcessorTraceStop() : SBCommandPluginInterface() {} ~ProcessorTraceStop() {} @@ -439,7 +444,8 @@ lldb::SBCommandReturnObject &result) { lldb::SBProcess process; lldb::SBThread thread; - if (!GetProcess(debugger, result, process)) + intelpt::SBPTProcess ptprocess; + if (!GetPTProcess(debugger, result, process, ptprocess)) return false; lldb::tid_t thread_id; @@ -466,7 +472,7 @@ // Stop trace lldb::SBError error; - pt_decoder_sp->StopProcessorTrace(process, error, thread_id); + ptprocess.StopProcessorTrace(error, thread_id); if (!error.Success()) { result.Printf("error: %s\n", error.GetCString()); result.SetStatus(lldb::eReturnStatusFailed); @@ -475,9 +481,6 @@ result.SetStatus(lldb::eReturnStatusSuccessFinishResult); return true; } - -private: - std::shared_ptr pt_decoder_sp; }; bool PTPluginInitialize(lldb::SBDebugger &debugger) { @@ -485,11 +488,7 @@ lldb::SBCommand proc_trace = interpreter.AddMultiwordCommand( "processor-trace", "Intel(R) Processor Trace for thread/process"); - std::shared_ptr PTDecoderSP( - new intelpt::PTDecoder(debugger)); - - lldb::SBCommandPluginInterface *proc_trace_start = - new ProcessorTraceStart(PTDecoderSP); + lldb::SBCommandPluginInterface *proc_trace_start = new ProcessorTraceStart(); const char *help_proc_trace_start = "start Intel(R) Processor Trace on a " "specific thread or on the whole process"; const char *syntax_proc_trace_start = @@ -506,8 +505,7 @@ proc_trace.AddCommand("start", proc_trace_start, help_proc_trace_start, syntax_proc_trace_start); - lldb::SBCommandPluginInterface *proc_trace_stop = - new ProcessorTraceStop(PTDecoderSP); + lldb::SBCommandPluginInterface *proc_trace_stop = new ProcessorTraceStop(); const char *help_proc_trace_stop = "stop Intel(R) Processor Trace on a specific thread or on whole process"; const char *syntax_proc_trace_stop = @@ -522,7 +520,7 @@ syntax_proc_trace_stop); lldb::SBCommandPluginInterface *proc_trace_show_instr_log = - new ProcessorTraceShowInstrLog(PTDecoderSP); + new ProcessorTraceShowInstrLog(); const char *help_proc_trace_show_instr_log = "display a log of assembly instructions executed for a specific thread " "or for the whole process.\n" @@ -551,8 +549,7 @@ help_proc_trace_show_instr_log, syntax_proc_trace_show_instr_log); - lldb::SBCommandPluginInterface *proc_trace_options = - new ProcessorTraceInfo(PTDecoderSP); + lldb::SBCommandPluginInterface *proc_trace_options = new ProcessorTraceInfo(); const char *help_proc_trace_show_options = "display all the information regarding Intel(R) Processor Trace for a " "specific thread or for the whole process.\n" diff --git a/lldb/tools/intel-features/intel-pt/source/Core/CMakeLists.txt b/lldb/tools/intel-features/intel-pt/source/Core/CMakeLists.txt --- a/lldb/tools/intel-features/intel-pt/source/Core/CMakeLists.txt +++ b/lldb/tools/intel-features/intel-pt/source/Core/CMakeLists.txt @@ -21,7 +21,7 @@ endif() add_lldb_library(lldbIntelPTCore - Decoder.cpp + PTProcess.cpp LINK_LIBS ${LIBIPT_LIBRARY} diff --git a/lldb/tools/intel-features/intel-pt/source/Core/Decoder.cpp b/lldb/tools/intel-features/intel-pt/source/Core/PTProcess.cpp rename from lldb/tools/intel-features/intel-pt/source/Core/Decoder.cpp rename to lldb/tools/intel-features/intel-pt/source/Core/PTProcess.cpp --- a/lldb/tools/intel-features/intel-pt/source/Core/Decoder.cpp +++ b/lldb/tools/intel-features/intel-pt/source/Core/PTProcess.cpp @@ -1,4 +1,4 @@ -//===-- Decoder.cpp ---------------------------------------------*- C++ -*-===// +//===-- PTProcess.cpp -------------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "intel-pt/Core/Decoder.h" +#include "intel-pt/Core/PTProcess.h" // C/C++ Includes #include @@ -18,77 +18,37 @@ using namespace intelpt_private; -// This function removes entries of all the processes/threads which were once +// This function removes entries of all the threads which were once // registered in the class but are not alive anymore because they died or // finished executing. -void Decoder::RemoveDeadProcessesAndThreads(lldb::SBProcess &sbprocess) { - lldb::SBTarget sbtarget = sbprocess.GetTarget(); - lldb::SBDebugger sbdebugger = sbtarget.GetDebugger(); - uint32_t num_targets = sbdebugger.GetNumTargets(); - - auto itr_process = m_mapProcessUID_mapThreadID_TraceInfo.begin(); - while (itr_process != m_mapProcessUID_mapThreadID_TraceInfo.end()) { - bool process_found = false; - lldb::SBTarget target; - lldb::SBProcess process; - for (uint32_t i = 0; i < num_targets; i++) { - target = sbdebugger.GetTargetAtIndex(i); - process = target.GetProcess(); - if (process.GetUniqueID() == itr_process->first) { - process_found = true; - break; - } - } - - // Remove the process's entry if it was not found in SBDebugger - if (!process_found) { - itr_process = m_mapProcessUID_mapThreadID_TraceInfo.erase(itr_process); +void PTProcess::RemoveDeadThreads() { + auto itr_thread = m_mapThreadID_TraceInfo.begin(); + while (itr_thread != m_mapThreadID_TraceInfo.end()) { + if (itr_thread->first == LLDB_INVALID_THREAD_ID) { + ++itr_thread; continue; } - // If the state of the process is exited or detached then remove process's - // entry. If not then remove entry for all those registered threads of this - // process that are not alive anymore. - lldb::StateType state = process.GetState(); - if ((state == lldb::StateType::eStateDetached) || - (state == lldb::StateType::eStateExited)) - itr_process = m_mapProcessUID_mapThreadID_TraceInfo.erase(itr_process); - else { - auto itr_thread = itr_process->second.begin(); - while (itr_thread != itr_process->second.end()) { - if (itr_thread->first == LLDB_INVALID_THREAD_ID) { - ++itr_thread; - continue; - } - - lldb::SBThread thread = process.GetThreadByID(itr_thread->first); - if (!thread.IsValid()) - itr_thread = itr_process->second.erase(itr_thread); - else - ++itr_thread; - } - ++itr_process; - } + lldb::SBThread thread = m_process.GetThreadByID(itr_thread->first); + if (!thread.IsValid()) + itr_thread = m_mapThreadID_TraceInfo.erase(itr_thread); + else + ++itr_thread; } } -void Decoder::StartProcessorTrace(lldb::SBProcess &sbprocess, - lldb::SBTraceOptions &sbtraceoptions, - lldb::SBError &sberror) { +void PTProcess::StartProcessorTrace(lldb::SBTraceOptions &sbtraceoptions, + lldb::SBError &sberror) { sberror.Clear(); - CheckDebuggerID(sbprocess, sberror); - if (!sberror.Success()) - return; - std::lock_guard guard( - m_mapProcessUID_mapThreadID_TraceInfo_mutex); - RemoveDeadProcessesAndThreads(sbprocess); + std::lock_guard guard(m_mapThreadID_TraceInfo_mutex); + RemoveDeadThreads(); if (sbtraceoptions.getType() != lldb::TraceType::eTraceTypeProcessorTrace) { sberror.SetErrorStringWithFormat("SBTraceOptions::TraceType not set to " "eTraceTypeProcessorTrace; ProcessID = " "%" PRIu64, - sbprocess.GetProcessID()); + m_process.GetProcessID()); return; } lldb::SBStructuredData sbstructdata = sbtraceoptions.getTraceParams(sberror); @@ -116,7 +76,7 @@ std::size_t pos = trace_tech_value.find((const char *)string_value, 0, bytes_written); - if ((pos == std::string::npos)) { + if (pos == std::string::npos) { sberror.SetErrorStringWithFormat( "key \"%s\" not set to \"%s\" in custom trace parameters", trace_tech_key, trace_tech_value.c_str()); @@ -125,55 +85,40 @@ // Start Tracing lldb::SBError error; - uint32_t unique_id = sbprocess.GetUniqueID(); lldb::tid_t tid = sbtraceoptions.getThreadID(); - lldb::SBTrace trace = sbprocess.StartTrace(sbtraceoptions, error); + lldb::SBTrace trace = m_process.StartTrace(sbtraceoptions, error); if (!error.Success()) { if (tid == LLDB_INVALID_THREAD_ID) sberror.SetErrorStringWithFormat("%s; ProcessID = %" PRIu64, error.GetCString(), - sbprocess.GetProcessID()); + m_process.GetProcessID()); else sberror.SetErrorStringWithFormat( "%s; thread_id = %" PRIu64 ", ProcessID = %" PRIu64, - error.GetCString(), tid, sbprocess.GetProcessID()); + error.GetCString(), tid, m_process.GetProcessID()); return; } - MapThreadID_TraceInfo &mapThreadID_TraceInfo = - m_mapProcessUID_mapThreadID_TraceInfo[unique_id]; - ThreadTraceInfo &trace_info = mapThreadID_TraceInfo[tid]; + ThreadTraceInfo &trace_info = m_mapThreadID_TraceInfo[tid]; trace_info.SetUniqueTraceInstance(trace); - trace_info.SetStopID(sbprocess.GetStopID()); + trace_info.SetStopID(m_process.GetStopID()); } -void Decoder::StopProcessorTrace(lldb::SBProcess &sbprocess, - lldb::SBError &sberror, lldb::tid_t tid) { +void PTProcess::StopProcessorTrace(lldb::SBError &sberror, lldb::tid_t tid) { sberror.Clear(); - CheckDebuggerID(sbprocess, sberror); if (!sberror.Success()) { return; } - std::lock_guard guard( - m_mapProcessUID_mapThreadID_TraceInfo_mutex); - RemoveDeadProcessesAndThreads(sbprocess); - - uint32_t unique_id = sbprocess.GetUniqueID(); - auto itr_process = m_mapProcessUID_mapThreadID_TraceInfo.find(unique_id); - if (itr_process == m_mapProcessUID_mapThreadID_TraceInfo.end()) { - sberror.SetErrorStringWithFormat( - "tracing not active for this process; ProcessID = %" PRIu64, - sbprocess.GetProcessID()); - return; - } + std::lock_guard guard(m_mapThreadID_TraceInfo_mutex); + RemoveDeadThreads(); lldb::SBError error; if (tid == LLDB_INVALID_THREAD_ID) { // This implies to stop tracing on the whole process lldb::user_id_t id_to_be_ignored = LLDB_INVALID_UID; - auto itr_thread = itr_process->second.begin(); - while (itr_thread != itr_process->second.end()) { + auto itr_thread = m_mapThreadID_TraceInfo.begin(); + while (itr_thread != m_mapThreadID_TraceInfo.end()) { // In the case when user started trace on the entire process and then // registered newly spawned threads of this process in the class later, // these newly spawned threads will have same trace id. If we stopped @@ -194,7 +139,7 @@ sberror.SetErrorStringWithFormat( "%s; thread id=%" PRIu64 ", ProcessID = %" PRIu64, error_string.c_str(), itr_thread->first, - sbprocess.GetProcessID()); + m_process.GetProcessID()); return; } } @@ -202,9 +147,8 @@ if (itr_thread->first == LLDB_INVALID_THREAD_ID) id_to_be_ignored = lldb_pt_user_id; } - itr_thread = itr_process->second.erase(itr_thread); + itr_thread = m_mapThreadID_TraceInfo.erase(itr_thread); } - m_mapProcessUID_mapThreadID_TraceInfo.erase(itr_process); } else { // This implies to stop tracing on a single thread. // if 'tid' is registered in the class then get the trace id and stop trace @@ -215,20 +159,19 @@ // the trace id of the process trace instance and stop trace on this thread. // If tracing was never started on the entire process then return error // because there is no way tracing is active on 'tid'. - MapThreadID_TraceInfo &mapThreadID_TraceInfo = itr_process->second; lldb::SBTrace trace; - auto itr = mapThreadID_TraceInfo.find(tid); - if (itr != mapThreadID_TraceInfo.end()) { + auto itr = m_mapThreadID_TraceInfo.find(tid); + if (itr != m_mapThreadID_TraceInfo.end()) { trace = itr->second.GetUniqueTraceInstance(); } else { - auto itr = mapThreadID_TraceInfo.find(LLDB_INVALID_THREAD_ID); - if (itr != mapThreadID_TraceInfo.end()) { + auto itr = m_mapThreadID_TraceInfo.find(LLDB_INVALID_THREAD_ID); + if (itr != m_mapThreadID_TraceInfo.end()) { trace = itr->second.GetUniqueTraceInstance(); } else { sberror.SetErrorStringWithFormat( "tracing not active for this thread; thread id=%" PRIu64 ", ProcessID = %" PRIu64, - tid, sbprocess.GetProcessID()); + tid, m_process.GetProcessID()); return; } } @@ -239,18 +182,18 @@ std::string error_string(error.GetCString()); sberror.SetErrorStringWithFormat( "%s; thread id=%" PRIu64 ", ProcessID = %" PRIu64, - error_string.c_str(), tid, sbprocess.GetProcessID()); + error_string.c_str(), tid, m_process.GetProcessID()); if (error_string.find("tracing not active") == std::string::npos) return; } // Delete the entry of 'tid' from this class (if any) - mapThreadID_TraceInfo.erase(tid); + m_mapThreadID_TraceInfo.erase(tid); } } -void Decoder::ReadTraceDataAndImageInfo(lldb::SBProcess &sbprocess, - lldb::tid_t tid, lldb::SBError &sberror, - ThreadTraceInfo &threadTraceInfo) { +void PTProcess::ReadTraceDataAndImageInfo(lldb::tid_t tid, + lldb::SBError &sberror, + ThreadTraceInfo &threadTraceInfo) { // Allocate trace data buffer and parse cpu info for 'tid' if it is registered // for the first time in class lldb::SBTrace &trace = threadTraceInfo.GetUniqueTraceInstance(); @@ -263,14 +206,14 @@ if (!error.Success()) { sberror.SetErrorStringWithFormat("%s; ProcessID = %" PRIu64, error.GetCString(), - sbprocess.GetProcessID()); + m_process.GetProcessID()); return; } if (traceoptions.getType() != lldb::TraceType::eTraceTypeProcessorTrace) { sberror.SetErrorStringWithFormat("invalid TraceType received from LLDB " "for this thread; thread id=%" PRIu64 ", ProcessID = %" PRIu64, - tid, sbprocess.GetProcessID()); + tid, m_process.GetProcessID()); return; } @@ -290,23 +233,21 @@ if (!error.Success()) { sberror.SetErrorStringWithFormat( "%s; thread_id = %" PRIu64 ", ProcessID = %" PRIu64, - error.GetCString(), tid, sbprocess.GetProcessID()); + error.GetCString(), tid, m_process.GetProcessID()); return; } std::fill(pt_buffer.begin() + bytes_written, pt_buffer.end(), 0); // Get information of all the modules of the inferior - lldb::SBTarget sbtarget = sbprocess.GetTarget(); ReadExecuteSectionInfos &readExecuteSectionInfos = threadTraceInfo.GetReadExecuteSectionInfos(); - GetTargetModulesInfo(sbtarget, readExecuteSectionInfos, sberror); + GetTargetModulesInfo(readExecuteSectionInfos, sberror); if (!sberror.Success()) return; } -void Decoder::DecodeProcessorTrace(lldb::SBProcess &sbprocess, lldb::tid_t tid, - lldb::SBError &sberror, - ThreadTraceInfo &threadTraceInfo) { +void PTProcess::DecodeProcessorTrace(lldb::tid_t tid, lldb::SBError &sberror, + ThreadTraceInfo &threadTraceInfo) { // Initialize instruction decoder struct pt_insn_decoder *decoder = nullptr; struct pt_config config; @@ -329,15 +270,9 @@ // Raw trace decoding requires information of Read & Execute sections of each // module of the inferior. This function updates internal state of the class to // store this information. -void Decoder::GetTargetModulesInfo( - lldb::SBTarget &sbtarget, ReadExecuteSectionInfos &readExecuteSectionInfos, - lldb::SBError &sberror) { - if (!sbtarget.IsValid()) { - sberror.SetErrorStringWithFormat("Can't get target's modules info from " - "LLDB; process has an invalid target"); - return; - } - +void PTProcess::GetTargetModulesInfo( + ReadExecuteSectionInfos &readExecuteSectionInfos, lldb::SBError &sberror) { + lldb::SBTarget sbtarget = m_process.GetTarget(); lldb::SBFileSpec target_file_spec = sbtarget.GetExecutable(); if (!target_file_spec.IsValid()) { sberror.SetErrorStringWithFormat("Target has an invalid file spec"); @@ -416,8 +351,8 @@ // is running. This function gets the Trace Configuration from LLDB, parses it // for cpu model, family, stepping and vendor id info and updates the internal // state of the class to store this information. -void Decoder::ParseCPUInfo(CPUInfo &pt_cpu, lldb::SBStructuredData &s, - lldb::SBError &sberror) { +void PTProcess::ParseCPUInfo(CPUInfo &pt_cpu, lldb::SBStructuredData &s, + lldb::SBError &sberror) { lldb::SBStructuredData custom_trace_params = s.GetValueForKey("intel-pt"); if (!custom_trace_params.IsValid()) { sberror.SetErrorStringWithFormat("lldb couldn't provide cpuinfo"); @@ -505,7 +440,7 @@ // structure with inferior's memory image information. pt_config structure is // initialized with trace buffer and cpu info of the inferior before storing it // in trace decoder. -void Decoder::InitializePTInstDecoder( +void PTProcess::InitializePTInstDecoder( struct pt_insn_decoder **decoder, struct pt_config *config, const CPUInfo &pt_cpu, Buffer &pt_buffer, const ReadExecuteSectionInfos &readExecuteSectionInfos, @@ -564,7 +499,7 @@ } } -void Decoder::AppendErrorWithOffsetToInstructionList( +void PTProcess::AppendErrorWithOffsetToInstructionList( int errcode, uint64_t decoder_offset, Instructions &instruction_list, lldb::SBError &sberror) { sberror.SetErrorStringWithFormat( @@ -574,16 +509,17 @@ instruction_list.emplace_back(sberror.GetCString()); } -void Decoder::AppendErrorWithoutOffsetToInstructionList( +void PTProcess::AppendErrorWithoutOffsetToInstructionList( int errcode, Instructions &instruction_list, lldb::SBError &sberror) { sberror.SetErrorStringWithFormat("processor trace decoding library: \"%s\"", pt_errstr(pt_errcode(errcode))); instruction_list.emplace_back(sberror.GetCString()); } -int Decoder::AppendErrorToInstructionList(int errcode, pt_insn_decoder *decoder, - Instructions &instruction_list, - lldb::SBError &sberror) { +int PTProcess::AppendErrorToInstructionList(int errcode, + pt_insn_decoder *decoder, + Instructions &instruction_list, + lldb::SBError &sberror) { uint64_t decoder_offset = 0; int errcode_off = pt_insn_get_offset(decoder, &decoder_offset); if (errcode_off < 0) { @@ -596,9 +532,9 @@ return 0; } -int Decoder::HandlePTInstructionEvents(pt_insn_decoder *decoder, int errcode, - Instructions &instruction_list, - lldb::SBError &sberror) { +int PTProcess::HandlePTInstructionEvents(pt_insn_decoder *decoder, int errcode, + Instructions &instruction_list, + lldb::SBError &sberror) { while (errcode & pts_event_pending) { pt_event event; errcode = pt_insn_event(decoder, &event, sizeof(event)); @@ -620,9 +556,9 @@ } // Start actual decoding of raw trace -void Decoder::DecodeTrace(struct pt_insn_decoder *decoder, - Instructions &instruction_list, - lldb::SBError &sberror) { +void PTProcess::DecodeTrace(struct pt_insn_decoder *decoder, + Instructions &instruction_list, + lldb::SBError &sberror) { uint64_t decoder_offset = 0; while (1) { @@ -710,8 +646,8 @@ } // Function to diagnose and indicate errors during raw trace decoding -void Decoder::Diagnose(struct pt_insn_decoder *decoder, int decode_error, - lldb::SBError &sberror, const struct pt_insn *insn) { +void PTProcess::Diagnose(struct pt_insn_decoder *decoder, int decode_error, + lldb::SBError &sberror, const struct pt_insn *insn) { int errcode; uint64_t offset; @@ -740,23 +676,16 @@ } } -void Decoder::GetInstructionLogAtOffset(lldb::SBProcess &sbprocess, - lldb::tid_t tid, uint32_t offset, - uint32_t count, - InstructionList &result_list, - lldb::SBError &sberror) { +void PTProcess::GetInstructionLogAtOffset(lldb::tid_t tid, uint32_t offset, + uint32_t count, + InstructionList &result_list, + lldb::SBError &sberror) { sberror.Clear(); - CheckDebuggerID(sbprocess, sberror); - if (!sberror.Success()) { - return; - } - - std::lock_guard guard( - m_mapProcessUID_mapThreadID_TraceInfo_mutex); - RemoveDeadProcessesAndThreads(sbprocess); + std::lock_guard guard(m_mapThreadID_TraceInfo_mutex); + RemoveDeadThreads(); ThreadTraceInfo *threadTraceInfo = nullptr; - FetchAndDecode(sbprocess, tid, sberror, &threadTraceInfo); + FetchAndDecode(tid, sberror, &threadTraceInfo); if (!sberror.Success()) { return; } @@ -774,7 +703,7 @@ sberror.SetErrorStringWithFormat( "Instruction Log not available for offset=%" PRIu32 " and count=%" PRIu32 ", ProcessID = %" PRIu64, - offset, count, sbprocess.GetProcessID()); + offset, count, m_process.GetProcessID()); return; } @@ -791,21 +720,18 @@ } } -void Decoder::GetProcessorTraceInfo(lldb::SBProcess &sbprocess, lldb::tid_t tid, - TraceOptions &options, - lldb::SBError &sberror) { +void PTProcess::GetProcessorTraceInfo(lldb::tid_t tid, TraceOptions &options, + lldb::SBError &sberror) { sberror.Clear(); - CheckDebuggerID(sbprocess, sberror); if (!sberror.Success()) { return; } - std::lock_guard guard( - m_mapProcessUID_mapThreadID_TraceInfo_mutex); - RemoveDeadProcessesAndThreads(sbprocess); + std::lock_guard guard(m_mapThreadID_TraceInfo_mutex); + RemoveDeadThreads(); ThreadTraceInfo *threadTraceInfo = nullptr; - FetchAndDecode(sbprocess, tid, sberror, &threadTraceInfo); + FetchAndDecode(tid, sberror, &threadTraceInfo); if (!sberror.Success()) { return; } @@ -823,22 +749,18 @@ if (!error.Success()) { std::string error_string(error.GetCString()); if (error_string.find("tracing not active") != std::string::npos) { - uint32_t unique_id = sbprocess.GetUniqueID(); - auto itr_process = m_mapProcessUID_mapThreadID_TraceInfo.find(unique_id); - if (itr_process == m_mapProcessUID_mapThreadID_TraceInfo.end()) - return; - itr_process->second.erase(tid); + m_mapThreadID_TraceInfo.erase(tid); } sberror.SetErrorStringWithFormat("%s; ProcessID = %" PRIu64, error_string.c_str(), - sbprocess.GetProcessID()); + m_process.GetProcessID()); return; } if (traceoptions.getType() != lldb::TraceType::eTraceTypeProcessorTrace) { sberror.SetErrorStringWithFormat("invalid TraceType received from LLDB " "for this thread; thread id=%" PRIu64 ", ProcessID = %" PRIu64, - tid, sbprocess.GetProcessID()); + tid, m_process.GetProcessID()); return; } options.setType(traceoptions.getType()); @@ -851,24 +773,13 @@ options.setInstructionLogSize(threadTraceInfo->GetInstructionLog().size()); } -void Decoder::FetchAndDecode(lldb::SBProcess &sbprocess, lldb::tid_t tid, - lldb::SBError &sberror, - ThreadTraceInfo **threadTraceInfo) { - // Return with error if 'sbprocess' is not registered in the class - uint32_t unique_id = sbprocess.GetUniqueID(); - auto itr_process = m_mapProcessUID_mapThreadID_TraceInfo.find(unique_id); - if (itr_process == m_mapProcessUID_mapThreadID_TraceInfo.end()) { - sberror.SetErrorStringWithFormat( - "tracing not active for this process; ProcessID = %" PRIu64, - sbprocess.GetProcessID()); - return; - } - +void PTProcess::FetchAndDecode(lldb::tid_t tid, lldb::SBError &sberror, + ThreadTraceInfo **threadTraceInfo) { if (tid == LLDB_INVALID_THREAD_ID) { sberror.SetErrorStringWithFormat( "invalid thread id provided; thread_id = %" PRIu64 ", ProcessID = %" PRIu64, - tid, sbprocess.GetProcessID()); + tid, m_process.GetProcessID()); return; } @@ -881,85 +792,50 @@ return; } - MapThreadID_TraceInfo &mapThreadID_TraceInfo = itr_process->second; - auto itr_thread = mapThreadID_TraceInfo.find(tid); - if (itr_thread != mapThreadID_TraceInfo.end()) { - if (itr_thread->second.GetStopID() == sbprocess.GetStopID()) { + auto itr_thread = m_mapThreadID_TraceInfo.find(tid); + if (itr_thread != m_mapThreadID_TraceInfo.end()) { + if (itr_thread->second.GetStopID() == m_process.GetStopID()) { *threadTraceInfo = &(itr_thread->second); return; } - itr_thread->second.SetStopID(sbprocess.GetStopID()); + itr_thread->second.SetStopID(m_process.GetStopID()); } else { // Implies 'tid' is not registered in the class. If tracing was never // started on the entire process then return an error. Else try to register // this thread and proceed with reading and decoding trace. lldb::SBError error; - itr_thread = mapThreadID_TraceInfo.find(LLDB_INVALID_THREAD_ID); - if (itr_thread == mapThreadID_TraceInfo.end()) { + itr_thread = m_mapThreadID_TraceInfo.find(LLDB_INVALID_THREAD_ID); + if (itr_thread == m_mapThreadID_TraceInfo.end()) { sberror.SetErrorStringWithFormat( "tracing not active for this thread; ProcessID = %" PRIu64, - sbprocess.GetProcessID()); + m_process.GetProcessID()); return; } lldb::SBTrace &trace = itr_thread->second.GetUniqueTraceInstance(); - ThreadTraceInfo &trace_info = mapThreadID_TraceInfo[tid]; + ThreadTraceInfo &trace_info = m_mapThreadID_TraceInfo[tid]; trace_info.SetUniqueTraceInstance(trace); - trace_info.SetStopID(sbprocess.GetStopID()); - itr_thread = mapThreadID_TraceInfo.find(tid); + trace_info.SetStopID(m_process.GetStopID()); + itr_thread = m_mapThreadID_TraceInfo.find(tid); } // Get raw trace data and inferior image from LLDB for the registered thread - ReadTraceDataAndImageInfo(sbprocess, tid, sberror, itr_thread->second); + ReadTraceDataAndImageInfo(tid, sberror, itr_thread->second); if (!sberror.Success()) { std::string error_string(sberror.GetCString()); if (error_string.find("tracing not active") != std::string::npos) - mapThreadID_TraceInfo.erase(itr_thread); + m_mapThreadID_TraceInfo.erase(itr_thread); return; } // Decode raw trace data - DecodeProcessorTrace(sbprocess, tid, sberror, itr_thread->second); + DecodeProcessorTrace(tid, sberror, itr_thread->second); if (!sberror.Success()) { return; } *threadTraceInfo = &(itr_thread->second); } -// This function checks whether the provided SBProcess instance belongs to same -// SBDebugger with which this tool instance is associated. -void Decoder::CheckDebuggerID(lldb::SBProcess &sbprocess, - lldb::SBError &sberror) { - if (!sbprocess.IsValid()) { - sberror.SetErrorStringWithFormat("invalid process instance"); - return; - } - - lldb::SBTarget sbtarget = sbprocess.GetTarget(); - if (!sbtarget.IsValid()) { - sberror.SetErrorStringWithFormat( - "process contains an invalid target; ProcessID = %" PRIu64, - sbprocess.GetProcessID()); - return; - } - - lldb::SBDebugger sbdebugger = sbtarget.GetDebugger(); - if (!sbdebugger.IsValid()) { - sberror.SetErrorStringWithFormat("process's target contains an invalid " - "debugger instance; ProcessID = %" PRIu64, - sbprocess.GetProcessID()); - return; - } - - if (sbdebugger.GetID() != m_debugger_user_id) { - sberror.SetErrorStringWithFormat( - "process belongs to a different SBDebugger instance than the one for " - "which the tool is instantiated; ProcessID = %" PRIu64, - sbprocess.GetProcessID()); - return; - } -} - -lldb::SBTraceOptions Decoder::GetDefaultTraceOptions() { +lldb::SBTraceOptions PTProcess::GetDefaultTraceOptions() { lldb::SBTraceOptions trace_opts; trace_opts.setThreadID(LLDB_INVALID_THREAD_ID); trace_opts.setType(lldb::TraceType::eTraceTypeProcessorTrace); diff --git a/lldb/tools/intel-features/scripts/lldb-intel-features.swig b/lldb/tools/intel-features/scripts/lldb-intel-features.swig --- a/lldb/tools/intel-features/scripts/lldb-intel-features.swig +++ b/lldb/tools/intel-features/scripts/lldb-intel-features.swig @@ -20,7 +20,7 @@ %{ #include "lldb/lldb-public.h" -#include "intel-pt/API/PTDecoder.h" +#include "intel-pt/API/SBPTProcess.h" using namespace intelpt; %} @@ -31,4 +31,4 @@ %include "python-typemaps.txt" /* Feature specific python interface files*/ -%include "../intel-pt/interface/PTDecoder.i" +%include "../intel-pt/interface/SBPTProcess.i"