Skip to content

Commit 3c8c213

Browse files
committed
Simpleperf: support dwarf callgraph in report command.
Use libbacktrace for stack unwinding. Bug: 22229391 Change-Id: Iab35cdb52936c65c4728e23423ded83050f1db76
1 parent 260e7e2 commit 3c8c213

File tree

14 files changed

+408
-74
lines changed

14 files changed

+408
-74
lines changed

simpleperf/Android.mk

Lines changed: 99 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,40 @@
1616

1717
LOCAL_PATH := $(call my-dir)
1818

19-
simpleperf_common_cppflags := -std=c++11 -Wall -Wextra -Werror -Wunused
19+
simpleperf_common_cppflags := -std=c++11 -Wall -Wextra -Werror -Wunused \
2020

21-
simpleperf_host_common_cppflags := $(simpleperf_common_cppflags) \
22-
-DUSE_BIONIC_UAPI_HEADERS -I bionic/libc/kernel \
21+
simpleperf_cppflags_target := $(simpleperf_common_cppflags) \
2322

24-
simpleperf_host_darwin_cppflags := $(simpleperf_host_common_cppflags) \
25-
-I $(LOCAL_PATH)/darwin_support \
23+
simpleperf_cppflags_host := $(simpleperf_common_cppflags) \
24+
-DUSE_BIONIC_UAPI_HEADERS -I bionic/libc/kernel \
2625

27-
simpleperf_common_shared_libraries := \
26+
simpleperf_cppflags_host_linux := $(simpleperf_cppflags_host) \
27+
28+
simpleperf_cppflags_host_darwin := $(simpleperf_cppflags_host) \
29+
-I $(LOCAL_PATH)/darwin_support/include \
30+
31+
LLVM_ROOT_PATH := external/llvm
32+
include $(LLVM_ROOT_PATH)/llvm.mk
33+
34+
simpleperf_shared_libraries_target := \
35+
libbacktrace \
2836
libbase \
2937
libLLVM \
3038

31-
LLVM_ROOT_PATH := external/llvm
39+
simpleperf_shared_libraries_host_linux := \
40+
libbacktrace \
41+
libbase \
42+
43+
simpleperf_shared_libraries_host_darwin := \
44+
libbase \
45+
libLLVM \
46+
47+
simpleperf_ldlibs_host_linux := -lrt \
48+
3249

3350
# libsimpleperf
3451
# =========================================================
35-
libsimpleperf_common_src_files := \
52+
libsimpleperf_src_files := \
3653
callchain.cpp \
3754
cmd_dumprecord.cpp \
3855
cmd_help.cpp \
@@ -49,113 +66,129 @@ libsimpleperf_common_src_files := \
4966
thread_tree.cpp \
5067
utils.cpp \
5168

52-
libsimpleperf_src_files := \
53-
$(libsimpleperf_common_src_files) \
69+
libsimpleperf_src_files_linux := \
5470
cmd_list.cpp \
5571
cmd_record.cpp \
5672
cmd_stat.cpp \
73+
dwarf_unwind.cpp \
5774
environment.cpp \
5875
event_fd.cpp \
5976
event_selection_set.cpp \
6077
record_file_writer.cpp \
6178
workload.cpp \
6279

63-
libsimpleperf_darwin_src_files := \
64-
$(libsimpleperf_common_src_files) \
65-
environment_fake.cpp \
80+
libsimpleperf_src_files_darwin := \
81+
darwin_support/darwin_support.cpp \
6682

83+
# libsimpleperf target
6784
include $(CLEAR_VARS)
6885
LOCAL_CLANG := true
69-
LOCAL_CPPFLAGS := $(simpleperf_common_cppflags)
70-
LOCAL_SRC_FILES := $(libsimpleperf_src_files)
71-
LOCAL_SHARED_LIBRARIES := $(simpleperf_common_shared_libraries)
86+
LOCAL_CPPFLAGS := $(simpleperf_cppflags_target)
87+
LOCAL_SRC_FILES := \
88+
$(libsimpleperf_src_files) \
89+
$(libsimpleperf_src_files_linux) \
90+
91+
LOCAL_SHARED_LIBRARIES := $(simpleperf_shared_libraries_target)
92+
LOCAL_MULTILIB := first
7293
LOCAL_MODULE := libsimpleperf
7394
LOCAL_MODULE_TAGS := debug
7495
LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
75-
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
76-
include $(LLVM_ROOT_PATH)/llvm.mk
7796
include $(LLVM_DEVICE_BUILD_MK)
7897
include $(BUILD_STATIC_LIBRARY)
7998

