summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ioshark/compile_ioshark.c2
-rw-r--r--ioshark/compile_ioshark_subr.c2
-rw-r--r--ioshark/convert_format.c2
-rw-r--r--ioshark/dump_ioshark_filenames.c2
-rw-r--r--ioshark/ioshark_bench.c2
-rw-r--r--ioshark/ioshark_bench_mmap.c2
-rw-r--r--libfec/Android.bp2
-rw-r--r--simpleperf/Android.bp23
-rw-r--r--simpleperf/IOEventLoop.h1
-rw-r--r--simpleperf/JITDebugReader.cpp78
-rw-r--r--simpleperf/JITDebugReader.h27
-rw-r--r--simpleperf/doc/collect_etm_data_for_autofdo.md30
-rw-r--r--simpleperf/environment.h3
-rwxr-xr-xsimpleperf/scripts/annotate.py25
-rwxr-xr-xsimpleperf/scripts/bin/android/arm/simpleperfbin2807668 -> 2812664 bytes
-rwxr-xr-xsimpleperf/scripts/bin/android/arm64/simpleperfbin3810832 -> 3819224 bytes
-rwxr-xr-xsimpleperf/scripts/bin/android/x86/simpleperfbin4372260 -> 4386820 bytes
-rwxr-xr-xsimpleperf/scripts/bin/android/x86_64/simpleperfbin4249312 -> 4244008 bytes
-rwxr-xr-xsimpleperf/scripts/bin/darwin/x86_64/libsimpleperf_report.dylibbin13978839 -> 13980215 bytes
-rwxr-xr-xsimpleperf/scripts/bin/darwin/x86_64/simpleperfbin13918013 -> 13902701 bytes
-rwxr-xr-xsimpleperf/scripts/bin/linux/x86_64/libsimpleperf_report.sobin7219712 -> 7208384 bytes
-rwxr-xr-xsimpleperf/scripts/bin/linux/x86_64/simpleperfbin7193024 -> 7181056 bytes
-rwxr-xr-xsimpleperf/scripts/bin/windows/x86_64/libsimpleperf_report.dllbin5598720 -> 5583872 bytes
-rwxr-xr-xsimpleperf/scripts/bin/windows/x86_64/simpleperf.exebin4654080 -> 4638208 bytes
-rwxr-xr-xsimpleperf/scripts/gecko_profile_generator.py13
-rwxr-xr-xsimpleperf/scripts/inferno/inferno.py6
-rwxr-xr-xsimpleperf/scripts/pprof_proto_generator.py20
-rwxr-xr-xsimpleperf/scripts/report_html.py9
-rwxr-xr-xsimpleperf/scripts/report_sample.py12
-rw-r--r--simpleperf/scripts/simpleperf_report_lib.py10
-rw-r--r--simpleperf/scripts/simpleperf_utils.py48
-rwxr-xr-xsimpleperf/scripts/stackcollapse.py15
-rwxr-xr-xsimpleperf/scripts/test/do_test.py13
-rw-r--r--simpleperf/scripts/test/pprof_proto_generator_test.py2
-rw-r--r--simpleperf/scripts/test/report_lib_test.py29
-rw-r--r--verity/fec/Android.bp5
36 files changed, 186 insertions, 197 deletions
diff --git a/ioshark/compile_ioshark.c b/ioshark/compile_ioshark.c
index 13755299..fe9085cf 100644
--- a/ioshark/compile_ioshark.c
+++ b/ioshark/compile_ioshark.c
@@ -22,7 +22,7 @@
#include <signal.h>
#include <string.h>
#include <sys/stat.h>
-#include <sys/errno.h>
+#include <errno.h>
#include <fcntl.h>
#include <ctype.h>
#include "ioshark.h"
diff --git a/ioshark/compile_ioshark_subr.c b/ioshark/compile_ioshark_subr.c
index 43fb2544..6fc301cc 100644
--- a/ioshark/compile_ioshark_subr.c
+++ b/ioshark/compile_ioshark_subr.c
@@ -21,7 +21,7 @@
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
-#include <sys/errno.h>
+#include <errno.h>
#include "ioshark.h"
#include "compile_ioshark.h"
#include <endian.h>
diff --git a/ioshark/convert_format.c b/ioshark/convert_format.c
index 3436ca77..989bfcb8 100644
--- a/ioshark/convert_format.c
+++ b/ioshark/convert_format.c
@@ -22,7 +22,7 @@
#include <signal.h>
#include <string.h>
#include <sys/stat.h>
-#include <sys/errno.h>
+#include <errno.h>
#include <fcntl.h>
#include <ctype.h>
#include <endian.h>
diff --git a/ioshark/dump_ioshark_filenames.c b/ioshark/dump_ioshark_filenames.c
index c082c274..a28ab790 100644
--- a/ioshark/dump_ioshark_filenames.c
+++ b/ioshark/dump_ioshark_filenames.c
@@ -21,7 +21,7 @@
#include <signal.h>
#include <string.h>
#include <sys/stat.h>
-#include <sys/errno.h>
+#include <errno.h>
#include <fcntl.h>
#include <ctype.h>
#include "ioshark.h"
diff --git a/ioshark/ioshark_bench.c b/ioshark/ioshark_bench.c
index e44a2a53..9540b741 100644
--- a/ioshark/ioshark_bench.c
+++ b/ioshark/ioshark_bench.c
@@ -22,7 +22,7 @@
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
-#include <sys/errno.h>
+#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <assert.h>
diff --git a/ioshark/ioshark_bench_mmap.c b/ioshark/ioshark_bench_mmap.c
index e8b3acce..3b37fbf6 100644
--- a/ioshark/ioshark_bench_mmap.c
+++ b/ioshark/ioshark_bench_mmap.c
@@ -23,7 +23,7 @@
#include <string.h>
#include <pthread.h>
#include <sys/stat.h>
-#include <sys/errno.h>
+#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <assert.h>
diff --git a/libfec/Android.bp b/libfec/Android.bp
index c19f6a90..302d8e40 100644
--- a/libfec/Android.bp
+++ b/libfec/Android.bp
@@ -58,7 +58,7 @@ cc_defaults {
"-DFEC_NO_KLOG",
],
},
- linux_glibc: {
+ host_linux: {
sanitize: {
misc_undefined: ["integer"],
},
diff --git a/simpleperf/Android.bp b/simpleperf/Android.bp
index b5edda80..58943931 100644
--- a/simpleperf/Android.bp
+++ b/simpleperf/Android.bp
@@ -131,6 +131,9 @@ cc_defaults {
linux_glibc_x86_64: {
stl: "libc++_static",
},
+ linux_musl_x86_64: {
+ stl: "libc++_static",
+ },
windows: {
enabled: true,
stl: "libc++_static",
@@ -434,6 +437,16 @@ cc_binary {
dir: "simpleperf/linux/x86_64",
},
},
+ linux_musl_x86: {
+ dist: {
+ dir: "simpleperf/linux_musl/x86",
+ },
+ },
+ linux_musl_x86_64: {
+ dist: {
+ dir: "simpleperf/linux_musl/x86_64",
+ },
+ },
windows_x86: {
dist: {
dir: "simpleperf/windows/x86",
@@ -518,6 +531,16 @@ cc_library_shared {
dir: "simpleperf/linux/x86_64",
},
},
+ linux_musl_x86: {
+ dist: {
+ dir: "simpleperf/linux_musl/x86",
+ },
+ },
+ linux_musl_x86_64: {
+ dist: {
+ dir: "simpleperf/linux_musl/x86_64",
+ },
+ },
windows_x86: {
dist: {
dir: "simpleperf/windows/x86",
diff --git a/simpleperf/IOEventLoop.h b/simpleperf/IOEventLoop.h
index f0192969..0bbbbd01 100644
--- a/simpleperf/IOEventLoop.h
+++ b/simpleperf/IOEventLoop.h
@@ -18,6 +18,7 @@
#define SIMPLE_PERF_IOEVENT_LOOP_H_
#include <stdint.h>
+#include <sys/time.h>
#include <time.h>
#include <functional>
diff --git a/simpleperf/JITDebugReader.cpp b/simpleperf/JITDebugReader.cpp
index 52db2959..28058940 100644
--- a/simpleperf/JITDebugReader.cpp
+++ b/simpleperf/JITDebugReader.cpp
@@ -411,17 +411,15 @@ bool JITDebugReader::InitializeProcess(Process& process) {
if (art_lib_path.empty()) {
return false;
}
- process.is_64bit = art_lib_path.find("lib64") != std::string::npos;
// 2. Read libart.so to find the addresses of __jit_debug_descriptor and __dex_debug_descriptor.
- const DescriptorsLocation* location = GetDescriptorsLocation(art_lib_path, process.is_64bit);
+ const DescriptorsLocation* location = GetDescriptorsLocation(art_lib_path);
if (location == nullptr) {
return false;
}
- process.descriptors_addr = location->relative_addr + min_vaddr_in_memory;
- process.descriptors_size = location->size;
- process.jit_descriptor_offset = location->jit_descriptor_offset;
- process.dex_descriptor_offset = location->dex_descriptor_offset;
+ process.is_64bit = location->is_64bit;
+ process.jit_descriptor_addr = location->jit_descriptor_addr + min_vaddr_in_memory;
+ process.dex_descriptor_addr = location->dex_descriptor_addr + min_vaddr_in_memory;
for (auto& map : thread_mmaps) {
if (StartsWith(map.name, kJITZygoteCacheMmapPrefix)) {
@@ -434,10 +432,10 @@ bool JITDebugReader::InitializeProcess(Process& process) {
}
const JITDebugReader::DescriptorsLocation* JITDebugReader::GetDescriptorsLocation(
- const std::string& art_lib_path, bool is_64bit) {
+ const std::string& art_lib_path) {
auto it = descriptors_location_cache_.find(art_lib_path);
if (it != descriptors_location_cache_.end()) {
- return it->second.relative_addr == 0u ? nullptr : &it->second;
+ return it->second.jit_descriptor_addr == 0u ? nullptr : &it->second;
}
DescriptorsLocation& location = descriptors_location_cache_[art_lib_path];
@@ -469,18 +467,9 @@ const JITDebugReader::DescriptorsLocation* JITDebugReader::GetDescriptorsLocatio
if (jit_addr == 0u || dex_addr == 0u) {
return nullptr;
}
- location.relative_addr = std::min(jit_addr, dex_addr);
- location.size = std::max(jit_addr, dex_addr) +
- (is_64bit ? sizeof(JITDescriptor64) : sizeof(JITDescriptor32)) -
- location.relative_addr;
- if (location.size >= 4096u) {
- PLOG(WARNING) << "The descriptors_size is unexpected large: " << location.size;
- }
- if (descriptors_buf_.size() < location.size) {
- descriptors_buf_.resize(location.size);
- }
- location.jit_descriptor_offset = jit_addr - location.relative_addr;
- location.dex_descriptor_offset = dex_addr - location.relative_addr;
+ location.is_64bit = elf->Is64Bit();
+ location.jit_descriptor_addr = jit_addr;
+ location.dex_descriptor_addr = dex_addr;
return &location;
}
@@ -505,14 +494,40 @@ bool JITDebugReader::ReadRemoteMem(Process& process, uint64_t remote_addr, uint6
bool JITDebugReader::ReadDescriptors(Process& process, Descriptor* jit_descriptor,
Descriptor* dex_descriptor) {
- if (!ReadRemoteMem(process, process.descriptors_addr, process.descriptors_size,
- descriptors_buf_.data())) {
+ if (process.is_64bit) {
+ return ReadDescriptorsImpl<JITDescriptor64>(process, jit_descriptor, dex_descriptor);
+ }
+ return ReadDescriptorsImpl<JITDescriptor32>(process, jit_descriptor, dex_descriptor);
+}
+
+template <typename DescriptorT>
+bool JITDebugReader::ReadDescriptorsImpl(Process& process, Descriptor* jit_descriptor,
+ Descriptor* dex_descriptor) {
+ DescriptorT raw_jit_descriptor;
+ DescriptorT raw_dex_descriptor;
+ iovec local_iovs[2];
+ local_iovs[0].iov_base = &raw_jit_descriptor;
+ local_iovs[0].iov_len = sizeof(DescriptorT);
+ local_iovs[1].iov_base = &raw_dex_descriptor;
+ local_iovs[1].iov_len = sizeof(DescriptorT);
+ iovec remote_iovs[2];
+ remote_iovs[0].iov_base =
+ reinterpret_cast<void*>(static_cast<uintptr_t>(process.jit_descriptor_addr));
+ remote_iovs[0].iov_len = sizeof(DescriptorT);
+ remote_iovs[1].iov_base =
+ reinterpret_cast<void*>(static_cast<uintptr_t>(process.dex_descriptor_addr));
+ remote_iovs[1].iov_len = sizeof(DescriptorT);
+ ssize_t result = process_vm_readv(process.pid, local_iovs, 2, remote_iovs, 2, 0);
+ if (static_cast<size_t>(result) != sizeof(DescriptorT) * 2) {
+ PLOG(DEBUG) << "ReadDescriptor(pid " << process.pid << ", jit_addr " << std::hex
+ << process.jit_descriptor_addr << ", dex_addr " << process.dex_descriptor_addr
+ << ") failed";
+ process.died = true;
return false;
}
- if (!LoadDescriptor(process.is_64bit, &descriptors_buf_[process.jit_descriptor_offset],
- jit_descriptor) ||
- !LoadDescriptor(process.is_64bit, &descriptors_buf_[process.dex_descriptor_offset],
- dex_descriptor)) {
+
+ if (!ParseDescriptor(raw_jit_descriptor, jit_descriptor) ||
+ !ParseDescriptor(raw_dex_descriptor, dex_descriptor)) {
return false;
}
jit_descriptor->type = DescriptorType::kJIT;
@@ -520,17 +535,8 @@ bool JITDebugReader::ReadDescriptors(Process& process, Descriptor* jit_descripto
return true;
}
-bool JITDebugReader::LoadDescriptor(bool is_64bit, const char* data, Descriptor* descriptor) {
- if (is_64bit) {
- return LoadDescriptorImpl<JITDescriptor64>(data, descriptor);
- }
- return LoadDescriptorImpl<JITDescriptor32>(data, descriptor);
-}
-
template <typename DescriptorT>
-bool JITDebugReader::LoadDescriptorImpl(const char* data, Descriptor* descriptor) {
- DescriptorT raw_descriptor;
- MoveFromBinaryFormat(raw_descriptor, data);
+bool JITDebugReader::ParseDescriptor(const DescriptorT& raw_descriptor, Descriptor* descriptor) {
if (!raw_descriptor.Valid()) {
return false;
}
diff --git a/simpleperf/JITDebugReader.h b/simpleperf/JITDebugReader.h
index 72f3790b..b9e984d5 100644
--- a/simpleperf/JITDebugReader.h
+++ b/simpleperf/JITDebugReader.h
@@ -162,13 +162,10 @@ class JITDebugReader {
bool initialized = false;
bool died = false;
bool is_64bit = false;
- // The jit descriptor and dex descriptor can be read in one process_vm_readv() call.
- uint64_t descriptors_addr = 0;
- uint64_t descriptors_size = 0;
- // offset relative to descriptors_addr
- uint64_t jit_descriptor_offset = 0;
- // offset relative to descriptors_addr
- uint64_t dex_descriptor_offset = 0;
+ // remote addr of jit descriptor
+ uint64_t jit_descriptor_addr = 0;
+ // remote addr of dex descriptor
+ uint64_t dex_descriptor_addr = 0;
// The state we know about the remote jit debug descriptor.
Descriptor last_jit_descriptor;
@@ -181,10 +178,9 @@ class JITDebugReader {
// The location of descriptors in libart.so.
struct DescriptorsLocation {
- uint64_t relative_addr = 0;
- uint64_t size = 0;
- uint64_t jit_descriptor_offset = 0;
- uint64_t dex_descriptor_offset = 0;
+ bool is_64bit = false;
+ uint64_t jit_descriptor_addr = 0;
+ uint64_t dex_descriptor_addr = 0;
};
bool ReadProcess(Process& process, std::vector<JITDebugInfo>* debug_info);
@@ -192,12 +188,14 @@ class JITDebugReader {
std::vector<JITDebugInfo>* debug_info);
bool IsDescriptorChanged(Process& process, Descriptor& old_descriptor);
bool InitializeProcess(Process& process);
- const DescriptorsLocation* GetDescriptorsLocation(const std::string& art_lib_path, bool is_64bit);
+ const DescriptorsLocation* GetDescriptorsLocation(const std::string& art_lib_path);
bool ReadRemoteMem(Process& process, uint64_t remote_addr, uint64_t size, void* data);
bool ReadDescriptors(Process& process, Descriptor* jit_descriptor, Descriptor* dex_descriptor);
- bool LoadDescriptor(bool is_64bit, const char* data, Descriptor* descriptor);
template <typename DescriptorT>
- bool LoadDescriptorImpl(const char* data, Descriptor* descriptor);
+ bool ReadDescriptorsImpl(Process& process, Descriptor* jit_descriptor,
+ Descriptor* dex_descriptor);
+ template <typename DescriptorT>
+ bool ParseDescriptor(const DescriptorT& raw_descriptor, Descriptor* descriptor);
bool ReadNewCodeEntries(Process& process, const Descriptor& descriptor,
uint64_t last_action_timestamp, uint32_t read_entry_limit,
@@ -226,7 +224,6 @@ class JITDebugReader {
// All monitored processes
std::unordered_map<pid_t, Process> processes_;
std::unordered_map<std::string, DescriptorsLocation> descriptors_location_cache_;
- std::vector<char> descriptors_buf_;
std::priority_queue<JITDebugInfo, std::vector<JITDebugInfo>, std::greater<JITDebugInfo>>
debug_info_q_;
diff --git a/simpleperf/doc/collect_etm_data_for_autofdo.md b/simpleperf/doc/collect_etm_data_for_autofdo.md
index f9f5a158..145c0adf 100644
--- a/simpleperf/doc/collect_etm_data_for_autofdo.md
+++ b/simpleperf/doc/collect_etm_data_for_autofdo.md
@@ -94,7 +94,7 @@ Then we can use a.prof for PGO during compilation, via `-fprofile-sample-use=a.p
## Collect ETM data with a daemon
Android also has a daemon collecting ETM data periodically. It only runs on userdebug and eng
-devices. The source code is in `<aosp-top>/system/extras/profcollectd`.
+devices. The source code is in https://android.googlesource.com/platform/system/extras/+/master/profcollectd/.
## Support ETM in the kernel
@@ -107,21 +107,37 @@ The Coresight driver can be enabled by below kernel configs:
CONFIG_CORESIGHT=y
CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y
CONFIG_CORESIGHT_SOURCE_ETM4X=y
- CONFIG_CORESIGHT_DYNAMIC_REPLICATOR=y
```
-On Kernel 5.10+, we can build Coresight driver as kernel modules instead.
+On Kernel 5.10+, we recommend building Coresight driver as kernel modules. Because it works with
+GKI kernel.
-Android common kernel 5.10+ should have all the Coresight patches needed. And we have backported
-necessary Coresight patches to Android common kernel 4.14 and 4.19. Android common kernel 5.4
-misses a few patches. Please create an [ndk issue](https://github.com/android/ndk/issues) if you
-need ETM function on 5.4 kernel.
+```config
+ CONFIG_CORESIGHT=m
+ CONFIG_CORESIGHT_LINK_AND_SINK_TMC=m
+ CONFIG_CORESIGHT_SOURCE_ETM4X=m
+```
+
+Android common kernel 5.10+ should have all the Coresight patches needed to collect ETM data.
+Android common kernel 5.4 misses two patches. But by adding patches in
+https://android-review.googlesource.com/q/topic:test_etm_on_hikey960_5.4, we can collect ETM data
+on hikey960 with 5.4 kernel.
+For Android common kernel 4.14 and 4.19, we have backported all necessary Coresight patches.
Besides Coresight driver, we also need to add Coresight devices in device tree. An example is in
https://github.com/torvalds/linux/blob/master/arch/arm64/boot/dts/arm/juno-base.dtsi. There should
be a path flowing ETM data from ETM device through funnels, ETF and replicators, all the way to
ETR, which writes ETM data to system memory.
+One optional flag in ETM device tree is "arm,coresight-loses-context-with-cpu". It saves ETM
+registers when a CPU enters low power state. It may be needed to avoid
+"coresight_disclaim_device_unlocked" warning when doing system wide collection.
+
+One optional flag in ETR device tree is "arm,scatter-gather". Simpleperf requests 4M system memory
+for ETR to store ETM data. Without IOMMU, the memory needs to be contiguous. If the kernel can't
+fulfill the request, simpleperf will report out of memory error. Fortunately, we can use
+"arm,scatter-gather" flag to let ETR run in scatter gather mode, which uses non-contiguous memory.
+
## Enable ETM in the bootloader
Unless ARMv8.4 Self-hosted Trace extension is implemented, ETM is considered as an external debug
diff --git a/simpleperf/environment.h b/simpleperf/environment.h
index 1dd6952e..34ce7fa5 100644
--- a/simpleperf/environment.h
+++ b/simpleperf/environment.h
@@ -144,7 +144,8 @@ static inline uint64_t GetSystemClock() {
#if defined(__ANDROID__)
bool IsInAppUid();
-#else
+#endif
+#if !defined(__ANDROID__) && !defined(ANDROID_HOST_MUSL)
static inline int gettid() {
return syscall(__NR_gettid);
}
diff --git a/simpleperf/scripts/annotate.py b/simpleperf/scripts/annotate.py
index ecfb2fdb..7bf8fe92 100755
--- a/simpleperf/scripts/annotate.py
+++ b/simpleperf/scripts/annotate.py
@@ -146,7 +146,7 @@ class SourceFileAnnotator(object):
def __init__(self, config):
# check config variables
- config_names = ['perf_data_list', 'source_dirs', 'comm_filters', 'dso_filters', 'ndk_path']
+ config_names = ['perf_data_list', 'source_dirs', 'dso_filters', 'ndk_path']
for name in config_names:
if name not in config:
log_exit('config [%s] is missing' % name)
@@ -161,7 +161,6 @@ class SourceFileAnnotator(object):
self.config = config
self.symfs_dir = symfs_dir
self.kallsyms = kallsyms
- self.comm_filter = set(config['comm_filters']) if config.get('comm_filters') else None
self.dso_filter = set(config['dso_filters']) if config.get('dso_filters') else None
config['annotate_dest_dir'] = 'annotated_files'
@@ -193,16 +192,12 @@ class SourceFileAnnotator(object):
lib.SetSymfs(self.symfs_dir)
if self.kallsyms:
lib.SetKallsymsFile(self.kallsyms)
- if self.config.get('sample_filter'):
- lib.SetSampleFilter(self.config.get('sample_filter'))
lib.SetReportOptions(self.config['report_lib_options'])
while True:
sample = lib.GetNextSample()
if sample is None:
lib.Close()
break
- if not self._filter_sample(sample):
- continue
symbols = []
symbols.append(lib.GetSymbolOfCurrentSample())
callchain = lib.GetCallChainOfCurrentSample()
@@ -216,13 +211,6 @@ class SourceFileAnnotator(object):
self.addr2line.add_addr(symbol.dso_name, build_id, symbol.symbol_addr,
symbol.symbol_addr)
- def _filter_sample(self, sample):
- """Return true if the sample can be used."""
- if self.comm_filter:
- if sample.thread_comm not in self.comm_filter:
- return False
- return True
-
def _filter_symbol(self, symbol):
if not self.dso_filter or symbol.dso_name in self.dso_filter:
return True
@@ -242,16 +230,12 @@ class SourceFileAnnotator(object):
lib.SetSymfs(self.symfs_dir)
if self.kallsyms:
lib.SetKallsymsFile(self.kallsyms)
- if self.config.get('sample_filter'):
- lib.SetSampleFilter(self.config.get('sample_filter'))
lib.SetReportOptions(self.config['report_lib_options'])
while True:
sample = lib.GetNextSample()
if sample is None:
lib.Close()
break
- if not self._filter_sample(sample):
- continue
self._generate_periods_for_sample(lib, sample)
def _generate_periods_for_sample(self, lib, sample):
@@ -479,12 +463,9 @@ def main():
help='show raw period instead of percentage')
parser.add_argument('--summary-width', type=int, default=80, help='max width of summary file')
sample_filter_group = parser.add_argument_group('Sample filter options')
- parser.add_sample_filter_options(sample_filter_group)
- sample_filter_group.add_argument('--comm', nargs='+', action='append', help="""
- Use samples only in threads with selected names.""")
sample_filter_group.add_argument('--dso', nargs='+', action='append', help="""
Use samples only in selected binaries.""")
- parser.add_report_lib_options()
+ parser.add_report_lib_options(sample_filter_group=sample_filter_group)
args = parser.parse_args()
config = {}
@@ -492,12 +473,10 @@ def main():
if not config['perf_data_list']:
config['perf_data_list'].append('perf.data')
config['source_dirs'] = flatten_arg_list(args.source_dirs)
- config['comm_filters'] = flatten_arg_list(args.comm)
config['dso_filters'] = flatten_arg_list(args.dso)
config['ndk_path'] = args.ndk_path
config['raw_period'] = args.raw_period
config['summary_width'] = args.summary_width
- config['sample_filter'] = args.sample_filter
config['report_lib_options'] = args.report_lib_options
annotator = SourceFileAnnotator(config)
diff --git a/simpleperf/scripts/bin/android/arm/simpleperf b/simpleperf/scripts/bin/android/arm/simpleperf
index 5ccbd4f1..db2fde7f 100755
--- a/simpleperf/scripts/bin/android/arm/simpleperf
+++ b/simpleperf/scripts/bin/android/arm/simpleperf
Binary files differ
diff --git a/simpleperf/scripts/bin/android/arm64/simpleperf b/simpleperf/scripts/bin/android/arm64/simpleperf
index 862e4d93..785b6e33 100755
--- a/simpleperf/scripts/bin/android/arm64/simpleperf
+++ b/simpleperf/scripts/bin/android/arm64/simpleperf
Binary files differ
diff --git a/simpleperf/scripts/bin/android/x86/simpleperf b/simpleperf/scripts/bin/android/x86/simpleperf
index a78e0514..97a168d5 100755
--- a/simpleperf/scripts/bin/android/x86/simpleperf
+++ b/simpleperf/scripts/bin/android/x86/simpleperf
Binary files differ
diff --git a/simpleperf/scripts/bin/android/x86_64/simpleperf b/simpleperf/scripts/bin/android/x86_64/simpleperf
index 8872cf4a..c250c450 100755
--- a/simpleperf/scripts/bin/android/x86_64/simpleperf
+++ b/simpleperf/scripts/bin/android/x86_64/simpleperf
Binary files differ
diff --git a/simpleperf/scripts/bin/darwin/x86_64/libsimpleperf_report.dylib b/simpleperf/scripts/bin/darwin/x86_64/libsimpleperf_report.dylib
index 32631f67..191e51f8 100755
--- a/simpleperf/scripts/bin/darwin/x86_64/libsimpleperf_report.dylib
+++ b/simpleperf/scripts/bin/darwin/x86_64/libsimpleperf_report.dylib
Binary files differ
diff --git a/simpleperf/scripts/bin/darwin/x86_64/simpleperf b/simpleperf/scripts/bin/darwin/x86_64/simpleperf
index c4daaf2b..1a6a8875 100755
--- a/simpleperf/scripts/bin/darwin/x86_64/simpleperf
+++ b/simpleperf/scripts/bin/darwin/x86_64/simpleperf
Binary files differ
diff --git a/simpleperf/scripts/bin/linux/x86_64/libsimpleperf_report.so b/simpleperf/scripts/bin/linux/x86_64/libsimpleperf_report.so
index 6f148a8e..ca444ec9 100755
--- a/simpleperf/scripts/bin/linux/x86_64/libsimpleperf_report.so
+++ b/simpleperf/scripts/bin/linux/x86_64/libsimpleperf_report.so
Binary files differ
diff --git a/simpleperf/scripts/bin/linux/x86_64/simpleperf b/simpleperf/scripts/bin/linux/x86_64/simpleperf
index f2968884..dca7b30d 100755
--- a/simpleperf/scripts/bin/linux/x86_64/simpleperf
+++ b/simpleperf/scripts/bin/linux/x86_64/simpleperf
Binary files differ
diff --git a/simpleperf/scripts/bin/windows/x86_64/libsimpleperf_report.dll b/simpleperf/scripts/bin/windows/x86_64/libsimpleperf_report.dll
index 074bff34..b49e8f8f 100755
--- a/simpleperf/scripts/bin/windows/x86_64/libsimpleperf_report.dll
+++ b/simpleperf/scripts/bin/windows/x86_64/libsimpleperf_report.dll
Binary files differ
diff --git a/simpleperf/scripts/bin/windows/x86_64/simpleperf.exe b/simpleperf/scripts/bin/windows/x86_64/simpleperf.exe
index fc98293a..9838e771 100755
--- a/simpleperf/scripts/bin/windows/x86_64/simpleperf.exe
+++ b/simpleperf/scripts/bin/windows/x86_64/simpleperf.exe
Binary files differ
diff --git a/simpleperf/scripts/gecko_profile_generator.py b/simpleperf/scripts/gecko_profile_generator.py
index 683a5696..396c9a58 100755
--- a/simpleperf/scripts/gecko_profile_generator.py
+++ b/simpleperf/scripts/gecko_profile_generator.py
@@ -295,8 +295,6 @@ def _gecko_profile(
record_file: str,
symfs_dir: Optional[str],
kallsyms_file: Optional[str],
- comm_filter: Set[str],
- sample_filter: Optional[str],
report_lib_options: ReportLibOptions) -> GeckoProfile:
"""convert a simpleperf profile to gecko format"""
lib = ReportLib()
@@ -307,8 +305,6 @@ def _gecko_profile(
lib.SetRecordFile(record_file)
if kallsyms_file is not None:
lib.SetKallsymsFile(kallsyms_file)
- if sample_filter:
- lib.SetSampleFilter(sample_filter)
lib.SetReportOptions(report_lib_options)
arch = lib.GetArch()
@@ -323,9 +319,6 @@ def _gecko_profile(
if sample is None:
lib.Close()
break
- if comm_filter:
- if sample.thread_comm not in comm_filter:
- continue
event = lib.GetEventOfCurrentSample()
symbol = lib.GetSymbolOfCurrentSample()
callchain = lib.GetCallChainOfCurrentSample()
@@ -404,18 +397,12 @@ def main() -> None:
parser.add_argument('--kallsyms', help='Set the path to find kernel symbols.')
parser.add_argument('-i', '--record_file', nargs='?', default='perf.data',
help='Default is perf.data.')
- sample_filter_group = parser.add_argument_group('Sample filter options')
- parser.add_sample_filter_options(sample_filter_group)
- sample_filter_group.add_argument('--comm', nargs='+', action='append', help="""
- Use samples only in threads with selected names.""")
parser.add_report_lib_options()
args = parser.parse_args()
profile = _gecko_profile(
record_file=args.record_file,
symfs_dir=args.symfs,
kallsyms_file=args.kallsyms,
- comm_filter=set(flatten_arg_list(args.comm)),
- sample_filter=args.sample_filter,
report_lib_options=args.report_lib_options)
json.dump(profile, sys.stdout, sort_keys=True)
diff --git a/simpleperf/scripts/inferno/inferno.py b/simpleperf/scripts/inferno/inferno.py
index 42cbeaca..ccf1b6b6 100755
--- a/simpleperf/scripts/inferno/inferno.py
+++ b/simpleperf/scripts/inferno/inferno.py
@@ -111,8 +111,6 @@ def parse_samples(process, args, sample_filter_fn):
lib.SetRecordFile(record_file)
if kallsyms_file:
lib.SetKallsymsFile(kallsyms_file)
- if args.sample_filter:
- lib.SetSampleFilter(args.sample_filter)
lib.SetReportOptions(args.report_lib_options)
process.cmd = lib.GetRecordCmd()
product_props = lib.MetaInfo().get("product_props")
@@ -308,8 +306,8 @@ def main():
report_group.add_argument('--symfs', help="""Set the path to find binaries with symbols and
debug info.""")
report_group.add_argument('--title', help='Show a title in the report.')
- parser.add_sample_filter_options(report_group, False)
- parser.add_report_lib_options(report_group)
+ parser.add_report_lib_options(
+ report_group, sample_filter_group=report_group, sample_filter_with_pid_shortcut=False)
debug_group = parser.add_argument_group('Debug options')
debug_group.add_argument('--disable_adb_root', action='store_true', help="""Force adb to run
diff --git a/simpleperf/scripts/pprof_proto_generator.py b/simpleperf/scripts/pprof_proto_generator.py
index e3e2d11f..57c988b9 100755
--- a/simpleperf/scripts/pprof_proto_generator.py
+++ b/simpleperf/scripts/pprof_proto_generator.py
@@ -270,7 +270,6 @@ class PprofProfileGenerator(object):
config['binary_cache_dir'] = 'binary_cache'
if not os.path.isdir(config['binary_cache_dir']):
config['binary_cache_dir'] = None
- self.comm_filter = set(config['comm_filters']) if config.get('comm_filters') else None
self.dso_filter = set(config['dso_filters']) if config.get('dso_filters') else None
self.max_chain_length = config['max_chain_length']
self.profile = profile_pb2.Profile()
@@ -303,8 +302,6 @@ class PprofProfileGenerator(object):
if self.config.get('show_art_frames'):
self.lib.ShowArtFrames()
- if self.config.get('sample_filter'):
- self.lib.SetSampleFilter(self.config['sample_filter'])
self.lib.SetReportOptions(self.config['report_lib_options'])
comments = [
@@ -328,9 +325,6 @@ class PprofProfileGenerator(object):
symbol = self.lib.GetSymbolOfCurrentSample()
callchain = self.lib.GetCallChainOfCurrentSample()
- if not self._filter_report_sample(report_sample):
- continue
-
sample_type_id = self.get_sample_type_id(event.name)
sample = Sample()
sample.add_value(sample_type_id, 1)
@@ -378,13 +372,6 @@ class PprofProfileGenerator(object):
return self.profile
- def _filter_report_sample(self, sample):
- """Return true if the sample can be used."""
- if self.comm_filter:
- if sample.thread_comm not in self.comm_filter:
- return False
- return True
-
def _filter_symbol(self, symbol):
if not self.dso_filter or symbol.dso_name in self.dso_filter:
return True
@@ -636,12 +623,9 @@ def main():
'-j', '--jobs', type=int, default=os.cpu_count(),
help='Use multithreading to speed up source code annotation.')
sample_filter_group = parser.add_argument_group('Sample filter options')
- parser.add_sample_filter_options(sample_filter_group)
- sample_filter_group.add_argument('--comm', nargs='+', action='append', help="""
- Use samples only in threads with selected names.""")
sample_filter_group.add_argument('--dso', nargs='+', action='append', help="""
Use samples only in selected binaries.""")
- parser.add_report_lib_options()
+ parser.add_report_lib_options(sample_filter_group=sample_filter_group)
args = parser.parse_args()
if args.show:
@@ -653,11 +637,9 @@ def main():
config = {}
config['output_file'] = args.output_file
- config['comm_filters'] = flatten_arg_list(args.comm)
config['dso_filters'] = flatten_arg_list(args.dso)
config['ndk_path'] = args.ndk_path
config['max_chain_length'] = args.max_chain_length
- config['sample_filter'] = args.sample_filter
config['report_lib_options'] = args.report_lib_options
generator = PprofProfileGenerator(config)
for record_file in args.record_file:
diff --git a/simpleperf/scripts/report_html.py b/simpleperf/scripts/report_html.py
index 9c00131b..56f8dae5 100755
--- a/simpleperf/scripts/report_html.py
+++ b/simpleperf/scripts/report_html.py
@@ -620,9 +620,7 @@ class RecordData(object):
self.gen_addr_hit_map_in_record_info = False
self.binary_finder = BinaryFinder(binary_cache_path, ReadElf(ndk_path))
- def load_record_file(
- self, record_file: str, report_lib_options: ReportLibOptions,
- sample_filter: Optional[str]):
+ def load_record_file(self, record_file: str, report_lib_options: ReportLibOptions):
lib = ReportLib()
lib.SetRecordFile(record_file)
# If not showing ip for unknown symbols, the percent of the unknown symbol may be
@@ -630,8 +628,6 @@ class RecordData(object):
lib.ShowIpForUnknownSymbol()
if self.binary_cache_path:
lib.SetSymfs(self.binary_cache_path)
- if sample_filter:
- lib.SetSampleFilter(sample_filter)
lib.SetReportOptions(report_lib_options)
self.meta_info = lib.MetaInfo()
self.cmdline = lib.GetRecordCmd()
@@ -983,7 +979,6 @@ def get_args() -> argparse.Namespace:
parser.add_argument('--aggregate-by-thread-name', action='store_true', help="""aggregate
samples by thread name instead of thread id. This is useful for
showing multiple perf.data generated for the same app.""")
- parser.add_sample_filter_options()
parser.add_report_lib_options()
return parser.parse_args()
@@ -1012,7 +1007,7 @@ def main():
# 2. Produce record data.
record_data = RecordData(binary_cache_path, ndk_path, build_addr_hit_map)
for record_file in args.record_file:
- record_data.load_record_file(record_file, args.report_lib_options, args.sample_filter)
+ record_data.load_record_file(record_file, args.report_lib_options)
if args.aggregate_by_thread_name:
record_data.aggregate_by_thread_name()
record_data.limit_percents(args.min_func_percent, args.min_callchain_percent)
diff --git a/simpleperf/scripts/report_sample.py b/simpleperf/scripts/report_sample.py
index d99bbf9e..dc5c4e2b 100755
--- a/simpleperf/scripts/report_sample.py
+++ b/simpleperf/scripts/report_sample.py
@@ -29,8 +29,6 @@ def report_sample(
kallsyms_file: str,
show_tracing_data: bool,
header: bool,
- comm_filter: Set[str],
- sample_filter: Optional[str],
report_lib_options: ReportLibOptions):
""" read record_file, and print each sample"""
lib = ReportLib()
@@ -42,8 +40,6 @@ def report_sample(
lib.SetRecordFile(record_file)
if kallsyms_file is not None:
lib.SetKallsymsFile(kallsyms_file)
- if sample_filter:
- lib.SetSampleFilter(sample_filter)
lib.SetReportOptions(report_lib_options)
if header:
@@ -60,9 +56,6 @@ def report_sample(
if sample is None:
lib.Close()
break
- if comm_filter:
- if sample.thread_comm not in comm_filter:
- continue
event = lib.GetEventOfCurrentSample()
symbol = lib.GetSymbolOfCurrentSample()
callchain = lib.GetCallChainOfCurrentSample()
@@ -95,9 +88,6 @@ def main():
parser.add_argument('--show_tracing_data', action='store_true', help='print tracing data.')
parser.add_argument('--header', action='store_true',
help='Show metadata header, like perf script --header')
- parser.add_argument('--comm', nargs='+', action='append', help="""
- Use samples only in threads with selected names.""")
- parser.add_sample_filter_options()
parser.add_report_lib_options()
args = parser.parse_args()
report_sample(
@@ -106,8 +96,6 @@ def main():
kallsyms_file=args.kallsyms,
show_tracing_data=args.show_tracing_data,
header=args.header,
- comm_filter=set(flatten_arg_list(args.comm)),
- sample_filter=args.sample_filter,
report_lib_options=args.report_lib_options)
diff --git a/simpleperf/scripts/simpleperf_report_lib.py b/simpleperf/scripts/simpleperf_report_lib.py
index 45938882..48b31199 100644
--- a/simpleperf/scripts/simpleperf_report_lib.py
+++ b/simpleperf/scripts/simpleperf_report_lib.py
@@ -307,6 +307,8 @@ class ReportLib(object):
self.ShowArtFrames(True)
if options.trace_offcpu:
self.SetTraceOffCpuMode(options.trace_offcpu)
+ if options.sample_filters:
+ self.SetSampleFilter(options.sample_filters)
def SetLogSeverity(self, log_level: str = 'info'):
""" Set log severity of native lib, can be verbose,debug,info,error,fatal."""
@@ -373,7 +375,7 @@ class ReportLib(object):
res: bool = self._SetTraceOffCpuModeFunc(self.getInstance(), _char_pt(mode))
_check(res, f'Failed to call SetTraceOffCpuMode({mode})')
- def SetSampleFilter(self, filter: str):
+ def SetSampleFilter(self, filters: List[str]):
""" Set options used to filter samples. Available options are:
--exclude-pid pid1,pid2,... Exclude samples for selected processes.
--exclude-tid tid1,tid2,... Exclude samples for selected threads.
@@ -392,8 +394,10 @@ class ReportLib(object):
The filter argument should be a concatenation of options.
"""
- res: bool = self._SetSampleFilterFunc(self.getInstance(), _char_pt(filter))
- _check(res, f'Failed to call SetSampleFilter({filter})')
+ filter_array = (ct.c_char_p * len(filters))()
+ filter_array[:] = [_char_pt(f) for f in filters]
+ res: bool = self._SetSampleFilterFunc(self.getInstance(), filter_array, len(filters))
+ _check(res, f'Failed to call SetSampleFilter({filters})')
def GetNextSample(self) -> Optional[SampleStruct]:
""" Return the next sample. If no more samples, return None. """
diff --git a/simpleperf/scripts/simpleperf_utils.py b/simpleperf/scripts/simpleperf_utils.py
index f11d0a0d..2a7dfd35 100644
--- a/simpleperf/scripts/simpleperf_utils.py
+++ b/simpleperf/scripts/simpleperf_utils.py
@@ -1005,6 +1005,7 @@ class ReportLibOptions:
show_art_frames: bool
trace_offcpu: str
proguard_mapping_files: List[str]
+ sample_filters: List[str]
class BaseArgumentParser(argparse.ArgumentParser):
@@ -1015,7 +1016,9 @@ class BaseArgumentParser(argparse.ArgumentParser):
self.has_report_lib_options = False
def add_report_lib_options(self, group: Optional[Any] = None,
- default_show_art_frames: bool = False):
+ default_show_art_frames: bool = False,
+ sample_filter_group: Optional[Any] = None,
+ sample_filter_with_pid_shortcut: bool = True):
self.has_report_lib_options = True
parser = group if group else self
parser.add_argument(
@@ -1032,8 +1035,9 @@ class BaseArgumentParser(argparse.ArgumentParser):
mixed-on-off-cpu (on-cpu and off-cpu samples using the same event name).
If not set, mixed-on-off-cpu mode is used.
""")
+ self._add_sample_filter_options(sample_filter_group, sample_filter_with_pid_shortcut)
- def add_sample_filter_options(
+ def _add_sample_filter_options(
self, group: Optional[Any] = None, with_pid_shortcut: bool = True):
if not group:
group = self.add_argument_group('Sample filter options')
@@ -1061,7 +1065,8 @@ class BaseArgumentParser(argparse.ArgumentParser):
'--include-process-name', metavar='process_name_regex', nargs='+',
help='only include samples for processes with name containing the regular expression')
group.add_argument(
- '--include-thread-name', metavar='thread_name_regex', nargs='+',
+ '--comm', '--include-thread-name', metavar='thread_name_regex',
+ dest='include_thread_name', nargs='+',
help='only include samples for threads with name containing the regular expression')
group.add_argument(
'--filter-file', metavar='file',
@@ -1070,40 +1075,38 @@ class BaseArgumentParser(argparse.ArgumentParser):
self.has_sample_filter_options = True
self.sample_filter_with_pid_shortcut = with_pid_shortcut
- def _build_sample_filter(self, args: argparse.Namespace) -> Optional[str]:
- """ Convert sample filter options into a sample filter string, which can be passed to
- ReportLib.SetSampleFilter().
- """
+ def _build_sample_filter(self, args: argparse.Namespace) -> List[str]:
+ """ Build sample filters, which can be passed to ReportLib.SetSampleFilter(). """
filters = []
if args.exclude_pid:
- filters.append('--exclude-pid ' + ','.join(str(pid) for pid in args.exclude_pid))
+ filters.extend(['--exclude-pid', ','.join(str(pid) for pid in args.exclude_pid)])
if args.exclude_tid:
- filters.append('--exclude-tid ' + ','.join(str(tid) for tid in args.exclude_tid))
+ filters.extend(['--exclude-tid', ','.join(str(tid) for tid in args.exclude_tid)])
if args.exclude_process_name:
for name in args.exclude_process_name:
- filters.append('--exclude-process-name ' + name)
+ filters.extend(['--exclude-process-name', name])
if args.exclude_thread_name:
for name in args.exclude_thread_name:
- filters.append('--exclude-thread-name ' + name)
+ filters.extend(['--exclude-thread-name', name])
if args.include_pid:
- filters.append('--include-pid ' + ','.join(str(pid) for pid in args.include_pid))
+ filters.extend(['--include-pid', ','.join(str(pid) for pid in args.include_pid)])
if args.include_tid:
- filters.append('--include-tid ' + ','.join(str(tid) for tid in args.include_tid))
+ filters.extend(['--include-tid', ','.join(str(tid) for tid in args.include_tid)])
if self.sample_filter_with_pid_shortcut:
if args.pid:
- filters.append('--include-pid ' + ','.join(str(pid) for pid in args.pid))
+ filters.extend(['--include-pid', ','.join(str(pid) for pid in args.pid)])
if args.tid:
- filters.append('--include-tid ' + ','.join(str(pid) for pid in args.tid))
+ filters.extend(['--include-tid', ','.join(str(pid) for pid in args.tid)])
if args.include_process_name:
for name in args.include_process_name:
- filters.append('--include-process-name ' + name)
+ filters.extend(['--include-process-name', name])
if args.include_thread_name:
for name in args.include_thread_name:
- filters.append('--include-thread-name ' + name)
+ filters.extend(['--include-thread-name', name])
if args.filter_file:
- filters.append('--filter-file ' + args.filter_file)
- return ' '.join(filters)
+ filters.extend(['--filter-file', args.filter_file])
+ return filters
def parse_known_args(self, *args, **kwargs):
self.add_argument(
@@ -1111,12 +1114,11 @@ class BaseArgumentParser(argparse.ArgumentParser):
default='info', help='set log level')
namespace, left_args = super().parse_known_args(*args, **kwargs)
- if self.has_sample_filter_options:
- setattr(namespace, 'sample_filter', self._build_sample_filter(namespace))
-
if self.has_report_lib_options:
+ sample_filters = self._build_sample_filter(namespace)
report_lib_options = ReportLibOptions(
- namespace.show_art_frames, namespace.trace_offcpu, namespace.proguard_mapping_file)
+ namespace.show_art_frames, namespace.trace_offcpu, namespace.proguard_mapping_file,
+ sample_filters)
setattr(namespace, 'report_lib_options', report_lib_options)
if not Log.initialized:
diff --git a/simpleperf/scripts/stackcollapse.py b/simpleperf/scripts/stackcollapse.py
index ee82a0ba..e0e1d86f 100755
--- a/simpleperf/scripts/stackcollapse.py
+++ b/simpleperf/scripts/stackcollapse.py
@@ -43,8 +43,6 @@ def collapse_stacks(
annotate_kernel: bool,
annotate_jit: bool,
include_addrs: bool,
- comm_filter: Set[str],
- sample_filter: Optional[str],
report_lib_options: ReportLibOptions):
"""read record_file, aggregate per-stack and print totals per-stack"""
lib = ReportLib()
@@ -57,8 +55,6 @@ def collapse_stacks(
lib.SetRecordFile(record_file)
if kallsyms_file is not None:
lib.SetKallsymsFile(kallsyms_file)
- if sample_filter:
- lib.SetSampleFilter(sample_filter)
lib.SetReportOptions(report_lib_options)
stacks: DefaultDict[str, int] = defaultdict(int)
@@ -69,9 +65,6 @@ def collapse_stacks(
if sample is None:
lib.Close()
break
- if comm_filter:
- if sample.thread_comm not in comm_filter:
- continue
event = lib.GetEventOfCurrentSample()
symbol = lib.GetSymbolOfCurrentSample()
callchain = lib.GetCallChainOfCurrentSample()
@@ -123,12 +116,10 @@ def main():
parser.add_argument('--addrs', action='store_true',
help='include raw addresses where symbols can\'t be found')
sample_filter_group = parser.add_argument_group('Sample filter options')
- parser.add_sample_filter_options(sample_filter_group, False)
sample_filter_group.add_argument('--event-filter', nargs='?', default='',
help='Event type filter e.g. "cpu-cycles" or "instructions"')
- sample_filter_group.add_argument('--comm', nargs='+', action='append', help="""
- Use samples only in threads with selected names.""")
- parser.add_report_lib_options()
+ parser.add_report_lib_options(sample_filter_group=sample_filter_group,
+ sample_filter_with_pid_shortcut=False)
args = parser.parse_args()
collapse_stacks(
record_file=args.record_file,
@@ -140,8 +131,6 @@ def main():
annotate_kernel=args.kernel,
annotate_jit=args.jit,
include_addrs=args.addrs,
- comm_filter=set(flatten_arg_list(args.comm)),
- sample_filter=args.sample_filter,
report_lib_options=args.report_lib_options)
diff --git a/simpleperf/scripts/test/do_test.py b/simpleperf/scripts/test/do_test.py
index 2c67bb78..b95a1fef 100755
--- a/simpleperf/scripts/test/do_test.py
+++ b/simpleperf/scripts/test/do_test.py
@@ -32,6 +32,7 @@ import multiprocessing as mp
import os
from pathlib import Path
import re
+import subprocess
import sys
import time
from tqdm import tqdm
@@ -39,7 +40,7 @@ import types
from typing import List, Optional
import unittest
-from simpleperf_utils import BaseArgumentParser, extant_dir, log_exit, remove
+from simpleperf_utils import BaseArgumentParser, extant_dir, log_exit, remove, is_darwin
from . api_profiler_test import *
from . annotate_test import *
@@ -517,6 +518,15 @@ def run_tests_in_child_process(tests: List[str], args: argparse.Namespace) -> bo
return False
+def sign_executables_on_darwin():
+ """ Sign executables on M1 Mac, otherwise they can't run. """
+ if not is_darwin():
+ return
+ bin_dir = Path(__file__).resolve().parents[1] / 'bin' / 'darwin' / 'x86_64'
+ for path in bin_dir.iterdir():
+ subprocess.run(f'codesign --force -s - {path}', shell=True, check=True)
+
+
def main() -> bool:
args = get_args()
tests = get_host_tests() if args.only_host_test else get_all_tests()
@@ -532,4 +542,5 @@ def main() -> bool:
# Switch to the test dir.
os.chdir(test_dir)
build_testdata(Path('testdata'))
+ sign_executables_on_darwin()
return run_tests_in_child_process(tests, args)
diff --git a/simpleperf/scripts/test/pprof_proto_generator_test.py b/simpleperf/scripts/test/pprof_proto_generator_test.py
index 8e39d1a7..cbeb8d6a 100644
--- a/simpleperf/scripts/test/pprof_proto_generator_test.py
+++ b/simpleperf/scripts/test/pprof_proto_generator_test.py
@@ -218,7 +218,7 @@ class TestPprofProtoGenerator(TestBase):
# Read recording file.
config = {'ndk_path': None, 'max_chain_length': 1000000,
- 'report_lib_options': ReportLibOptions(False, '', None)}
+ 'report_lib_options': ReportLibOptions(False, '', None, None)}
generator = PprofProfileGenerator(config)
generator.load_record_file(testdata_file)
diff --git a/simpleperf/scripts/test/report_lib_test.py b/simpleperf/scripts/test/report_lib_test.py
index ba7ae466..1447c5ae 100644
--- a/simpleperf/scripts/test/report_lib_test.py
+++ b/simpleperf/scripts/test/report_lib_test.py
@@ -16,7 +16,7 @@
import os
import tempfile
-from typing import Set
+from typing import List, Set
from simpleperf_report_lib import ReportLib
from . test_utils import TestBase, TestHelper
@@ -275,34 +275,39 @@ class TestReportLib(TestBase):
def test_set_sample_filter(self):
""" Test using ReportLib.SetSampleFilter(). """
- def get_threads_for_filter(filter: str) -> Set[int]:
+ def get_threads_for_filter(filters: List[str]) -> Set[int]:
self.report_lib.Close()
self.report_lib = ReportLib()
self.report_lib.SetRecordFile(TestHelper.testdata_path('perf_display_bitmaps.data'))
- self.report_lib.SetSampleFilter(filter)
+ self.report_lib.SetSampleFilter(filters)
threads = set()
while self.report_lib.GetNextSample():
sample = self.report_lib.GetCurrentSample()
threads.add(sample.tid)
return threads
- self.assertNotIn(31850, get_threads_for_filter('--exclude-pid 31850'))
- self.assertIn(31850, get_threads_for_filter('--include-pid 31850'))
- self.assertNotIn(31881, get_threads_for_filter('--exclude-tid 31881'))
- self.assertIn(31881, get_threads_for_filter('--include-tid 31881'))
+ self.assertNotIn(31850, get_threads_for_filter(['--exclude-pid', '31850']))
+ self.assertIn(31850, get_threads_for_filter(['--include-pid', '31850']))
+ self.assertNotIn(31881, get_threads_for_filter(['--exclude-tid', '31881']))
+ self.assertIn(31881, get_threads_for_filter(['--include-tid', '31881']))
self.assertNotIn(31881, get_threads_for_filter(
- '--exclude-process-name com.example.android.displayingbitmaps'))
+ ['--exclude-process-name', 'com.example.android.displayingbitmaps']))
self.assertIn(31881, get_threads_for_filter(
- '--include-process-name com.example.android.displayingbitmaps'))
+ ['--include-process-name', 'com.example.android.displayingbitmaps']))
self.assertNotIn(31850, get_threads_for_filter(
- '--exclude-thread-name com.example.android.displayingbitmaps'))
+ ['--exclude-thread-name', 'com.example.android.displayingbitmaps']))
self.assertIn(31850, get_threads_for_filter(
- '--include-thread-name com.example.android.displayingbitmaps'))
+ ['--include-thread-name', 'com.example.android.displayingbitmaps']))
+
+ # Check that thread name can have space.
+ self.assertNotIn(31856, get_threads_for_filter(
+ ['--exclude-thread-name', 'Jit thread pool']))
+ self.assertIn(31856, get_threads_for_filter(['--include-thread-name', 'Jit thread pool']))
with tempfile.NamedTemporaryFile('w', delete=False) as filter_file:
filter_file.write('GLOBAL_BEGIN 684943449406175\nGLOBAL_END 684943449406176')
filter_file.flush()
- threads = get_threads_for_filter('--filter-file ' + filter_file.name)
+ threads = get_threads_for_filter(['--filter-file', filter_file.name])
self.assertIn(31881, threads)
self.assertNotIn(31850, threads)
os.unlink(filter_file.name)
diff --git a/verity/fec/Android.bp b/verity/fec/Android.bp
index 9ca45600..ede5fd19 100644
--- a/verity/fec/Android.bp
+++ b/verity/fec/Android.bp
@@ -25,6 +25,11 @@ cc_binary_host {
misc_undefined: ["integer"],
},
},
+ linux_musl_x86_64: {
+ sanitize: {
+ misc_undefined: ["integer"],
+ },
+ },
linux: {
static_libs: [
"libavb",