summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-04-28 20:09:12 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-04-28 20:09:12 +0000
commit8d1a91b325d2eb72954150be3aa2878cc2590366 (patch)
treeff52905359cc3119eefdfdfd89ff245124845a77
parent3b1534fc2bf39b1b834d234344e35d877514a202 (diff)
parentcd6b038e799ea13120e9676e0f1b23cdda4223db (diff)
downloadextras-8d1a91b325d2eb72954150be3aa2878cc2590366.tar.gz
Snap for 8505378 from cd6b038e799ea13120e9676e0f1b23cdda4223db to mainline-go-adservices-release
Change-Id: Icd018c86bd8106d2efa7d1b84bae2303a82628eb
-rw-r--r--ext4_utils/mkuserimg_mke2fs.py4
-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/Android.mk2
-rw-r--r--simpleperf/IOEventLoop.cpp32
-rw-r--r--simpleperf/IOEventLoop.h25
-rw-r--r--simpleperf/IOEventLoop_test.cpp42
-rw-r--r--simpleperf/OfflineUnwinder.cpp3
-rw-r--r--simpleperf/OfflineUnwinder.h5
-rw-r--r--simpleperf/cmd_monitor.cpp13
-rw-r--r--simpleperf/cmd_record.cpp44
-rw-r--r--simpleperf/doc/collect_etm_data_for_autofdo.md30
-rw-r--r--simpleperf/environment.h3
-rw-r--r--simpleperf/event_selection_set.cpp9
-rwxr-xr-xsimpleperf/scripts/test/do_test.py13
-rw-r--r--tests/kernel.config/AndroidTest.xml2
-rw-r--r--verity/Android.bp7
-rw-r--r--verity/build_verity_metadata.py20
-rw-r--r--verity/fec/Android.bp5
25 files changed, 213 insertions, 83 deletions
diff --git a/ext4_utils/mkuserimg_mke2fs.py b/ext4_utils/mkuserimg_mke2fs.py
index 599e40ee..41ae8cd7 100644
--- a/ext4_utils/mkuserimg_mke2fs.py
+++ b/ext4_utils/mkuserimg_mke2fs.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
#
# Copyright (C) 2018 The Android Open Source Project
#
@@ -165,7 +165,7 @@ def ConstructE2fsCommands(args):
if args.flash_erase_block_size:
mke2fs_extended_opts.append("stripe_width={}".format(
- int(args.flash_erase_block_size) / BLOCKSIZE))
+ int(args.flash_erase_block_size) // BLOCKSIZE))
if args.flash_logical_block_size:
# stride should be the max of 8kb and the logical block size
stride = max(int(args.flash_logical_block_size), 8192)
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/Android.mk b/simpleperf/Android.mk
index df0009f4..954c28c0 100644
--- a/simpleperf/Android.mk
+++ b/simpleperf/Android.mk
@@ -33,4 +33,6 @@ SIMPLEPERF_SCRIPT_PATH := \
$(SIMPLEPERF_SCRIPT_PATH) : $(SOONG_ZIP)
$(hide) $(SOONG_ZIP) -d -o $@ -C system/extras/simpleperf $(SIMPLEPERF_SCRIPT_LIST)
+$(call declare-1p-target,$(SIMPLEPERF_SCRIPT_PATH),system/extras)
+
$(call dist-for-goals,simpleperf,$(SIMPLEPERF_SCRIPT_PATH):simpleperf/simpleperf_script.zip)
diff --git a/simpleperf/IOEventLoop.cpp b/simpleperf/IOEventLoop.cpp
index 06bdd713..239fff97 100644
--- a/simpleperf/IOEventLoop.cpp
+++ b/simpleperf/IOEventLoop.cpp
@@ -84,6 +84,10 @@ bool IOEventLoop::EnsureInit() {
return false;
}
event_config_free(cfg);
+ if (event_base_priority_init(ebase_, 2) != 0) {
+ LOG(ERROR) << "event_base_priority_init failed";
+ return false;
+ }
}
if (ebase_ == nullptr) {
LOG(ERROR) << "failed to create event_base";
@@ -110,39 +114,44 @@ static bool MakeFdNonBlocking(int fd) {
return true;
}
-IOEventRef IOEventLoop::AddReadEvent(int fd, const std::function<bool()>& callback) {
+IOEventRef IOEventLoop::AddReadEvent(int fd, const std::function<bool()>& callback,
+ IOEventPriority priority) {
if (!MakeFdNonBlocking(fd)) {
return nullptr;
}
- return AddEvent(fd, EV_READ | EV_PERSIST, nullptr, callback);
+ return AddEvent(fd, EV_READ | EV_PERSIST, nullptr, callback, priority);
}
-IOEventRef IOEventLoop::AddWriteEvent(int fd, const std::function<bool()>& callback) {
+IOEventRef IOEventLoop::AddWriteEvent(int fd, const std::function<bool()>& callback,
+ IOEventPriority priority) {
if (!MakeFdNonBlocking(fd)) {
return nullptr;
}
- return AddEvent(fd, EV_WRITE | EV_PERSIST, nullptr, callback);
+ return AddEvent(fd, EV_WRITE | EV_PERSIST, nullptr, callback, priority);
}
-bool IOEventLoop::AddSignalEvent(int sig, const std::function<bool()>& callback) {
- return AddEvent(sig, EV_SIGNAL | EV_PERSIST, nullptr, callback) != nullptr;
+bool IOEventLoop::AddSignalEvent(int sig, const std::function<bool()>& callback,
+ IOEventPriority priority) {
+ return AddEvent(sig, EV_SIGNAL | EV_PERSIST, nullptr, callback, priority) != nullptr;
}
-bool IOEventLoop::AddSignalEvents(std::vector<int> sigs, const std::function<bool()>& callback) {
+bool IOEventLoop::AddSignalEvents(std::vector<int> sigs, const std::function<bool()>& callback,
+ IOEventPriority priority) {
for (auto sig : sigs) {
- if (!AddSignalEvent(sig, callback)) {
+ if (!AddSignalEvent(sig, callback, priority)) {
return false;
}
}
return true;
}
-IOEventRef IOEventLoop::AddPeriodicEvent(timeval duration, const std::function<bool()>& callback) {
- return AddEvent(-1, EV_PERSIST, &duration, callback);
+IOEventRef IOEventLoop::AddPeriodicEvent(timeval duration, const std::function<bool()>& callback,
+ IOEventPriority priority) {
+ return AddEvent(-1, EV_PERSIST, &duration, callback, priority);
}
IOEventRef IOEventLoop::AddEvent(int fd_or_sig, int16_t events, timeval* timeout,
- const std::function<bool()>& callback) {
+ const std::function<bool()>& callback, IOEventPriority priority) {
if (!EnsureInit()) {
return nullptr;
}
@@ -152,6 +161,7 @@ IOEventRef IOEventLoop::AddEvent(int fd_or_sig, int16_t events, timeval* timeout
LOG(ERROR) << "event_new() failed";
return nullptr;
}
+ event_priority_set(e->e, priority);
if (event_add(e->e, timeout) != 0) {
LOG(ERROR) << "event_add() failed";
return nullptr;
diff --git a/simpleperf/IOEventLoop.h b/simpleperf/IOEventLoop.h
index f0192969..1578a4d0 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>
@@ -31,6 +32,12 @@ namespace simpleperf {
struct IOEvent;
typedef IOEvent* IOEventRef;
+enum IOEventPriority {
+ // Lower value means higher priority.
+ IOEventHighPriority = 0,
+ IOEventLowPriority = 1,
+};
+
// IOEventLoop is a class wrapper of libevent, it monitors events happened,
// and calls the corresponding callbacks. Possible events are: file ready to
// read, file ready to write, signal happens, periodic timer timeout.
@@ -45,22 +52,27 @@ class IOEventLoop {
// Register a read Event, so [callback] is called when [fd] can be read
// without blocking. If registered successfully, return the reference
// to control the Event, otherwise return nullptr.
- IOEventRef AddReadEvent(int fd, const std::function<bool()>& callback);
+ IOEventRef AddReadEvent(int fd, const std::function<bool()>& callback,
+ IOEventPriority priority = IOEventLowPriority);
// Register a write Event, so [callback] is called when [fd] can be written
// without blocking.
- IOEventRef AddWriteEvent(int fd, const std::function<bool()>& callback);
+ IOEventRef AddWriteEvent(int fd, const std::function<bool()>& callback,
+ IOEventPriority priority = IOEventLowPriority);
// Register a signal Event, so [callback] is called each time signal [sig]
// happens.
- bool AddSignalEvent(int sig, const std::function<bool()>& callback);
+ bool AddSignalEvent(int sig, const std::function<bool()>& callback,
+ IOEventPriority priority = IOEventLowPriority);
// Register a vector of signal Events.
- bool AddSignalEvents(std::vector<int> sigs, const std::function<bool()>& callback);
+ bool AddSignalEvents(std::vector<int> sigs, const std::function<bool()>& callback,
+ IOEventPriority priority = IOEventLowPriority);
// Register a periodic Event, so [callback] is called periodically every
// [duration].
- IOEventRef AddPeriodicEvent(timeval duration, const std::function<bool()>& callback);
+ IOEventRef AddPeriodicEvent(timeval duration, const std::function<bool()>& callback,
+ IOEventPriority priority = IOEventLowPriority);
// Run a loop polling for Events. It only exits when ExitLoop() is called
// in a callback function of registered Events.
@@ -80,7 +92,8 @@ class IOEventLoop {
private:
bool EnsureInit();
IOEventRef AddEvent(int fd_or_sig, int16_t events, timeval* timeout,
- const std::function<bool()>& callback);
+ const std::function<bool()>& callback,
+ IOEventPriority priority = IOEventLowPriority);
static void EventCallbackFn(int, int16_t, void*);
event_base* ebase_;
diff --git a/simpleperf/IOEventLoop_test.cpp b/simpleperf/IOEventLoop_test.cpp
index 09f64522..658fe820 100644
--- a/simpleperf/IOEventLoop_test.cpp
+++ b/simpleperf/IOEventLoop_test.cpp
@@ -250,3 +250,45 @@ TEST(IOEventLoop, exit_before_loop) {
IOEventLoop loop;
ASSERT_TRUE(loop.ExitLoop());
}
+
+TEST(IOEventLoop, priority) {
+ int low_priority_fd[2];
+ ASSERT_EQ(0, pipe(low_priority_fd));
+ int high_priority_fd[2];
+ ASSERT_EQ(0, pipe(high_priority_fd));
+
+ IOEventLoop loop;
+ int count = 0;
+
+ ASSERT_NE(nullptr, loop.AddReadEvent(
+ low_priority_fd[0],
+ [&]() {
+ char c;
+ read(low_priority_fd[0], &c, 1);
+ CHECK_EQ(count, 1);
+ count++;
+ return loop.ExitLoop();
+ },
+ IOEventLowPriority));
+
+ ASSERT_NE(nullptr, loop.AddReadEvent(
+ high_priority_fd[0],
+ [&]() {
+ char c;
+ read(high_priority_fd[0], &c, 1);
+ CHECK_EQ(count, 0);
+ count++;
+ return true;
+ },
+ IOEventHighPriority));
+
+ char c;
+ CHECK_EQ(write(low_priority_fd[1], &c, 1), 1);
+ CHECK_EQ(write(high_priority_fd[1], &c, 1), 1);
+ ASSERT_TRUE(loop.RunLoop());
+ ASSERT_EQ(2, count);
+ for (int i = 0; i < 2; i++) {
+ close(low_priority_fd[i]);
+ close(high_priority_fd[i]);
+ }
+}
diff --git a/simpleperf/OfflineUnwinder.cpp b/simpleperf/OfflineUnwinder.cpp
index f611ef4d..bbc488b4 100644
--- a/simpleperf/OfflineUnwinder.cpp
+++ b/simpleperf/OfflineUnwinder.cpp
@@ -66,6 +66,9 @@ CHECK_ERROR_CODE(ERROR_INVALID_ELF);
CHECK_ERROR_CODE(ERROR_THREAD_DOES_NOT_EXIST);
CHECK_ERROR_CODE(ERROR_THREAD_TIMEOUT);
CHECK_ERROR_CODE(ERROR_SYSTEM_CALL);
+CHECK_ERROR_CODE(ERROR_BAD_ARCH);
+CHECK_ERROR_CODE(ERROR_MAPS_PARSE);
+CHECK_ERROR_CODE(ERROR_INVALID_PARAMETER);
CHECK_ERROR_CODE(ERROR_MAX);
// Max frames seen so far is 463, in http://b/110923759.
diff --git a/simpleperf/OfflineUnwinder.h b/simpleperf/OfflineUnwinder.h
index b6445577..9eb9e8ff 100644
--- a/simpleperf/OfflineUnwinder.h
+++ b/simpleperf/OfflineUnwinder.h
@@ -39,7 +39,10 @@ enum UnwindStackErrorCode : uint8_t {
// not exist.
ERROR_THREAD_TIMEOUT, // Timeout trying to unwind a local thread.
ERROR_SYSTEM_CALL, // System call failed while unwinding.
- ERROR_MAX = ERROR_SYSTEM_CALL,
+ ERROR_BAD_ARCH, // Arch invalid (none, or mismatched).
+ ERROR_MAPS_PARSE, // Failed to parse maps data.
+ ERROR_INVALID_PARAMETER, // Invalid parameter passed to function.
+ ERROR_MAX = ERROR_INVALID_PARAMETER,
};
struct UnwindingResult {
diff --git a/simpleperf/cmd_monitor.cpp b/simpleperf/cmd_monitor.cpp
index ed9edfac..d81ccfea 100644
--- a/simpleperf/cmd_monitor.cpp
+++ b/simpleperf/cmd_monitor.cpp
@@ -266,21 +266,22 @@ bool MonitorCommand::PrepareMonitoring() {
// 5. Add read/signal/periodic Events.
IOEventLoop* loop = event_selection_set_.GetIOEventLoop();
auto exit_loop_callback = [loop]() { return loop->ExitLoop(); };
- if (!loop->AddSignalEvents({SIGCHLD, SIGINT, SIGTERM}, exit_loop_callback)) {
+ if (!loop->AddSignalEvents({SIGCHLD, SIGINT, SIGTERM}, exit_loop_callback, IOEventHighPriority)) {
return false;
}
// Only add an event for SIGHUP if we didn't inherit SIG_IGN (e.g. from
// nohup).
if (!SignalIsIgnored(SIGHUP)) {
- if (!loop->AddSignalEvent(SIGHUP, exit_loop_callback)) {
+ if (!loop->AddSignalEvent(SIGHUP, exit_loop_callback, IOEventHighPriority)) {
return false;
}
}
if (duration_in_sec_ != 0) {
- if (!loop->AddPeriodicEvent(SecondToTimeval(duration_in_sec_),
- [loop]() { return loop->ExitLoop(); })) {
+ if (!loop->AddPeriodicEvent(
+ SecondToTimeval(duration_in_sec_), [loop]() { return loop->ExitLoop(); },
+ IOEventHighPriority)) {
return false;
}
}
@@ -291,6 +292,10 @@ bool MonitorCommand::DoMonitoring() {
if (!event_selection_set_.GetIOEventLoop()->RunLoop()) {
return false;
}
+ if (!event_selection_set_.SyncKernelBuffer()) {
+ return false;
+ }
+ event_selection_set_.CloseEventFiles();
if (!event_selection_set_.FinishReadMmapEventData()) {
return false;
}
diff --git a/simpleperf/cmd_record.cpp b/simpleperf/cmd_record.cpp
index b84bcfab..4b79eedc 100644
--- a/simpleperf/cmd_record.cpp
+++ b/simpleperf/cmd_record.cpp
@@ -629,25 +629,26 @@ bool RecordCommand::PrepareRecording(Workload* workload) {
}
IOEventLoop* loop = event_selection_set_.GetIOEventLoop();
auto exit_loop_callback = [loop]() { return loop->ExitLoop(); };
- if (!loop->AddSignalEvents({SIGCHLD, SIGINT, SIGTERM}, exit_loop_callback)) {
+ if (!loop->AddSignalEvents({SIGCHLD, SIGINT, SIGTERM}, exit_loop_callback, IOEventHighPriority)) {
return false;
}
// Only add an event for SIGHUP if we didn't inherit SIG_IGN (e.g. from nohup).
if (!SignalIsIgnored(SIGHUP)) {
- if (!loop->AddSignalEvent(SIGHUP, exit_loop_callback)) {
+ if (!loop->AddSignalEvent(SIGHUP, exit_loop_callback, IOEventHighPriority)) {
return false;
}
}
if (stop_signal_fd_ != -1) {
- if (!loop->AddReadEvent(stop_signal_fd_, exit_loop_callback)) {
+ if (!loop->AddReadEvent(stop_signal_fd_, exit_loop_callback, IOEventHighPriority)) {
return false;
}
}
if (duration_in_sec_ != 0) {
- if (!loop->AddPeriodicEvent(SecondToTimeval(duration_in_sec_),
- [loop]() { return loop->ExitLoop(); })) {
+ if (!loop->AddPeriodicEvent(
+ SecondToTimeval(duration_in_sec_), [loop]() { return loop->ExitLoop(); },
+ IOEventHighPriority)) {
return false;
}
}
@@ -718,9 +719,10 @@ bool RecordCommand::DoRecording(Workload* workload) {
return false;
}
time_stat_.stop_recording_time = GetSystemClock();
- if (!event_selection_set_.FinishReadMmapEventData()) {
+ if (!event_selection_set_.SyncKernelBuffer()) {
return false;
}
+ event_selection_set_.CloseEventFiles();
time_stat_.finish_recording_time = GetSystemClock();
uint64_t recording_time = time_stat_.finish_recording_time - time_stat_.start_recording_time;
LOG(INFO) << "Recorded for " << recording_time / 1e9 << " seconds. Start post processing.";
@@ -754,26 +756,31 @@ static bool WriteRecordDataToOutFd(const std::string& in_filename,
}
bool RecordCommand::PostProcessRecording(const std::vector<std::string>& args) {
- // 1. Merge map records dumped while recording by map record thread.
+ // 1. Read records left in the buffer.
+ if (!event_selection_set_.FinishReadMmapEventData()) {
+ return false;
+ }
+
+ // 2. Merge map records dumped while recording by map record thread.
if (map_record_thread_) {
if (!map_record_thread_->Join() || !MergeMapRecords()) {
return false;
}
}
- // 2. Post unwind dwarf callchain.
+ // 3. Post unwind dwarf callchain.
if (unwind_dwarf_callchain_ && post_unwind_) {
if (!PostUnwindRecords()) {
return false;
}
}
- // 3. Optionally join Callchains.
+ // 4. Optionally join Callchains.
if (callchain_joiner_) {
JoinCallChains();
}
- // 4. Dump additional features, and close record file.
+ // 5. Dump additional features, and close record file.
if (!DumpAdditionalFeatures(args)) {
return false;
}
@@ -785,7 +792,7 @@ bool RecordCommand::PostProcessRecording(const std::vector<std::string>& args) {
}
time_stat_.post_process_time = GetSystemClock();
- // 4. Show brief record result.
+ // 6. Show brief record result.
auto record_stat = event_selection_set_.GetRecordStat();
if (event_selection_set_.HasAuxTrace()) {
LOG(INFO) << "Aux data traced: " << record_stat.aux_data_size;
@@ -1278,8 +1285,9 @@ bool RecordCommand::CreateAndInitRecordFile() {
return false;
}
// Use first perf_event_attr and first event id to dump mmap and comm records.
- EventAttrWithId dumping_attr_id = event_selection_set_.GetEventAttrWithId()[0];
- map_record_reader_.emplace(*dumping_attr_id.attr, dumping_attr_id.ids[0],
+ dumping_attr_id_ = event_selection_set_.GetEventAttrWithId()[0];
+ CHECK(!dumping_attr_id_.ids.empty());
+ map_record_reader_.emplace(*dumping_attr_id_.attr, dumping_attr_id_.ids[0],
event_selection_set_.RecordNotExecutableMaps());
map_record_reader_->SetCallback([this](Record* r) { return ProcessRecord(r); });
@@ -1503,14 +1511,13 @@ bool RecordCommand::SaveRecordWithoutUnwinding(Record* record) {
bool RecordCommand::ProcessJITDebugInfo(const std::vector<JITDebugInfo>& debug_info,
bool sync_kernel_records) {
- EventAttrWithId attr_id = event_selection_set_.GetEventAttrWithId()[0];
for (auto& info : debug_info) {
if (info.type == JITDebugInfo::JIT_DEBUG_JIT_CODE) {
uint64_t timestamp =
jit_debug_reader_->SyncWithRecords() ? info.timestamp : last_record_timestamp_;
- Mmap2Record record(*attr_id.attr, false, info.pid, info.pid, info.jit_code_addr,
+ Mmap2Record record(*dumping_attr_id_.attr, false, info.pid, info.pid, info.jit_code_addr,
info.jit_code_len, info.file_offset, map_flags::PROT_JIT_SYMFILE_MAP,
- info.file_path, attr_id.ids[0], timestamp);
+ info.file_path, dumping_attr_id_.ids[0], timestamp);
if (!ProcessRecord(&record)) {
return false;
}
@@ -1519,8 +1526,9 @@ bool RecordCommand::ProcessJITDebugInfo(const std::vector<JITDebugInfo>& debug_i
ThreadMmap& map = *info.extracted_dex_file_map;
uint64_t timestamp =
jit_debug_reader_->SyncWithRecords() ? info.timestamp : last_record_timestamp_;
- Mmap2Record record(*attr_id.attr, false, info.pid, info.pid, map.start_addr, map.len,
- map.pgoff, map.prot, map.name, attr_id.ids[0], timestamp);
+ Mmap2Record record(*dumping_attr_id_.attr, false, info.pid, info.pid, map.start_addr,
+ map.len, map.pgoff, map.prot, map.name, dumping_attr_id_.ids[0],
+ timestamp);
if (!ProcessRecord(&record)) {
return false;
}
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/event_selection_set.cpp b/simpleperf/event_selection_set.cpp
index d5bca318..58b4b956 100644
--- a/simpleperf/event_selection_set.cpp
+++ b/simpleperf/event_selection_set.cpp
@@ -840,14 +840,7 @@ bool EventSelectionSet::ReadMmapEventData(bool with_time_limit) {
}
bool EventSelectionSet::FinishReadMmapEventData() {
- // Stop the read thread, so we don't get more records beyond current time.
- if (!SyncKernelBuffer() || !record_read_thread_->StopReadThread()) {
- return false;
- }
- if (!ReadMmapEventData(false)) {
- return false;
- }
- return true;
+ return ReadMmapEventData(false);
}
void EventSelectionSet::CloseEventFiles() {
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/tests/kernel.config/AndroidTest.xml b/tests/kernel.config/AndroidTest.xml
index 19da90af..78452e1c 100644
--- a/tests/kernel.config/AndroidTest.xml
+++ b/tests/kernel.config/AndroidTest.xml
@@ -26,7 +26,7 @@
</target_preparer>
<!-- Make sure there is some data in the pstore then reboot -->
<target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
- <option name="run-command" value="echo HELLOWORLD >/dev/pmsg0" />
+ <option name="run-command" value="if [ -e /dev/pmsg0 ] ; then echo HELLOWORLD > /dev/pmsg0; fi" />
<option name="throw-if-cmd-fail" value="true" />
</target_preparer>
<target_preparer class="com.android.tradefed.targetprep.RebootTargetPreparer" />
diff --git a/verity/Android.bp b/verity/Android.bp
index fc2b827c..ef09528c 100644
--- a/verity/Android.bp
+++ b/verity/Android.bp
@@ -154,13 +154,8 @@ python_binary_host {
name: "build_verity_metadata",
srcs: ["build_verity_metadata.py"],
version: {
- py2: {
- enabled: true,
- embedded_launcher: true,
- },
py3: {
- enabled: false,
- embedded_launcher: false,
+ embedded_launcher: true,
},
},
}
diff --git a/verity/build_verity_metadata.py b/verity/build_verity_metadata.py
index 5a7d7d27..a428f270 100644
--- a/verity/build_verity_metadata.py
+++ b/verity/build_verity_metadata.py
@@ -1,4 +1,4 @@
-#! /usr/bin/env python
+#!/usr/bin/env python3
#
# Copyright (C) 2013 The Android Open Source Project
#
@@ -29,9 +29,9 @@ BLOCK_SIZE = 4096
METADATA_SIZE = BLOCK_SIZE * 8
def run(cmd):
- p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
+ p = subprocess.Popen(cmd, stdout=subprocess.PIPE, text=True)
output, _ = p.communicate()
- print output
+ print(output)
if p.returncode:
exit(-1)
@@ -43,12 +43,12 @@ def build_metadata_block(verity_table, signature, verity_disable=False):
magic = MAGIC_DISABLE if verity_disable else MAGIC_NUMBER
block = struct.pack("II256sI", magic, VERSION, signature, table_len)
block += verity_table
- block = block.ljust(METADATA_SIZE, '\x00')
+ block = block.ljust(METADATA_SIZE, b'\x00')
return block
def sign_verity_table(table, signer_path, key_path, signer_args=None):
- with tempfile.NamedTemporaryFile(suffix='.table') as table_file:
- with tempfile.NamedTemporaryFile(suffix='.sig') as signature_file:
+ with tempfile.NamedTemporaryFile(mode='wb', suffix='.table') as table_file:
+ with tempfile.NamedTemporaryFile(mode='rb', suffix='.sig') as signature_file:
table_file.write(table)
table_file.flush()
if signer_args is None:
@@ -56,7 +56,7 @@ def sign_verity_table(table, signer_path, key_path, signer_args=None):
else:
args_list = shlex.split(signer_args)
cmd = [signer_path] + args_list + [table_file.name, key_path, signature_file.name]
- print cmd
+ print(cmd)
run(cmd)
return signature_file.read()
@@ -70,7 +70,7 @@ def build_verity_table(block_device, data_blocks, root_hash, salt):
data_blocks,
root_hash,
salt)
- return table
+ return table.encode()
def build_verity_metadata(data_blocks, metadata_image, root_hash, salt,
block_device, signer_path, signing_key, signer_args=None,
@@ -109,9 +109,9 @@ if __name__ == "__main__":
args = parser.parse_args()
if args.dest == 'size':
- print get_verity_metadata_size(args.partition_size)
+ print(get_verity_metadata_size(args.partition_size))
else:
- build_verity_metadata(args.blocks / 4096, args.metadata_image,
+ build_verity_metadata(args.blocks // 4096, args.metadata_image,
args.root_hash, args.salt, args.block_device,
args.signer_path, args.signing_key,
args.signer_args, args.verity_disable)
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",