99+
# libsimpleperf linux host
80100
ifeq ($(HOST_OS),linux)
81101
include $(CLEAR_VARS)
82102
LOCAL_CLANG := true
83-
LOCAL_CPPFLAGS := $(simpleperf_host_common_cppflags)
84-
LOCAL_SRC_FILES := $(libsimpleperf_src_files)
85-
LOCAL_SHARED_LIBRARIES := $(simpleperf_common_shared_libraries)
86-
LOCAL_LDLIBS := -lrt
103+
LOCAL_CPPFLAGS := $(simpleperf_cppflags_host_linux)
104+
LOCAL_SRC_FILES := \
105+
$(libsimpleperf_src_files) \
106+
$(libsimpleperf_src_files_linux) \
107+
108+
LOCAL_SHARED_LIBRARIES := $(simpleperf_shared_libraries_host_linux)
109+
LOCAL_LDLIBS := $(simpleperf_ldlibs_host_linux)
110+
LOCAL_MULTILIB := first
87111
LOCAL_MODULE := libsimpleperf
88112
LOCAL_MODULE_TAGS := optional
89-
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
90-
include $(LLVM_ROOT_PATH)/llvm.mk
91113
include $(LLVM_HOST_BUILD_MK)
92114
include $(BUILD_HOST_STATIC_LIBRARY)
93115
endif
94116

117+
# libsimpleperf darwin host
95118
ifeq ($(HOST_OS),darwin)
96119
include $(CLEAR_VARS)
97120
LOCAL_CLANG := true
98-
LOCAL_CPPFLAGS := $(simpleperf_host_darwin_cppflags)
99-
LOCAL_SRC_FILES := $(libsimpleperf_darwin_src_files)
100-
LOCAL_SHARED_LIBRARIES := $(simpleperf_common_shared_libraries)
121+
LOCAL_CPPFLAGS := $(simpleperf_cppflags_host_darwin)
122+
LOCAL_SRC_FILES := \
123+
$(libsimpleperf_src_files) \
124+
$(libsimpleperf_src_files_darwin) \
125+
126+
LOCAL_SHARED_LIBRARIES := $(simpleperf_shared_libraries_host_darwin)
127+
LOCAL_MULTILIB := first
101128
LOCAL_MODULE := libsimpleperf
102129
LOCAL_MODULE_TAGS := optional
103-
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
104-
include $(LLVM_ROOT_PATH)/llvm.mk
105130
include $(LLVM_HOST_BUILD_MK)
106131
include $(BUILD_HOST_SHARED_LIBRARY)
107132
endif
108133

134+
109135
# simpleperf
110136
# =========================================================
137+
138+
# simpleperf target
111139
include $(CLEAR_VARS)
112140
LOCAL_CLANG := true
113-
LOCAL_CPPFLAGS := $(simpleperf_common_cppflags)
141+
LOCAL_CPPFLAGS := $(simpleperf_cppflags_target)
114142
LOCAL_SRC_FILES := main.cpp
115143
LOCAL_WHOLE_STATIC_LIBRARIES := libsimpleperf
116-
LOCAL_SHARED_LIBRARIES := $(simpleperf_common_shared_libraries)
144+
LOCAL_SHARED_LIBRARIES := $(simpleperf_shared_libraries_target)
145+
LOCAL_MULTILIB := first
117146
LOCAL_MODULE := simpleperf
118147
LOCAL_MODULE_TAGS := debug
119148
LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
120-
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
121149
include $(BUILD_EXECUTABLE)
122150

151+
# simpleperf linux host
123152
ifeq ($(HOST_OS),linux)
124153
include $(CLEAR_VARS)
125154
LOCAL_CLANG := true
126-
LOCAL_CPPFLAGS := $(simpleperf_host_common_cppflags)
155+
LOCAL_CPPFLAGS := $(simpleperf_cppflags_host_linux)
127156
LOCAL_SRC_FILES := main.cpp
128157
LOCAL_WHOLE_STATIC_LIBRARIES := libsimpleperf
129-
LOCAL_SHARED_LIBRARIES := $(simpleperf_common_shared_libraries)
130-
LOCAL_LDLIBS := -lrt
158+
LOCAL_SHARED_LIBRARIES := $(simpleperf_shared_libraries_host_linux)
159+
LOCAL_MULTILIB := first
160+
LOCAL_LDLIBS := $(simpleperf_ldlibs_host_linux)
131161
LOCAL_MODULE := simpleperf
132162
LOCAL_MODULE_TAGS := optional
133-
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
134163
include $(BUILD_HOST_EXECUTABLE)
135164
endif
136165

