This revision was automatically updated to reflect the committed changes.
Closed by commit rGa0a46473c3df: [trace][intelpt] Support system-wide tracing
[11] - Read warnings and perf… (authored by Walter Erquinigo
<[email protected]>).
Herald added a subscriber: Michael137.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D125943/new/
https://reviews.llvm.org/D125943
Files:
lldb/include/lldb/Target/Trace.h
lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
lldb/source/Target/Trace.cpp
Index: lldb/source/Target/Trace.cpp
===================================================================
--- lldb/source/Target/Trace.cpp
+++ lldb/source/Target/Trace.cpp
@@ -17,6 +17,7 @@
#include "lldb/Target/Process.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Thread.h"
+#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Stream.h"
using namespace lldb;
@@ -175,28 +176,37 @@
return m_live_process->TraceGetBinaryData(request);
}
-void Trace::RefreshLiveProcessState() {
+const char *Trace::RefreshLiveProcessState() {
if (!m_live_process)
- return;
+ return nullptr;
uint32_t new_stop_id = m_live_process->GetStopID();
if (new_stop_id == m_stop_id)
- return;
+ return nullptr;
+
+ Log *log = GetLog(LLDBLog::Target);
+ LLDB_LOG(log, "Trace::RefreshLiveProcessState invoked");
m_stop_id = new_stop_id;
m_live_thread_data.clear();
+ m_live_refresh_error.reset();
+
+ auto HandleError = [&](Error &&err) -> const char * {
+ m_live_refresh_error = toString(std::move(err));
+ return m_live_refresh_error->c_str();
+ };
Expected<std::string> json_string = GetLiveProcessState();
- if (!json_string) {
- DoRefreshLiveProcessState(json_string.takeError());
- return;
- }
+ if (!json_string)
+ return HandleError(json_string.takeError());
+
Expected<TraceGetStateResponse> live_process_state =
json::parse<TraceGetStateResponse>(*json_string, "TraceGetStateResponse");
- if (!live_process_state) {
- DoRefreshLiveProcessState(live_process_state.takeError());
- return;
- }
+ if (!live_process_state)
+ return HandleError(live_process_state.takeError());
+
+ for (std::string &warning : live_process_state->warnings)
+ LLDB_LOG(log, "Warning when fetching the trace state: {0}", warning);
for (const TraceThreadState &thread_state :
live_process_state->traced_threads) {
@@ -207,9 +217,15 @@
for (const TraceBinaryData &item : live_process_state->process_binary_data)
m_live_process_data[item.kind] = item.size;
- DoRefreshLiveProcessState(std::move(live_process_state));
+ if (Error err = DoRefreshLiveProcessState(std::move(*live_process_state),
+ *json_string))
+ return HandleError(std::move(err));
+
+ return nullptr;
}
+Process *Trace::GetLiveProcess() { return m_live_process; }
+
uint32_t Trace::GetStopID() {
RefreshLiveProcessState();
return m_stop_id;
Index: lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
===================================================================
--- lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
+++ lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
@@ -75,8 +75,8 @@
llvm::Expected<size_t> GetRawTraceSize(Thread &thread);
- void DoRefreshLiveProcessState(
- llvm::Expected<TraceGetStateResponse> state) override;
+ llvm::Error DoRefreshLiveProcessState(TraceGetStateResponse state,
+ llvm::StringRef json_response) override;
bool IsTraced(lldb::tid_t tid) override;
@@ -148,12 +148,6 @@
llvm::Expected<pt_cpu> GetCPUInfo();
- /// Get the current traced live process.
- ///
- /// \return
- /// The current traced live process. If it's not a live process,
- /// return \a nullptr.
- Process *GetLiveProcess();
/// \return
/// The timer object for this trace.
@@ -191,9 +185,11 @@
/// binary data.
llvm::Optional<pt_cpu> m_cpu_info;
std::map<lldb::tid_t, std::unique_ptr<ThreadDecoder>> m_thread_decoders;
- /// Error gotten after a failed live process update, if any.
- llvm::Optional<std::string> m_live_refresh_error;
+ /// Helper variable used to track long running operations for telemetry.
TaskTimer m_task_timer;
+ /// It is provided by either a session file or a live process to convert TSC
+ /// counters to and from nanos. It might not be available on all hosts.
+ llvm::Optional<LinuxPerfZeroTscConversion> m_tsc_conversion;
};
} // namespace trace_intel_pt
Index: lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
===================================================================
--- lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
+++ lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
@@ -87,11 +87,10 @@
}
DecodedThreadSP TraceIntelPT::Decode(Thread &thread) {
- RefreshLiveProcessState();
- if (m_live_refresh_error.hasValue())
+ if (const char *error = RefreshLiveProcessState())
return std::make_shared<DecodedThread>(
thread.shared_from_this(),
- createStringError(inconvertibleErrorCode(), *m_live_refresh_error));
+ createStringError(inconvertibleErrorCode(), error));
auto it = m_thread_decoders.find(thread.GetID());
if (it == m_thread_decoders.end())
@@ -241,23 +240,29 @@
return *m_cpu_info;
}
-Process *TraceIntelPT::GetLiveProcess() { return m_live_process; }
-
-void TraceIntelPT::DoRefreshLiveProcessState(
- Expected<TraceGetStateResponse> state) {
+Error TraceIntelPT::DoRefreshLiveProcessState(TraceGetStateResponse state,
+ StringRef json_response) {
m_thread_decoders.clear();
- if (!state) {
- m_live_refresh_error = toString(state.takeError());
- return;
- }
-
- for (const TraceThreadState &thread_state : state->traced_threads) {
+ for (const TraceThreadState &thread_state : state.traced_threads) {
ThreadSP thread_sp =
- m_live_process->GetThreadList().FindThreadByID(thread_state.tid);
+ GetLiveProcess()->GetThreadList().FindThreadByID(thread_state.tid);
m_thread_decoders.emplace(
thread_state.tid, std::make_unique<ThreadDecoder>(thread_sp, *this));
}
+
+ Expected<TraceIntelPTGetStateResponse> intelpt_state =
+ json::parse<TraceIntelPTGetStateResponse>(json_response,
+ "TraceIntelPTGetStateResponse");
+ if (!intelpt_state)
+ return intelpt_state.takeError();
+
+ m_tsc_conversion = intelpt_state->tsc_perf_zero_conversion;
+ if (m_tsc_conversion) {
+ Log *log = GetLog(LLDBLog::Target);
+ LLDB_LOG(log, "TraceIntelPT found TSC conversion information");
+ }
+ return Error::success();
}
bool TraceIntelPT::IsTraced(lldb::tid_t tid) {
Index: lldb/include/lldb/Target/Trace.h
===================================================================
--- lldb/include/lldb/Target/Trace.h
+++ lldb/include/lldb/Target/Trace.h
@@ -265,6 +265,13 @@
llvm::Error OnThreadBinaryDataRead(lldb::tid_t tid, llvm::StringRef kind,
OnBinaryDataReadCallback callback);
+ /// Get the current traced live process.
+ ///
+ /// \return
+ /// The current traced live process. If it's not a live process,
+ /// return \a nullptr.
+ Process *GetLiveProcess();
+
protected:
/// Implementation of \a OnThreadBinaryDataRead() for live threads.
llvm::Error OnLiveThreadBinaryDataRead(lldb::tid_t tid, llvm::StringRef kind,
@@ -365,14 +372,30 @@
///
/// \param[in] state
/// The jLLDBTraceGetState response.
- virtual void
- DoRefreshLiveProcessState(llvm::Expected<TraceGetStateResponse> state) = 0;
+ ///
+ /// \param[in] json_response
+ /// The original JSON response as a string. It might be useful to redecode
+ /// it if it contains custom data for a specific trace plug-in.
+ ///
+ /// \return
+ /// \b Error::success() if this operation succeedes, or an actual error
+ /// otherwise.
+ virtual llvm::Error
+ DoRefreshLiveProcessState(TraceGetStateResponse state,
+ llvm::StringRef json_response) = 0;
- /// Method to be invoked by the plug-in to refresh the live process state.
+ /// Method to be invoked by the plug-in to refresh the live process state. It
+ /// will invoked DoRefreshLiveProcessState at some point, which should be
+ /// implemented by the plug-in for custom state handling.
+ ///
+ /// The result is cached through the same process stop. Even in the case of
+ /// errors, it caches the error.
///
- /// The result is cached through the same process stop.
- void RefreshLiveProcessState();
+ /// \return
+ /// An error message if this operation failed, or \b nullptr otherwise.
+ const char *RefreshLiveProcessState();
+private:
uint32_t m_stop_id = LLDB_INVALID_STOP_ID;
/// Process traced by this object if doing live tracing. Otherwise it's null.
Process *m_live_process = nullptr;
@@ -395,6 +418,8 @@
/// tid -> data kind -> file
llvm::DenseMap<lldb::tid_t, std::unordered_map<std::string, FileSpec>>
m_postmortem_thread_data;
+
+ llvm::Optional<std::string> m_live_refresh_error;
};
} // namespace lldb_private
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits