summaryrefslogtreecommitdiff
path: root/simpleperf/record.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'simpleperf/record.cpp')
-rw-r--r--simpleperf/record.cpp25
1 files changed, 25 insertions, 0 deletions
diff --git a/simpleperf/record.cpp b/simpleperf/record.cpp
index 65e98ea6..f3548150 100644
--- a/simpleperf/record.cpp
+++ b/simpleperf/record.cpp
@@ -594,6 +594,31 @@ void SampleRecord::ReplaceRegAndStackWithCallChain(
*reinterpret_cast<uint64_t*>(p) = callchain_data.ip_nr;
}
+size_t SampleRecord::ExcludeKernelCallChain() {
+ size_t user_callchain_length = 0u;
+ if (sample_type & PERF_SAMPLE_CALLCHAIN) {
+ size_t i;
+ for (i = 0; i < callchain_data.ip_nr; ++i) {
+ if (callchain_data.ips[i] == PERF_CONTEXT_USER) {
+ i++;
+ if (i < callchain_data.ip_nr) {
+ ip_data.ip = callchain_data.ips[i];
+ if (sample_type & PERF_SAMPLE_IP) {
+ *reinterpret_cast<uint64_t*>(const_cast<char*>(binary_ + header_size())) = ip_data.ip;
+ }
+ header.misc = (header.misc & ~PERF_RECORD_MISC_KERNEL) | PERF_RECORD_MISC_USER;
+ reinterpret_cast<perf_event_header*>(const_cast<char*>(binary_))->misc = header.misc;
+ }
+ break;
+ } else {
+ const_cast<uint64_t*>(callchain_data.ips)[i] = PERF_CONTEXT_USER;
+ }
+ }
+ user_callchain_length = callchain_data.ip_nr - i;
+ }
+ return user_callchain_length;
+}
+
void SampleRecord::DumpData(size_t indent) const {
PrintIndented(indent, "sample_type: 0x%" PRIx64 "\n", sample_type);
if (sample_type & PERF_SAMPLE_IP) {