166+
# simpleperf darwin host
137167
ifeq ($(HOST_OS),darwin)
138168
include $(CLEAR_VARS)
139169
LOCAL_CLANG := true
140-
LOCAL_CPPFLAGS := $(simpleperf_host_darwin_cppflags)
170+
LOCAL_CPPFLAGS := $(simpleperf_cppflags_host_darwin)
141171
LOCAL_SRC_FILES := main.cpp
142-
LOCAL_SHARED_LIBRARIES := libsimpleperf $(simpleperf_common_shared_libraries)
172+
LOCAL_SHARED_LIBRARIES := \
173+
libsimpleperf \
174+
$(simpleperf_shared_libraries_host_darwin) \
175+
176+
LOCAL_MULTILIB := first
143177
LOCAL_MODULE := simpleperf
144178
LOCAL_MODULE_TAGS := optional
145-
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
146179
include $(BUILD_HOST_EXECUTABLE)
147180
endif
148181

182+
149183
# simpleperf_unit_test
150184
# =========================================================
151-
simpleperf_unit_test_common_src_files := \
185+
simpleperf_unit_test_src_files := \
152186
command_test.cpp \
153187
gtest_main.cpp \
154188
record_test.cpp \
155189
sample_tree_test.cpp \
156190

157-
simpleperf_unit_test_src_files := \
158-
$(simpleperf_unit_test_common_src_files) \
191+
simpleperf_unit_test_src_files_linux := \
159192
cmd_dumprecord_test.cpp \
160193
cmd_list_test.cpp \
161194
cmd_record_test.cpp \
@@ -167,38 +200,50 @@ simpleperf_unit_test_src_files := \
167200
record_file_test.cpp \
168201
workload_test.cpp \
169202

203+
# simpleperf_unit_test target
170204
include $(CLEAR_VARS)
171205
LOCAL_CLANG := true
172-
LOCAL_CPPFLAGS := $(simpleperf_common_cppflags)
173-
LOCAL_SRC_FILES := $(simpleperf_unit_test_src_files)
206+
LOCAL_CPPFLAGS := $(simpleperf_cppflags_target)
207+
LOCAL_SRC_FILES := \
208+
$(simpleperf_unit_test_src_files) \
209+
$(simpleperf_unit_test_src_files_linux) \
210+
174211
LOCAL_WHOLE_STATIC_LIBRARIES := libsimpleperf
175-
LOCAL_SHARED_LIBRARIES := $(simpleperf_common_shared_libraries)
212+
LOCAL_SHARED_LIBRARIES := $(simpleperf_shared_libraries_target)
213+
LOCAL_MULTILIB := first
176214
LOCAL_MODULE := simpleperf_unit_test
177215
LOCAL_MODULE_TAGS := optional
178-
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
179216
include $(BUILD_NATIVE_TEST)
180217

218+
# simpleperf_unit_test linux host
181219
ifeq ($(HOST_OS),linux)
182220
include $(CLEAR_VARS)
183221
LOCAL_CLANG := true
184-
LOCAL_CPPFLAGS := $(simpleperf_host_common_cppflags)
185-
LOCAL_SRC_FILES := $(simpleperf_unit_test_src_files)
222+
LOCAL_CPPFLAGS := $(simpleperf_cppflags_host_linux)
223+
LOCAL_SRC_FILES := \
224+
$(simpleperf_unit_test_src_files) \
225+
$(simpleperf_unit_test_src_files_linux) \
226+
186227
LOCAL_WHOLE_STATIC_LIBRARIES := libsimpleperf
187-
LOCAL_SHARED_LIBRARIES := $(simpleperf_common_shared_libraries)
228+
LOCAL_SHARED_LIBRARIES := $(simpleperf_shared_libraries_host_linux)
229+
LOCAL_MULTILIB := first
188230
LOCAL_MODULE := simpleperf_unit_test
189231
LOCAL_MODULE_TAGS := optional
190-
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
191232
include $(BUILD_HOST_NATIVE_TEST)
192233
endif
193234

235+
# simpleperf_unit_test darwin host
194236
ifeq ($(HOST_OS),darwin)
195237
include $(CLEAR_VARS)
196238
LOCAL_CLANG := true
197-
LOCAL_CPPFLAGS := $(simpleperf_host_darwin_cppflags)
198-
LOCAL_SRC_FILES := $(simpleperf_unit_test_common_src_files)
199-
LOCAL_SHARED_LIBRARIES := libsimpleperf $(simpleperf_common_shared_libraries)
239+
LOCAL_CPPFLAGS := $(simpleperf_cppflags_host_darwin)
240+
LOCAL_SRC_FILES := $(simpleperf_unit_test_src_files)
241+
LOCAL_SHARED_LIBRARIES := \
242+
libsimpleperf \
243+
$(simpleperf_shared_libraries_host_darwin) \
244+
245+
LOCAL_MULTILIB := first
200246
LOCAL_MODULE := simpleperf_unit_test
201247
LOCAL_MODULE_TAGS := optional
202-
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
203248
include $(BUILD_HOST_NATIVE_TEST)
204249
endif

