Skip to content

Commit 1a3f996

Browse files
author
Walter Erquinigo
committed
[trace][intelpt] Support system-wide tracing [13] - Add context switch decoding
- Add the logic that parses all cpu context switch traces and produces blocks of continuous executions, which will be later used to assign intel pt subtraces to threads and to identify gaps. This logic can also identify if the context switch trace is malformed. - The continuous executions blocks are able to indicate when there were some contention issues when producing the context switch trace. See the inline comments for more information. - Update the 'dump info' command to show information and stats related to the multicore decoding flow, including timing about context switch decoding. - Add the logic to conver nanoseconds to TSCs. - Fix a bug when returning the context switches. Now they data returned makes sense and even empty traces can be returned from lldb-server. - Finish the necessary bits for loading and saving a multi-core trace bundle from disk. - Change some size_t to uint64_t for compatibility with 32 bit systems. Tested by saving a trace session of a program that sleeps 100 times, it was able to produce the following 'dump info' text: ``` (lldb) trace load /tmp/trace3/trace.json (lldb) thread trace dump info Trace technology: intel-pt thread #1: tid = 4192415 Total number of instructions: 1 Memory usage: Total approximate memory usage (excluding raw trace): 2.51 KiB Average memory usage per instruction (excluding raw trace): 2573.00 bytes Timing for this thread: Timing for global tasks: Context switch trace decoding: 0.00s Events: Number of instructions with events: 0 Number of individual events: 0 Multi-core decoding: Total number of continuous executions found: 2499 Number of continuous executions for this thread: 102 Errors: Number of TSC decoding errors: 0 ``` Differential Revision: https://reviews.llvm.org/D126267
1 parent ff0122d commit 1a3f996

22 files changed

+702
-120
lines changed

lldb/include/lldb/Target/Trace.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -433,15 +433,15 @@ class Trace : public PluginInterface,
433433
GetLiveProcessBinaryData(llvm::StringRef kind);
434434

435435
/// Get the size of the data returned by \a GetLiveThreadBinaryData
436-
llvm::Optional<size_t> GetLiveThreadBinaryDataSize(lldb::tid_t tid,
437-
llvm::StringRef kind);
436+
llvm::Optional<uint64_t> GetLiveThreadBinaryDataSize(lldb::tid_t tid,
437+
llvm::StringRef kind);
438438

439439
/// Get the size of the data returned by \a GetLiveCoreBinaryData
440-
llvm::Optional<size_t> GetLiveCoreBinaryDataSize(lldb::core_id_t core_id,
441-
llvm::StringRef kind);
440+
llvm::Optional<uint64_t> GetLiveCoreBinaryDataSize(lldb::core_id_t core_id,
441+
llvm::StringRef kind);
442442

443443
/// Get the size of the data returned by \a GetLiveProcessBinaryData
444-
llvm::Optional<size_t> GetLiveProcessBinaryDataSize(llvm::StringRef kind);
444+
llvm::Optional<uint64_t> GetLiveProcessBinaryDataSize(llvm::StringRef kind);
445445

446446
/// Constructor for post mortem processes
447447
Trace(llvm::ArrayRef<lldb::ProcessSP> postmortem_processes,
@@ -513,14 +513,14 @@ class Trace : public PluginInterface,
513513
/// \{
514514

515515
/// tid -> data kind -> size
516-
llvm::DenseMap<lldb::tid_t, std::unordered_map<std::string, size_t>>
516+
llvm::DenseMap<lldb::tid_t, std::unordered_map<std::string, uint64_t>>
517517
m_live_thread_data;
518518

519519
/// core id -> data kind -> size
520-
llvm::DenseMap<lldb::core_id_t, std::unordered_map<std::string, size_t>>
520+
llvm::DenseMap<lldb::core_id_t, std::unordered_map<std::string, uint64_t>>
521521
m_live_core_data;
522522
/// data kind -> size
523-
std::unordered_map<std::string, size_t> m_live_process_data;
523+
std::unordered_map<std::string, uint64_t> m_live_process_data;
524524
/// \}
525525

526526
/// The list of cores being traced. Might be \b None depending on the plug-in.

lldb/include/lldb/Utility/TraceGDBRemotePackets.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ struct TraceGetBinaryDataRequest {
154154
/// Optional tid if the data is related to a thread.
155155
llvm::Optional<lldb::tid_t> tid;
156156
/// Optional core id if the data is related to a cpu core.
157-
llvm::Optional<lldb::tid_t> core_id;
157+
llvm::Optional<lldb::core_id_t> core_id;
158158
/// Offset in bytes from where to start reading the data.
159159
uint64_t offset;
160160
/// Number of bytes to read.

lldb/include/lldb/Utility/TraceIntelPTGDBRemotePackets.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,9 @@ struct LinuxPerfZeroTscConversion {
8080
///
8181
/// \return
8282
/// Nanosecond wall time.
83-
std::chrono::nanoseconds ToNanos(uint64_t tsc);
83+
std::chrono::nanoseconds ToNanos(uint64_t tsc) const;
84+
85+
uint64_t ToTSC(std::chrono::nanoseconds nanos) const;
8486

8587
uint32_t time_mult;
8688
uint16_t time_shift;

lldb/source/Plugins/Process/Linux/Perf.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ PerfEvent::ReadFlushedOutDataCyclicBuffer(size_t offset, size_t size) {
231231
"buffer but only {1} are available",
232232
size, output.size()));
233233

234-
return data;
234+
return output;
235235
}
236236

237237
Expected<std::vector<uint8_t>>
@@ -282,7 +282,7 @@ PerfEvent::ReadFlushedOutAuxCyclicBuffer(size_t offset, size_t size) {
282282
"buffer but only {1} are available",
283283
size, output.size()));
284284

285-
return data;
285+
return output;
286286
}
287287