simpleperf/cmd_report.cpp

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include <base/strings.h>
3030

3131
#include "command.h"
32+
#include "dwarf_unwind.h"
3233
#include "environment.h"
3334
#include "event_attr.h"
3435
#include "event_type.h"
@@ -532,10 +533,28 @@ void ReportCommand::ProcessSampleRecord(const SampleRecord& r) {
532533
if (sample == nullptr) {
533534
return;
534535
}
535-
if (accumulate_callchain_ && (r.sample_type & PERF_SAMPLE_CALLCHAIN) != 0) {
536+
if (accumulate_callchain_) {
537+
std::vector<uint64_t> ips;
538+
if (r.sample_type & PERF_SAMPLE_CALLCHAIN) {
539+
ips.insert(ips.end(), r.callchain_data.ips.begin(), r.callchain_data.ips.end());
540+
}
541+
// Use stack_user_data.data.size() instead of stack_user_data.dyn_size, to make up for
542+
// the missing kernel patch in N9. See b/22612370.
543+
if ((r.sample_type & PERF_SAMPLE_REGS_USER) && (r.regs_user_data.reg_mask != 0) &&
544+
(r.sample_type & PERF_SAMPLE_STACK_USER) && (!r.stack_user_data.data.empty())) {
545+
RegSet regs = CreateRegSet(r.regs_user_data.reg_mask, r.regs_user_data.regs);
546+
std::vector<char> stack(r.stack_user_data.data.begin(),
547+
r.stack_user_data.data.begin() + r.stack_user_data.data.size());
548+
std::vector<uint64_t> unwind_ips = UnwindCallChain(*sample->thread, regs, stack);
549+
if (!unwind_ips.empty()) {
550+
ips.push_back(PERF_CONTEXT_USER);
551+
ips.insert(ips.end(), unwind_ips.begin(), unwind_ips.end());
552+
}
553+
}
554+
536555
std::vector<SampleEntry*> callchain;
537556
callchain.push_back(sample);
538-
const std::vector<uint64_t>& ips = r.callchain_data.ips;
557+
539558
bool first_ip = true;
540559
for (auto& ip : ips) {
541560
if (ip >= PERF_CONTEXT_MAX) {
@@ -551,18 +570,19 @@ void ReportCommand::ProcessSampleRecord(const SampleRecord& r) {
551570
}
552571
} else {
553572
if (first_ip) {
573+
first_ip = false;
554574
// Remove duplication with sampled ip.
555575
if (ip == r.ip_data.ip) {
556576
continue;
557577
}
558-
first_ip = false;
559578
}
560579
SampleEntry* sample =
561580
sample_tree_->AddCallChainSample(r.tid_data.pid, r.tid_data.tid, ip, r.time_data.time,
562581
r.period_data.period, in_kernel, callchain);
563582
callchain.push_back(sample);
564583
}
565584
}
585+
566586
if (print_callgraph_) {
567587
std::set<SampleEntry*> added_set;
568588
if (!callgraph_show_callee_) {

simpleperf/cmd_report_test.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <gtest/gtest.h>
1818

1919
#include "command.h"
20+
#include "event_selection_set.h"
2021

2122
static std::unique_ptr<Command> RecordCmd() {
2223
return CreateCommandInstance("record");
@@ -81,8 +82,6 @@ TEST_F(ReportCommandTest, dso_filter_option) {
8182
ASSERT_TRUE(ReportCmd()->Run({"--dsos", "[kernel.kallsyms],/init"}));
8283
}
8384

84-
extern bool IsBranchSamplingSupported();
85-
8685
TEST(report_cmd, use_branch_address) {
8786
if (IsBranchSamplingSupported()) {
8887
ASSERT_TRUE(RecordCmd()->Run({"-b", "sleep", "1"}));
@@ -93,3 +92,13 @@ TEST(report_cmd, use_branch_address) {
9392
<< "This test does nothing as branch stack sampling is not supported on this device.";
9493
}
9594
}
95+
96+
TEST(report_cmd, dwarf_callgraph) {
97+
if (IsDwarfCallChainSamplingSupported()) {
98+
ASSERT_TRUE(RecordCmd()->Run({"-g", "-o", "perf_dwarf.data", "sleep", "1"}));
99+
ASSERT_TRUE(ReportCmd()->Run({"-g", "-i", "perf_dwarf.data"}));
100+
} else {
101+
GTEST_LOG_(INFO)
102+
<< "This test does nothing as dwarf callchain sampling is not supported on this device.";
103+
}
104+
}

0 commit comments

Comments
 (0)