288288
Error PerfEvent::DisableWithIoctl() {
@@ -313,7 +313,7 @@ Error PerfEvent::EnableWithIoctl() {
313313

314314
size_t PerfEvent::GetEffectiveDataBufferSize() const {
315315
perf_event_mmap_page &mmap_metadata = GetMetadataPage();
316-
if (mmap_metadata.data_head <= mmap_metadata.data_size)
316+
if (mmap_metadata.data_head < mmap_metadata.data_size)
317317
return mmap_metadata.data_head;
318318
else
319319
return mmap_metadata.data_size; // The buffer has wrapped.

lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2697,8 +2697,8 @@ GDBRemoteCommunicationClient::SendSetCurrentThreadPacket(uint64_t tid,
26972697
packet.Printf("%" PRIx64, tid);
26982698

26992699
StringExtractorGDBRemote response;
2700-
if (SendPacketAndWaitForResponse(packet.GetString(), response)
2701-
== PacketResult::Success) {
2700+
if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
2701+
PacketResult::Success) {
27022702
if (response.IsOKResponse())
27032703
return {{pid, tid}};
27042704

@@ -3701,9 +3701,6 @@ GDBRemoteCommunicationClient::SendTraceGetBinaryData(
37013701
GDBRemoteCommunication::PacketResult::Success) {
37023702
if (response.IsErrorResponse())
37033703
return response.GetStatus().ToError();
3704-
if (response.IsUnsupportedResponse())
3705-
return llvm::createStringError(llvm::inconvertibleErrorCode(),
3706-
"jLLDBTraceGetBinaryData is unsupported");
37073704
std::string data;
37083705
response.GetEscapedBinaryData(data);
37093706
return std::vector<uint8_t>(data.begin(), data.end());

lldb/source/Plugins/Trace/intel-pt/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ add_lldb_library(lldbPluginTraceIntelPT PLUGIN
2222
TraceCursorIntelPT.cpp
2323
TraceIntelPT.cpp
2424
TraceIntelPTJSONStructs.cpp
25+
TraceIntelPTMultiCoreDecoder.cpp
2526
TraceIntelPTSessionFileParser.cpp
2627
TraceIntelPTSessionSaver.cpp
2728

lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ class CommandObjectThreadTraceStartIntelPT
3131

3232
llvm::ArrayRef<OptionDefinition> GetDefinitions() override;
3333

34-
size_t m_trace_buffer_size;
34+
uint64_t m_trace_buffer_size;
3535
bool m_enable_tsc;
36-
llvm::Optional<size_t> m_psb_period;
36+
llvm::Optional<uint64_t> m_psb_period;
3737
};
3838

3939
CommandObjectThreadTraceStartIntelPT(TraceIntelPT &trace,
@@ -74,10 +74,10 @@ class CommandObjectProcessTraceStartIntelPT : public CommandObjectParsed {
7474

7575
llvm::ArrayRef<OptionDefinition> GetDefinitions() override;
7676

77-
size_t m_trace_buffer_size;
78-
size_t m_process_buffer_size_limit;
77+
uint64_t m_trace_buffer_size;
78+
uint64_t m_process_buffer_size_limit;
7979
bool m_enable_tsc;
80-
llvm::Optional<size_t> m_psb_period;
80+
llvm::Optional<uint64_t> m_psb_period;
8181
bool m_per_core_tracing;
8282
};
8383

lldb/source/Plugins/Trace/intel-pt/TaskTimer.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ using namespace lldb_private;
55
using namespace lldb_private::trace_intel_pt;
66
using namespace llvm;
77

8-
void ThreadTaskTimer::ForEachTimedTask(
8+
void ScopedTaskTimer::ForEachTimedTask(
99
std::function<void(const std::string &event,
1010
std::chrono::milliseconds duration)>
1111
callback) {
@@ -14,9 +14,11 @@ void ThreadTaskTimer::ForEachTimedTask(
1414
}
1515
}
1616

17-
ThreadTaskTimer &TaskTimer::ForThread(lldb::tid_t tid) {
17+
ScopedTaskTimer &TaskTimer::ForThread(lldb::tid_t tid) {
1818
auto it = m_thread_timers.find(tid);
1919
if (it == m_thread_timers.end())
20-
it = m_thread_timers.try_emplace(tid, ThreadTaskTimer{}).first;
20+
it = m_thread_timers.try_emplace(tid, ScopedTaskTimer{}).first;
2121
return it->second;
2222
}
23+
24+
ScopedTaskTimer &TaskTimer::ForGlobal() { return m_global_timer; }

lldb/source/Plugins/Trace/intel-pt/TaskTimer.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ namespace lldb_private {
2222
namespace trace_intel_pt {
2323

2424
/// Class used to track the duration of long running tasks related to a single
25-
/// thread for reporting.
26-
class ThreadTaskTimer {
25+
/// scope for reporting.
26+
class ScopedTaskTimer {
2727
public:
2828
/// Execute the given \p task and record its duration.
2929
///
@@ -63,10 +63,15 @@ class TaskTimer {
6363
public:
6464
/// \return
6565
/// The timer object for the given thread.
66-
ThreadTaskTimer &ForThread(lldb::tid_t tid);
66+
ScopedTaskTimer &ForThread(lldb::tid_t tid);
67+
68+
/// \return
69+
/// The timer object for global tasks.
70+
ScopedTaskTimer &ForGlobal();
6771

6872
private:
69-
llvm::DenseMap<lldb::tid_t, ThreadTaskTimer> m_thread_timers;
73+
llvm::DenseMap<lldb::tid_t, ScopedTaskTimer> m_thread_timers;
74+
ScopedTaskTimer m_global_timer;
7075
};
7176

7277
} // namespace trace_intel_pt

0 commit comments

Comments
 (0)