diff options
author | ThiƩbaud Weksteen <tweek@google.com> | 2020-10-26 09:10:54 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2020-10-26 09:10:54 +0000 |
commit | 7ebc9e6cd61d5b167ccccbea85f42387370f51a7 (patch) | |
tree | b13633d7e0644cdb8e58c08bc780eedf580534e0 | |
parent | 4b06245be4931caad63f3cce59dafaf689143248 (diff) | |
parent | 4848ee07bb07ebb765e6fa0561f0d90ff86bbffb (diff) | |
download | extras-7ebc9e6cd61d5b167ccccbea85f42387370f51a7.tar.gz |
Merge "simpleperf: enable .clang-format"
103 files changed, 1762 insertions, 1894 deletions
diff --git a/simpleperf/.clang-format b/simpleperf/.clang-format new file mode 120000 index 00000000..fd0645fd --- /dev/null +++ b/simpleperf/.clang-format @@ -0,0 +1 @@ +../.clang-format-2
\ No newline at end of file diff --git a/simpleperf/CallChainJoiner.cpp b/simpleperf/CallChainJoiner.cpp index f6198844..5d02cd5e 100644 --- a/simpleperf/CallChainJoiner.cpp +++ b/simpleperf/CallChainJoiner.cpp @@ -31,7 +31,7 @@ LRUCache::LRUCache(size_t cache_size, size_t matched_node_count_to_extend_callch CHECK_GE(cache_stat_.max_node_count, 2u); CHECK_GE(matched_node_count_to_extend_callchain, 1u); cache_stat_.matched_node_count_to_extend_callchain = matched_node_count_to_extend_callchain; - nodes_ = new CacheNode[cache_stat_.max_node_count + 1]; // with 1 sentinel node + nodes_ = new CacheNode[cache_stat_.max_node_count + 1]; // with 1 sentinel node // nodes_[0] is the sentinel node of the LRU linked list. nodes_[0].is_leaf = 1; nodes_[0].parent_index = 0; @@ -170,13 +170,12 @@ void LRUCache::UnlinkParent(CacheNode* child) { child->parent_index = 0; } -} // call_chain_joiner_impl +} // namespace call_chain_joiner_impl using namespace call_chain_joiner_impl; static bool WriteCallChain(FILE* fp, pid_t pid, pid_t tid, CallChainJoiner::ChainType type, - const std::vector<uint64_t>& ips, - const std::vector<uint64_t>& sps, + const std::vector<uint64_t>& ips, const std::vector<uint64_t>& sps, size_t ip_count) { // Below is the content of a call chain stored in file. // uint32_t pid; @@ -231,8 +230,7 @@ static bool ReadCallChain(FILE* fp, pid_t& pid, pid_t& tid, CallChainJoiner::Cha static bool ReadCallChainInReverseOrder(FILE* fp, pid_t& pid, pid_t& tid, CallChainJoiner::ChainType& type, - std::vector<uint64_t>& ips, - std::vector<uint64_t>& sps) { + std::vector<uint64_t>& ips, std::vector<uint64_t>& sps) { uint32_t size; if (fseek(fp, -4, SEEK_CUR) != 0 || fread(&size, sizeof(size), 1, fp) != 1) { PLOG(ERROR) << "fread"; @@ -348,8 +346,7 @@ bool CallChainJoiner::JoinCallChains() { } std::vector<std::pair<FILE*, FILE*>> file_pairs = { std::make_pair(original_chains_fp_, tmp_fp.get()), - std::make_pair(tmp_fp.get(), joined_chains_fp_) - }; + std::make_pair(tmp_fp.get(), joined_chains_fp_)}; for (size_t pass = 0; pass < 2u; ++pass) { auto& pair = file_pairs[pass]; for (size_t i = 0; i < stat_.chain_count; ++i) { @@ -382,8 +379,7 @@ bool CallChainJoiner::JoinCallChains() { } bool CallChainJoiner::GetNextCallChain(pid_t& pid, pid_t& tid, ChainType& type, - std::vector<uint64_t>& ips, - std::vector<uint64_t>& sps) { + std::vector<uint64_t>& ips, std::vector<uint64_t>& sps) { if (next_chain_index_ == stat_.chain_count * 2) { // No more chains. return false; diff --git a/simpleperf/CallChainJoiner.h b/simpleperf/CallChainJoiner.h index 29370ee8..ecb0b8b5 100644 --- a/simpleperf/CallChainJoiner.h +++ b/simpleperf/CallChainJoiner.h @@ -72,9 +72,7 @@ class LRUCache { // Add a call chain in the cache, and extend it if possible. void AddCallChain(pid_t tid, std::vector<uint64_t>& ips, std::vector<uint64_t>& sps); - const LRUCacheStat& Stat() { - return cache_stat_; - } + const LRUCacheStat& Stat() { return cache_stat_; } CacheNode* FindNode(uint32_t tid, uint64_t ip, uint64_t sp) { CacheNode key; @@ -96,9 +94,7 @@ class LRUCache { return node->parent_index == 0u ? nullptr : nodes_ + node->parent_index; } - int GetNodeIndex(CacheNode* node) { - return node - nodes_; - } + int GetNodeIndex(CacheNode* node) { return node - nodes_; } void RemoveNodeFromLRUList(CacheNode* node) { CacheNode* prev = &nodes_[node->leaf_link_prev]; @@ -168,15 +164,10 @@ class CallChainJoiner { size_t after_join_max_chain_length = 0u; }; void DumpStat(); - const Stat& GetStat() { - return stat_; - } - const call_chain_joiner_impl::LRUCacheStat& GetCacheStat() { - return cache_stat_; - } + const Stat& GetStat() { return stat_; } + const call_chain_joiner_impl::LRUCacheStat& GetCacheStat() { return cache_stat_; } private: - bool keep_original_callchains_; FILE* original_chains_fp_; FILE* joined_chains_fp_; diff --git a/simpleperf/CallChainJoiner_test.cpp b/simpleperf/CallChainJoiner_test.cpp index f33b97d5..ae0f63b1 100644 --- a/simpleperf/CallChainJoiner_test.cpp +++ b/simpleperf/CallChainJoiner_test.cpp @@ -23,8 +23,7 @@ using namespace simpleperf; using namespace simpleperf::call_chain_joiner_impl; -static bool JoinCallChain(LRUCache& cache, uint32_t tid, - const std::vector<uint64_t>& input_ip, +static bool JoinCallChain(LRUCache& cache, uint32_t tid, const std::vector<uint64_t>& input_ip, const std::vector<uint64_t>& input_sp, const std::vector<uint64_t>& expected_output_ip, const std::vector<uint64_t>& expected_output_sp) { @@ -87,10 +86,10 @@ TEST(LRUCache, extend_chains) { // d -> c -> b // c -> b -> a => d -> c -> b -> a LRUCache cache3(sizeof(CacheNode) * 4, 2); - ASSERT_TRUE(JoinCallChain(cache3, 0, {0xb, 0xc, 0xd}, {0xb, 0xc, 0xd}, - {0xb, 0xc, 0xd}, {0xb, 0xc, 0xd})); - ASSERT_TRUE(JoinCallChain(cache3, 0, {0xa, 0xb, 0xc}, {0xa, 0xb, 0xc}, - {0xa, 0xb, 0xc, 0xd}, {0xa, 0xb, 0xc, 0xd})); + ASSERT_TRUE( + JoinCallChain(cache3, 0, {0xb, 0xc, 0xd}, {0xb, 0xc, 0xd}, {0xb, 0xc, 0xd}, {0xb, 0xc, 0xd})); + ASSERT_TRUE(JoinCallChain(cache3, 0, {0xa, 0xb, 0xc}, {0xa, 0xb, 0xc}, {0xa, 0xb, 0xc, 0xd}, + {0xa, 0xb, 0xc, 0xd})); ASSERT_EQ(cache3.Stat().used_node_count, 4u); } @@ -168,12 +167,11 @@ class CallChainJoinerTest : public ::testing::Test { TEST_F(CallChainJoinerTest, smoke) { CallChainJoiner joiner(sizeof(CacheNode) * 1024, 1, true); for (pid_t pid = 0; pid < 10; ++pid) { - ASSERT_TRUE(joiner.AddCallChain(pid, pid, CallChainJoiner::ORIGINAL_OFFLINE, - {1, 2, 3}, {1, 2, 3})); - ASSERT_TRUE(joiner.AddCallChain(pid, pid, CallChainJoiner::ORIGINAL_REMOTE, - {3, 4, 5}, {3, 4, 5})); - ASSERT_TRUE(joiner.AddCallChain(pid, pid, CallChainJoiner::ORIGINAL_OFFLINE, - {1, 4}, {1, 4})); + ASSERT_TRUE( + joiner.AddCallChain(pid, pid, CallChainJoiner::ORIGINAL_OFFLINE, {1, 2, 3}, {1, 2, 3})); + ASSERT_TRUE( + joiner.AddCallChain(pid, pid, CallChainJoiner::ORIGINAL_REMOTE, {3, 4, 5}, {3, 4, 5})); + ASSERT_TRUE(joiner.AddCallChain(pid, pid, CallChainJoiner::ORIGINAL_OFFLINE, {1, 4}, {1, 4})); } ASSERT_TRUE(joiner.JoinCallChains()); pid_t pid; @@ -200,8 +198,7 @@ TEST_F(CallChainJoinerTest, smoke) { ASSERT_TRUE(joiner.GetNextCallChain(pid, tid, type, ips, sps)); ASSERT_EQ(pid, expected_pid); ASSERT_EQ(tid, expected_pid); - ASSERT_EQ(type, i == 0u ? CallChainJoiner::ORIGINAL_REMOTE - : CallChainJoiner::JOINED_REMOTE); + ASSERT_EQ(type, i == 0u ? CallChainJoiner::ORIGINAL_REMOTE : CallChainJoiner::JOINED_REMOTE); ASSERT_EQ(ips, std::vector<uint64_t>({3, 4, 5})); ASSERT_EQ(sps, std::vector<uint64_t>({3, 4, 5})); } diff --git a/simpleperf/ETMDecoder.cpp b/simpleperf/ETMDecoder.cpp index 2d39b445..4f9d090c 100644 --- a/simpleperf/ETMDecoder.cpp +++ b/simpleperf/ETMDecoder.cpp @@ -53,7 +53,9 @@ class DecodeErrorLogger : public ocsdDefaultErrorLogger { ocsdMsgLogger msg_logger_; }; -static bool IsRespError(ocsd_datapath_resp_t resp) { return resp >= OCSD_RESP_ERR_CONT; } +static bool IsRespError(ocsd_datapath_resp_t resp) { + return resp >= OCSD_RESP_ERR_CONT; +} // Used instead of DecodeTree in OpenCSD to avoid linking decoders not for ETMV4 instruction tracing // in OpenCSD. @@ -172,9 +174,7 @@ class MapLocator : public PacketCallback { ThreadTree& GetThreadTree() { return thread_tree_; } // Return current thread id of a trace_id. If not available, return -1. - pid_t GetTid(uint8_t trace_id) const { - return trace_data_[trace_id].tid; - } + pid_t GetTid(uint8_t trace_id) const { return trace_data_[trace_id].tid; } ocsd_datapath_resp_t ProcessPacket(uint8_t trace_id, ocsd_datapath_op_t op, ocsd_trc_index_t index_sop, @@ -660,7 +660,7 @@ class ETMDecoderImpl : public ETMDecoder { InstallElementCallback(instr_range_parser_.get()); } - void RegisterCallback(const BranchListCallbackFn& callback ){ + void RegisterCallback(const BranchListCallbackFn& callback) { InstallMapLocator(); branch_list_parser_.reset(new BranchListParser(*map_locator_, callback)); branch_list_parser_->CheckConfigs(configs_); diff --git a/simpleperf/ETMRecorder.cpp b/simpleperf/ETMRecorder.cpp index 46d9b098..1a62c94a 100644 --- a/simpleperf/ETMRecorder.cpp +++ b/simpleperf/ETMRecorder.cpp @@ -19,8 +19,8 @@ #include <stdio.h> #include <sys/sysinfo.h> -#include <memory> #include <limits> +#include <memory> #include <string> #include <android-base/file.h> @@ -103,8 +103,8 @@ std::unique_ptr<EventType> ETMRecorder::BuildEventType() { if (etm_event_type == -1) { return nullptr; } - return std::make_unique<EventType>( - "cs-etm", etm_event_type, 0, "CoreSight ETM instruction tracing", "arm"); + return std::make_unique<EventType>("cs-etm", etm_event_type, 0, + "CoreSight ETM instruction tracing", "arm"); } bool ETMRecorder::CheckEtmSupport() { @@ -140,17 +140,16 @@ bool ETMRecorder::CheckEtmSupport() { bool ETMRecorder::ReadEtmInfo() { int cpu_count = get_nprocs_conf(); - for (const auto &name : GetEntriesInDir(ETM_DIR)) { + for (const auto& name : GetEntriesInDir(ETM_DIR)) { int cpu; if (sscanf(name.c_str(), "cpu%d", &cpu) == 1) { - ETMPerCpu &cpu_info = etm_info_[cpu]; - bool success = - ReadValueInEtmDir(name + "/trcidr/trcidr0", &cpu_info.trcidr0) && - ReadValueInEtmDir(name + "/trcidr/trcidr1", &cpu_info.trcidr1) && - ReadValueInEtmDir(name + "/trcidr/trcidr2", &cpu_info.trcidr2) && - ReadValueInEtmDir(name + "/trcidr/trcidr4", &cpu_info.trcidr4) && - ReadValueInEtmDir(name + "/trcidr/trcidr8", &cpu_info.trcidr8) && - ReadValueInEtmDir(name + "/mgmt/trcauthstatus", &cpu_info.trcauthstatus); + ETMPerCpu& cpu_info = etm_info_[cpu]; + bool success = ReadValueInEtmDir(name + "/trcidr/trcidr0", &cpu_info.trcidr0) && + ReadValueInEtmDir(name + "/trcidr/trcidr1", &cpu_info.trcidr1) && + ReadValueInEtmDir(name + "/trcidr/trcidr2", &cpu_info.trcidr2) && + ReadValueInEtmDir(name + "/trcidr/trcidr4", &cpu_info.trcidr4) && + ReadValueInEtmDir(name + "/trcidr/trcidr8", &cpu_info.trcidr8) && + ReadValueInEtmDir(name + "/mgmt/trcauthstatus", &cpu_info.trcauthstatus); if (!success) { return false; } @@ -160,7 +159,7 @@ bool ETMRecorder::ReadEtmInfo() { } bool ETMRecorder::FindSinkConfig() { - for (const auto &name : GetEntriesInDir(ETM_DIR + "sinks")) { + for (const auto& name : GetEntriesInDir(ETM_DIR + "sinks")) { if (name.find("etr") != -1) { if (ReadValueInEtmDir("sinks/" + name, &sink_config_)) { return true; diff --git a/simpleperf/ETMRecorder.h b/simpleperf/ETMRecorder.h index 5896c1f3..33c0f726 100644 --- a/simpleperf/ETMRecorder.h +++ b/simpleperf/ETMRecorder.h @@ -22,8 +22,8 @@ #include <memory> #include "event_type.h" -#include "record.h" #include "perf_event.h" +#include "record.h" namespace simpleperf { @@ -75,4 +75,4 @@ class ETMRecorder { std::map<int, ETMPerCpu> etm_info_; }; -} // namespace simpleperf
\ No newline at end of file +} // namespace simpleperf
\ No newline at end of file diff --git a/simpleperf/IOEventLoop.cpp b/simpleperf/IOEventLoop.cpp index 102bc6d2..b87a05d3 100644 --- a/simpleperf/IOEventLoop.cpp +++ b/simpleperf/IOEventLoop.cpp @@ -29,8 +29,7 @@ struct IOEvent { bool enabled; IOEvent(IOEventLoop* loop, const std::function<bool()>& callback) - : loop(loop), e(nullptr), timeout({}), callback(callback), enabled(false) { - } + : loop(loop), e(nullptr), timeout({}), callback(callback), enabled(false) {} ~IOEvent() { if (e != nullptr) { @@ -109,29 +108,25 @@ 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) { if (!MakeFdNonBlocking(fd)) { return nullptr; } return AddEvent(fd, EV_READ | EV_PERSIST, nullptr, callback); } -IOEventRef IOEventLoop::AddWriteEvent(int fd, - const std::function<bool()>& callback) { +IOEventRef IOEventLoop::AddWriteEvent(int fd, const std::function<bool()>& callback) { if (!MakeFdNonBlocking(fd)) { return nullptr; } return AddEvent(fd, EV_WRITE | EV_PERSIST, nullptr, callback); } -bool IOEventLoop::AddSignalEvent(int sig, - const std::function<bool()>& callback) { +bool IOEventLoop::AddSignalEvent(int sig, const std::function<bool()>& callback) { return AddEvent(sig, EV_SIGNAL | EV_PERSIST, nullptr, callback) != 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) { for (auto sig : sigs) { if (!AddSignalEvent(sig, callback)) { return false; @@ -204,8 +199,8 @@ bool IOEventLoop::DisableEvent(IOEventRef ref) { bool IOEventLoop::EnableEvent(IOEventRef ref) { if (!ref->enabled) { - timeval* timeout = (ref->timeout.tv_sec != 0 || ref->timeout.tv_usec != 0) ? - &ref->timeout : nullptr; + timeval* timeout = + (ref->timeout.tv_sec != 0 || ref->timeout.tv_usec != 0) ? &ref->timeout : nullptr; if (event_add(ref->e, timeout) != 0) { LOG(ERROR) << "event_add() failed"; return false; diff --git a/simpleperf/IOEventLoop.h b/simpleperf/IOEventLoop.h index ee9014ae..6f78d789 100644 --- a/simpleperf/IOEventLoop.h +++ b/simpleperf/IOEventLoop.h @@ -53,8 +53,7 @@ class IOEventLoop { bool AddSignalEvent(int sig, const std::function<bool()>& callback); // 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); // Register a periodic Event, so [callback] is called periodically every // [duration]. diff --git a/simpleperf/IOEventLoop_test.cpp b/simpleperf/IOEventLoop_test.cpp index 9363bbc0..546f0d77 100644 --- a/simpleperf/IOEventLoop_test.cpp +++ b/simpleperf/IOEventLoop_test.cpp @@ -140,8 +140,8 @@ void TestPeriodicEvents(int period_in_us, int iterations, bool precise) { ASSERT_TRUE(loop.RunLoop()); auto end_time = std::chrono::steady_clock::now(); ASSERT_EQ(iterations, count); - double time_used = std::chrono::duration_cast<std::chrono::duration<double>>( - end_time - start_time).count(); + double time_used = + std::chrono::duration_cast<std::chrono::duration<double>>(end_time - start_time).count(); double min_time_in_sec = period_in_us / 1e6 * iterations; double max_time_in_sec = min_time_in_sec + (precise ? 0.1 : 1); ASSERT_GE(time_used, min_time_in_sec); diff --git a/simpleperf/JITDebugReader.cpp b/simpleperf/JITDebugReader.cpp index 622c073b..f483c49d 100644 --- a/simpleperf/JITDebugReader.cpp +++ b/simpleperf/JITDebugReader.cpp @@ -70,14 +70,12 @@ struct JITDescriptor { uint32_t flags; uint32_t sizeof_descriptor; uint32_t sizeof_entry; - uint32_t action_seqlock; // incremented before and after any modification + uint32_t action_seqlock; // incremented before and after any modification uint64_t action_timestamp; // CLOCK_MONOTONIC time of last action bool Valid() const; - int AndroidVersion() const { - return magic[7] - '0'; - } + int AndroidVersion() const { return magic[7] - '0'; } }; // Match the format of JITCodeEntry in art/runtime/jit/debugger_interface.cc @@ -90,9 +88,7 @@ struct JITCodeEntry { uint64_t symfile_size; uint64_t register_timestamp; // CLOCK_MONOTONIC time of entry registration - bool Valid() const { - return symfile_addr > 0u && symfile_size > 0u; - } + bool Valid() const { return symfile_addr > 0u && symfile_size > 0u; } }; // Match the format of JITCodeEntry in art/runtime/jit/debugger_interface.cc @@ -105,9 +101,7 @@ struct __attribute__((packed)) PackedJITCodeEntry { uint64_t symfile_size; uint64_t register_timestamp; - bool Valid() const { - return symfile_addr > 0u && symfile_size > 0u; - } + bool Valid() const { return symfile_addr > 0u && symfile_size > 0u; } }; // Match the format of JITCodeEntry in art/runtime/jit/debugger_interface.cc @@ -119,11 +113,9 @@ struct JITCodeEntryV2 { ADDRT symfile_addr; uint64_t symfile_size; uint64_t register_timestamp; // CLOCK_MONOTONIC time of entry registration - uint32_t seqlock; // even value if valid + uint32_t seqlock; // even value if valid - bool Valid() const { - return (seqlock & 1) == 0; - } + bool Valid() const { return (seqlock & 1) == 0; } }; // Match the format of JITCodeEntry in art/runtime/jit/debugger_interface.cc @@ -137,9 +129,7 @@ struct __attribute__((packed)) PackedJITCodeEntryV2 { uint64_t register_timestamp; uint32_t seqlock; - bool Valid() const { - return (seqlock & 1) == 0; - } + bool Valid() const { return (seqlock & 1) == 0; } }; // Match the format of JITCodeEntry in art/runtime/jit/debugger_interface.cc @@ -154,9 +144,7 @@ struct __attribute__((packed)) PaddedJITCodeEntryV2 { uint32_t seqlock; uint32_t pad; - bool Valid() const { - return (seqlock & 1) == 0; - } + bool Valid() const { return (seqlock & 1) == 0; } }; using JITDescriptor32 = JITDescriptor<uint32_t>; @@ -254,8 +242,7 @@ class TempSymFile { uint64_t GetOffset() const { return file_offset_; } private: - TempSymFile(std::string&& path, FILE* fp) - : path_(std::move(path)), fp_(fp, fclose) {} + TempSymFile(std::string&& path, FILE* fp) : path_(std::move(path)), fp_(fp, fclose) {} const std::string path_; std::unique_ptr<FILE, decltype(&fclose)> fp_; @@ -270,7 +257,7 @@ JITDebugReader::JITDebugReader(const std::string& symfile_prefix, SymFileOption JITDebugReader::~JITDebugReader() {} bool JITDebugReader::RegisterDebugInfoCallback(IOEventLoop* loop, - const debug_info_callback_t& callback) { + const debug_info_callback_t& callback) { debug_info_callback_ = callback; read_event_ = loop->AddPeriodicEvent(SecondToTimeval(kUpdateJITDebugInfoIntervalInMs / 1000.0), [this]() { return ReadAllProcesses(); }); @@ -292,7 +279,7 @@ bool JITDebugReader::MonitorProcess(pid_t pid) { static bool IsArtLib(const std::string& filename) { return android::base::EndsWith(filename, "libart.so") || - android::base::EndsWith(filename, "libartd.so"); + android::base::EndsWith(filename, "libartd.so"); } bool JITDebugReader::UpdateRecord(const Record* record) { @@ -553,8 +540,9 @@ bool JITDebugReader::ReadRemoteMem(Process& process, uint64_t remote_addr, uint6 remote_iov.iov_len = size; ssize_t result = process_vm_readv(process.pid, &local_iov, 1, &remote_iov, 1, 0); if (static_cast<size_t>(result) != size) { - PLOG(DEBUG) << "ReadRemoteMem(" << " pid " << process.pid << ", addr " << std::hex - << remote_addr << ", size " << size << ") failed"; + PLOG(DEBUG) << "ReadRemoteMem(" + << " pid " << process.pid << ", addr " << std::hex << remote_addr << ", size " + << size << ") failed"; process.died = true; return false; } @@ -607,19 +595,19 @@ bool JITDebugReader::ReadNewCodeEntries(Process& process, const Descriptor& desc std::vector<CodeEntry>* new_code_entries) { if (descriptor.version == 1) { if (process.is_64bit) { - return ReadNewCodeEntriesImpl<JITCodeEntry64>( - process, descriptor, last_action_timestamp, read_entry_limit, new_code_entries); + return ReadNewCodeEntriesImpl<JITCodeEntry64>(process, descriptor, last_action_timestamp, + read_entry_limit, new_code_entries); } - return ReadNewCodeEntriesImpl<JITCodeEntry32>( - process, descriptor, last_action_timestamp, read_entry_limit, new_code_entries); + return ReadNewCodeEntriesImpl<JITCodeEntry32>(process, descriptor, last_action_timestamp, + read_entry_limit, new_code_entries); } if (descriptor.version == 2) { if (process.is_64bit) { - return ReadNewCodeEntriesImpl<JITCodeEntry64V2>( - process, descriptor, last_action_timestamp, read_entry_limit, new_code_entries); + return ReadNewCodeEntriesImpl<JITCodeEntry64V2>(process, descriptor, last_action_timestamp, + read_entry_limit, new_code_entries); } - return ReadNewCodeEntriesImpl<JITCodeEntry32V2>( - process, descriptor, last_action_timestamp, read_entry_limit, new_code_entries); + return ReadNewCodeEntriesImpl<JITCodeEntry32V2>(process, descriptor, last_action_timestamp, + read_entry_limit, new_code_entries); } return false; } @@ -702,9 +690,9 @@ bool JITDebugReader::ReadJITCodeDebugInfo(Process& process, debug_info->emplace_back(process.pid, jit_entry.timestamp, symbol.vaddr, symbol.len, symfile->GetPath() + location_in_file, file_offset); - LOG(VERBOSE) << "JITSymbol " << symbol.name << " at [" << std::hex << symbol.vaddr - << " - " << (symbol.vaddr + symbol.len) << " with size " << symbol.len - << " in " << symfile->GetPath() << location_in_file; + LOG(VERBOSE) << "JITSymbol " << symbol.name << " at [" << std::hex << symbol.vaddr << " - " + << (symbol.vaddr + symbol.len) << " with size " << symbol.len << " in " + << symfile->GetPath() << location_in_file; }; ElfStatus status; auto elf = ElfFile::Open(data.data(), jit_entry.symfile_size, &status); @@ -739,9 +727,9 @@ TempSymFile* JITDebugReader::GetTempSymFile(Process& process, const CodeEntry& j return zygote_symfile_.get(); } if (!app_symfile_) { - std::string path = symfile_prefix_ + "_" + kJITAppCacheFile; - app_symfile_ = - TempSymFile::Create(std::move(path), symfile_option_ == SymFileOption::kDropSymFiles); + std::string path = symfile_prefix_ + "_" + kJITAppCacheFile; + app_symfile_ = + TempSymFile::Create(std::move(path), symfile_option_ == SymFileOption::kDropSymFiles); } return app_symfile_.get(); } @@ -754,12 +742,10 @@ void JITDebugReader::ReadDexFileDebugInfo(Process& process, process.died = true; return; } - auto comp = [](const ThreadMmap& map, uint64_t addr) { - return map.start_addr <= addr; - }; + auto comp = [](const ThreadMmap& map, uint64_t addr) { return map.start_addr <= addr; }; for (auto& dex_entry : dex_entries) { - auto it = std::lower_bound(thread_mmaps.begin(), thread_mmaps.end(), - dex_entry.symfile_addr, comp); + auto it = + std::lower_bound(thread_mmaps.begin(), thread_mmaps.end(), dex_entry.symfile_addr, comp); if (it == thread_mmaps.begin()) { continue; } @@ -785,14 +771,14 @@ void JITDebugReader::ReadDexFileDebugInfo(Process& process, uint64_t dex_file_offset = dex_entry.symfile_addr - it->start_addr + it->pgoff; debug_info->emplace_back(process.pid, dex_entry.timestamp, dex_file_offset, file_path, extracted_dex_file_map); - LOG(VERBOSE) << "DexFile " << file_path << "+" << std::hex << dex_file_offset - << " in map [" << it->start_addr << " - " << (it->start_addr + it->len) - << "] with size " << dex_entry.symfile_size; + LOG(VERBOSE) << "DexFile " << file_path << "+" << std::hex << dex_file_offset << " in map [" + << it->start_addr << " - " << (it->start_addr + it->len) << "] with size " + << dex_entry.symfile_size; } } bool JITDebugReader::AddDebugInfo(const std::vector<JITDebugInfo>& debug_info, - bool sync_kernel_records) { + bool sync_kernel_records) { if (!debug_info.empty()) { if (sync_option_ == SyncOption::kSyncWithRecords) { for (auto& info : debug_info) { diff --git a/simpleperf/JITDebugReader.h b/simpleperf/JITDebugReader.h index a890299a..72f3790b 100644 --- a/simpleperf/JITDebugReader.h +++ b/simpleperf/JITDebugReader.h @@ -30,8 +30,8 @@ #include <android-base/file.h> #include <android-base/logging.h> -#include "environment.h" #include "IOEventLoop.h" +#include "environment.h" #include "record.h" namespace simpleperf { @@ -85,9 +85,7 @@ struct JITDebugInfo { file_offset(0), extracted_dex_file_map(extracted_dex_file_map) {} - bool operator>(const JITDebugInfo& other) const { - return timestamp > other.timestamp; - } + bool operator>(const JITDebugInfo& other) const { return timestamp > other.timestamp; } }; class TempSymFile; @@ -102,7 +100,7 @@ class JITDebugReader { }; enum class SyncOption { - kNoSync, // Don't sync debug info with records. + kNoSync, // Don't sync debug info with records. kSyncWithRecords, // Sync debug info with records based on monotonic timestamp. }; @@ -113,9 +111,7 @@ class JITDebugReader { ~JITDebugReader(); - bool SyncWithRecords() const { - return sync_option_ == SyncOption::kSyncWithRecords; - } + bool SyncWithRecords() const { return sync_option_ == SyncOption::kSyncWithRecords; } typedef std::function<bool(const std::vector<JITDebugInfo>&, bool)> debug_info_callback_t; bool RegisterDebugInfoCallback(IOEventLoop* loop, const debug_info_callback_t& callback); @@ -148,7 +144,7 @@ class JITDebugReader { struct Descriptor { DescriptorType type; int version = 0; - uint32_t action_seqlock = 0; // incremented before and after any modification + uint32_t action_seqlock = 0; // incremented before and after any modification uint64_t action_timestamp = 0; // CLOCK_MONOTONIC time of last action uint64_t first_entry_addr = 0; }; @@ -196,8 +192,7 @@ 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 is_64bit); 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); @@ -213,10 +208,10 @@ class JITDebugReader { std::vector<CodeEntry>* new_code_entries); bool ReadJITCodeDebugInfo(Process& process, const std::vector<CodeEntry>& jit_entries, - std::vector<JITDebugInfo>* debug_info); + std::vector<JITDebugInfo>* debug_info); TempSymFile* GetTempSymFile(Process& process, const CodeEntry& jit_entry); void ReadDexFileDebugInfo(Process& process, const std::vector<CodeEntry>& dex_entries, - std::vector<JITDebugInfo>* debug_info); + std::vector<JITDebugInfo>* debug_info); bool AddDebugInfo(const std::vector<JITDebugInfo>& debug_info, bool sync_kernel_records); const std::string symfile_prefix_; @@ -241,6 +236,6 @@ class JITDebugReader { std::unique_ptr<TempSymFile> zygote_symfile_; }; -} //namespace simpleperf +} // namespace simpleperf -#endif // SIMPLE_PERF_JIT_DEBUG_READER_H_ +#endif // SIMPLE_PERF_JIT_DEBUG_READER_H_ diff --git a/simpleperf/OfflineUnwinder.cpp b/simpleperf/OfflineUnwinder.cpp index 7bf71abd..3472a860 100644 --- a/simpleperf/OfflineUnwinder.cpp +++ b/simpleperf/OfflineUnwinder.cpp @@ -38,15 +38,16 @@ #include <unwindstack/UserX86.h> #include <unwindstack/UserX86_64.h> -#include "environment.h" #include "JITDebugReader.h" #include "OfflineUnwinder_impl.h" +#include "environment.h" #include "perf_regs.h" #include "read_apk.h" #include "thread_tree.h" static_assert(simpleperf::map_flags::PROT_JIT_SYMFILE_MAP == - unwindstack::MAPS_FLAGS_JIT_SYMFILE_MAP, ""); + unwindstack::MAPS_FLAGS_JIT_SYMFILE_MAP, + ""); namespace simpleperf { @@ -58,8 +59,8 @@ unwindstack::Regs* OfflineUnwinderImpl::GetBacktraceRegs(const RegSet& regs) { case ARCH_ARM: { unwindstack::arm_user_regs arm_user_regs; memset(&arm_user_regs, 0, sizeof(arm_user_regs)); - static_assert( - static_cast<int>(unwindstack::ARM_REG_R0) == static_cast<int>(PERF_REG_ARM_R0), ""); + static_assert(static_cast<int>(unwindstack::ARM_REG_R0) == static_cast<int>(PERF_REG_ARM_R0), + ""); static_assert( static_cast<int>(unwindstack::ARM_REG_LAST) == static_cast<int>(PERF_REG_ARM_MAX), ""); for (size_t i = unwindstack::ARM_REG_R0; i < unwindstack::ARM_REG_LAST; ++i) { @@ -188,9 +189,8 @@ void UnwindMaps::UpdateMaps(const MapSet& map_set) { maps_.begin()); } - std::sort(entries_.begin(), entries_.end(), [](const auto& e1, const auto& e2) { - return e1->start_addr < e2->start_addr; - }); + std::sort(entries_.begin(), entries_.end(), + [](const auto& e1, const auto& e2) { return e1->start_addr < e2->start_addr; }); // Use Sort() to sort maps_ and create prev_real_map links. // prev_real_map is needed by libunwindstack to find the start of an embedded lib in an apk. // See http://b/120981155. diff --git a/simpleperf/OfflineUnwinder.h b/simpleperf/OfflineUnwinder.h index 26609048..7aa417e2 100644 --- a/simpleperf/OfflineUnwinder.h +++ b/simpleperf/OfflineUnwinder.h @@ -61,9 +61,7 @@ class OfflineUnwinder { size_t stack_size, std::vector<uint64_t>* ips, std::vector<uint64_t>* sps) = 0; - const UnwindingResult& GetUnwindingResult() const { - return unwinding_result_; - } + const UnwindingResult& GetUnwindingResult() const { return unwinding_result_; } bool IsCallChainBrokenForIncompleteJITDebugInfo() { return is_callchain_broken_for_incomplete_jit_debug_info_; @@ -79,6 +77,6 @@ class OfflineUnwinder { bool is_callchain_broken_for_incomplete_jit_debug_info_ = false; }; -} // namespace simpleperf +} // namespace simpleperf #endif // SIMPLE_PERF_OFFLINE_UNWINDER_H_ diff --git a/simpleperf/RecordReadThread.cpp b/simpleperf/RecordReadThread.cpp index 18bc84ba..16af9292 100644 --- a/simpleperf/RecordReadThread.cpp +++ b/simpleperf/RecordReadThread.cpp @@ -33,17 +33,16 @@ static constexpr size_t kDefaultLowBufferLevel = 10 * 1024 * 1024u; static constexpr size_t kDefaultCriticalBufferLevel = 5 * 1024 * 1024u; RecordBuffer::RecordBuffer(size_t buffer_size) - : read_head_(0), write_head_(0), buffer_size_(buffer_size), buffer_(new char[buffer_size]) { -} + : read_head_(0), write_head_(0), buffer_size_(buffer_size), buffer_(new char[buffer_size]) {} size_t RecordBuffer::GetFreeSize() const { - size_t write_head = write_head_.load(std::memory_order_relaxed); - size_t read_head = read_head_.load(std::memory_order_relaxed); - size_t write_tail = read_head > 0 ? read_head - 1 : buffer_size_ - 1; - if (write_head <= write_tail) { - return write_tail - write_head; - } - return buffer_size_ - write_head + write_tail; + size_t write_head = write_head_.load(std::memory_order_relaxed); + size_t read_head = read_head_.load(std::memory_order_relaxed); + size_t write_tail = read_head > 0 ? read_head - 1 : buffer_size_ - 1; + if (write_head <= write_tail) { + return write_tail - write_head; + } + return buffer_size_ - write_head + write_tail; } char* RecordBuffer::AllocWriteSpace(size_t record_size) { @@ -121,13 +120,13 @@ RecordParser::RecordParser(const perf_event_attr& attr) pos += sizeof(uint64_t); } mask = PERF_SAMPLE_ADDR | PERF_SAMPLE_ID | PERF_SAMPLE_STREAM_ID | PERF_SAMPLE_CPU | - PERF_SAMPLE_PERIOD; + PERF_SAMPLE_PERIOD; pos += __builtin_popcountll(sample_type_ & mask) * sizeof(uint64_t); callchain_pos_in_sample_records_ = pos; if ((sample_type_ & PERF_SAMPLE_TIME) && attr.sample_id_all) { mask = PERF_SAMPLE_IDENTIFIER | PERF_SAMPLE_CPU | PERF_SAMPLE_STREAM_ID | PERF_SAMPLE_ID; - time_rpos_in_non_sample_records_ = (__builtin_popcountll(sample_type_ & mask) + 1) * - sizeof(uint64_t); + time_rpos_in_non_sample_records_ = + (__builtin_popcountll(sample_type_ & mask) + 1) * sizeof(uint64_t); } } @@ -143,7 +142,7 @@ size_t RecordParser::GetTimePos(const perf_event_header& header) const { } size_t RecordParser::GetStackSizePos( - const std::function<void(size_t,size_t,void*)>& read_record_fn) const{ + const std::function<void(size_t, size_t, void*)>& read_record_fn) const { size_t pos = callchain_pos_in_sample_records_; if (sample_type_ & PERF_SAMPLE_CALLCHAIN) { uint64_t ip_nr; @@ -426,10 +425,9 @@ bool RecordReadThread::HandleAddEventFds(IOEventLoop& loop, bool RecordReadThread::HandleRemoveEventFds(const std::vector<EventFd*>& event_fds) { for (auto& event_fd : event_fds) { if (event_fd->HasMappedBuffer()) { - auto it = std::find_if(kernel_record_readers_.begin(), kernel_record_readers_.end(), - [&](const KernelRecordReader& reader) { - return reader.GetEventFd() == event_fd; - }); + auto it = std::find_if( + kernel_record_readers_.begin(), kernel_record_readers_.end(), + [&](const KernelRecordReader& reader) { return reader.GetEventFd() == event_fd; }); if (it != kernel_record_readers_.end()) { kernel_record_readers_.erase(it); event_fd->StopPolling(); @@ -521,10 +519,10 @@ void RecordReadThread::PushRecordToRecordBuffer(KernelRecordReader* kernel_recor // the call chain joiner can complete the callchains. stack_size_limit = 1024; } - size_t stack_size_pos = record_parser_.GetStackSizePos( - [&](size_t pos, size_t size, void* dest) { + size_t stack_size_pos = + record_parser_.GetStackSizePos([&](size_t pos, size_t size, void* dest) { return kernel_record_reader->ReadRecord(pos, size, dest); - }); + }); uint64_t stack_size; kernel_record_reader->ReadRecord(stack_size_pos, sizeof(stack_size), &stack_size); if (stack_size > 0) { diff --git a/simpleperf/RecordReadThread.h b/simpleperf/RecordReadThread.h index e991fff0..321dc8c5 100644 --- a/simpleperf/RecordReadThread.h +++ b/simpleperf/RecordReadThread.h @@ -75,7 +75,7 @@ class RecordParser { // Return pos of the time field in the record. If not available, return 0. size_t GetTimePos(const perf_event_header& header) const; // Return pos of the user stack size field in the sample record. If not available, return 0. - size_t GetStackSizePos(const std::function<void(size_t,size_t,void*)>& read_record_fn) const; + size_t GetStackSizePos(const std::function<void(size_t, size_t, void*)>& read_record_fn) const; private: uint64_t sample_type_; @@ -127,8 +127,8 @@ class KernelRecordReader { class RecordReadThread { public: RecordReadThread(size_t record_buffer_size, const perf_event_attr& attr, size_t min_mmap_pages, - size_t max_mmap_pages, size_t aux_buffer_size, - bool allow_cutting_samples = true, bool exclude_perf = false); + size_t max_mmap_pages, size_t aux_buffer_size, bool allow_cutting_samples = true, + bool exclude_perf = false); ~RecordReadThread(); void SetBufferLevels(size_t record_buffer_low_level, size_t record_buffer_critical_level) { record_buffer_low_level_ = record_buffer_low_level; diff --git a/simpleperf/RecordReadThread_test.cpp b/simpleperf/RecordReadThread_test.cpp index 8d7f6ac4..71c8e287 100644 --- a/simpleperf/RecordReadThread_test.cpp +++ b/simpleperf/RecordReadThread_test.cpp @@ -74,8 +74,8 @@ TEST_F(RecordBufferTest, fifo) { } TEST(RecordParser, smoke) { - std::unique_ptr<RecordFileReader> reader = RecordFileReader::CreateInstance( - GetTestData(PERF_DATA_NO_UNWIND)); + std::unique_ptr<RecordFileReader> reader = + RecordFileReader::CreateInstance(GetTestData(PERF_DATA_NO_UNWIND)); ASSERT_TRUE(reader); RecordParser parser(*reader->AttrSection()[0].attr); auto process_record = [&](std::unique_ptr<Record> record) { @@ -143,8 +143,10 @@ static perf_event_attr CreateFakeEventAttr() { return CreateDefaultPerfEventAttr(*type); } -static std::vector<std::unique_ptr<Record>> CreateFakeRecords( - const perf_event_attr& attr, size_t record_count, size_t stack_size, size_t dyn_stack_size) { +static std::vector<std::unique_ptr<Record>> CreateFakeRecords(const perf_event_attr& attr, + size_t record_count, + size_t stack_size, + size_t dyn_stack_size) { std::vector<std::unique_ptr<Record>> records; for (size_t i = 0; i < record_count; ++i) { SampleRecord* r = new SampleRecord(attr, i, i + 1, i + 2, i + 3, i + 4, i + 5, i + 6, {}, @@ -164,8 +166,8 @@ static size_t AlignToPowerOfTwo(size_t value) { static inline std::function<bool(size_t&)> SetArg(size_t value) { return [value](size_t& arg) { - arg = value; - return true; + arg = value; + return true; }; } @@ -190,7 +192,8 @@ TEST(KernelRecordReader, smoke) { MockEventFd event_fd(attr, 0, buffer.data(), buffer.size(), false); EXPECT_CALL(event_fd, GetAvailableMmapDataSize(Truly(SetArg(data_pos)))) - .Times(1).WillOnce(Return(data_size)); + .Times(1) + .WillOnce(Return(data_size)); EXPECT_CALL(event_fd, DiscardMmapData(Eq(data_size))).Times(1); KernelRecordReader reader(&event_fd); RecordParser parser(attr); @@ -228,7 +231,8 @@ class RecordReadThreadTest : public ::testing::Test { event_fds_[i].reset(new MockEventFd(attr, i, buffers_[i].data(), buffer_size, false)); EXPECT_CALL(*event_fds_[i], CreateMappedBuffer(_, _)).Times(1).WillOnce(Return(true)); EXPECT_CALL(*event_fds_[i], StartPolling(_, _)).Times(1).WillOnce(Return(true)); - EXPECT_CALL(*event_fds_[i], GetAvailableMmapDataSize(Truly(SetArg(0)))).Times(1) + EXPECT_CALL(*event_fds_[i], GetAvailableMmapDataSize(Truly(SetArg(0)))) + .Times(1) .WillOnce(Return(data_size)); EXPECT_CALL(*event_fds_[i], DiscardMmapData(Eq(data_size))).Times(1); EXPECT_CALL(*event_fds_[i], StopPolling()).Times(1).WillOnce(Return(true)); diff --git a/simpleperf/SampleComparator.h b/simpleperf/SampleComparator.h index 429821ea..7c2a53be 100644 --- a/simpleperf/SampleComparator.h +++ b/simpleperf/SampleComparator.h @@ -56,10 +56,8 @@ BUILD_COMPARE_VALUE_FUNCTION_REVERSE(CompareSampleCount, sample_count); BUILD_COMPARE_STRING_FUNCTION(CompareComm, thread_comm); BUILD_COMPARE_STRING_FUNCTION(CompareDso, map->dso->GetReportPath().data()); BUILD_COMPARE_STRING_FUNCTION(CompareSymbol, symbol->DemangledName()); -BUILD_COMPARE_STRING_FUNCTION(CompareDsoFrom, - branch_from.map->dso->GetReportPath().data()); -BUILD_COMPARE_STRING_FUNCTION(CompareSymbolFrom, - branch_from.symbol->DemangledName()); +BUILD_COMPARE_STRING_FUNCTION(CompareDsoFrom, branch_from.map->dso->GetReportPath().data()); +BUILD_COMPARE_STRING_FUNCTION(CompareSymbolFrom, branch_from.symbol->DemangledName()); BUILD_COMPARE_VALUE_FUNCTION(CompareCallGraphDuplicated, callchain.duplicated); template <typename EntryT> @@ -82,13 +80,10 @@ class SampleComparator { public: typedef int (*compare_sample_func_t)(const EntryT*, const EntryT*); - void AddCompareFunction(compare_sample_func_t func) { - compare_v_.push_back(func); - } + void AddCompareFunction(compare_sample_func_t func) { compare_v_.push_back(func); } void AddComparator(const SampleComparator<EntryT>& other) { - compare_v_.insert(compare_v_.end(), other.compare_v_.begin(), - other.compare_v_.end()); + compare_v_.insert(compare_v_.end(), other.compare_v_.begin(), other.compare_v_.end()); } bool operator()(const EntryT* sample1, const EntryT* sample2) const { diff --git a/simpleperf/SampleDisplayer.h b/simpleperf/SampleDisplayer.h index f66b8f8d..02165944 100644 --- a/simpleperf/SampleDisplayer.h +++ b/simpleperf/SampleDisplayer.h @@ -28,8 +28,7 @@ // The display functions below are used to show items in a sample. template <typename EntryT, typename InfoT> -std::string DisplayAccumulatedOverhead(const EntryT* sample, - const InfoT* info) { +std::string DisplayAccumulatedOverhead(const EntryT* sample, const InfoT* info) { uint64_t period = sample->period + sample->accumulated_period; uint64_t total_period = info->total_period; double percentage = (total_period != 0) ? 100.0 * period / total_period : 0.0; @@ -105,8 +104,7 @@ class CallgraphDisplayer { static constexpr int SPACES_BETWEEN_CALLGRAPH_ENTRIES = 4; public: - CallgraphDisplayer(uint32_t max_stack = UINT32_MAX, - double percent_limit = 0.0, + CallgraphDisplayer(uint32_t max_stack = UINT32_MAX, double percent_limit = 0.0, bool brief_callgraph = false) : max_stack_(max_stack), percent_limit_(percent_limit), brief_callgraph_(brief_callgraph) {} @@ -132,15 +130,14 @@ class CallgraphDisplayer { } void DisplayCallGraphEntry(FILE* fp, size_t depth, std::string prefix, - const std::unique_ptr<CallChainNodeT>& node, - uint64_t parent_period, bool last) { + const std::unique_ptr<CallChainNodeT>& node, uint64_t parent_period, + bool last) { if (depth > max_stack_) { return; } std::string percentage_s = "-- "; if (node->period + node->children_period != parent_period) { - double percentage = - 100.0 * (node->period + node->children_period) / parent_period; + double percentage = 100.0 * (node->period + node->children_period) / parent_period; if (percentage < percent_limit_) { return; } @@ -164,8 +161,7 @@ class CallgraphDisplayer { } for (size_t i = 0; i < node->children.size(); ++i) { DisplayCallGraphEntry(fp, depth + 1, prefix, node->children[i], - node->children_period + node->period, - (i + 1 == node->children.size())); + node->children_period + node->period, (i + 1 == node->children.size())); } } @@ -187,10 +183,8 @@ template <typename EntryT, typename InfoT> class SampleDisplayer { public: typedef std::string (*display_sample_func_t)(const EntryT*); - typedef std::string (*display_sample_with_info_func_t)(const EntryT*, - const InfoT*); - using exclusive_display_sample_func_t = - std::function<void(FILE*, const EntryT*)>; + typedef std::string (*display_sample_with_info_func_t)(const EntryT*, const InfoT*); + using exclusive_display_sample_func_t = std::function<void(FILE*, const EntryT*)>; private: struct Item { @@ -213,8 +207,7 @@ class SampleDisplayer { display_v_.push_back(item); } - void AddDisplayFunction(const std::string& name, - display_sample_with_info_func_t func_with_info) { + void AddDisplayFunction(const std::string& name, display_sample_with_info_func_t func_with_info) { Item item; item.name = name; item.width = name.size(); @@ -232,9 +225,8 @@ class SampleDisplayer { return; } for (auto& item : display_v_) { - std::string data = (item.func != nullptr) - ? item.func(sample) - : item.func_with_info(sample, info_); + std::string data = + (item.func != nullptr) ? item.func(sample) : item.func_with_info(sample, info_); item.width = std::max(item.width, data.size()); } } @@ -257,9 +249,8 @@ class SampleDisplayer { void PrintSample(FILE* fp, const EntryT* sample) { for (size_t i = 0; i < display_v_.size(); ++i) { auto& item = display_v_[i]; - std::string data = (item.func != nullptr) - ? item.func(sample) - : item.func_with_info(sample, info_); + std::string data = + (item.func != nullptr) ? item.func(sample) : item.func_with_info(sample, info_); if (report_csv_) { if (data.find(',') == std::string::npos) { fprintf(fp, "%s", data.c_str()); diff --git a/simpleperf/app_api/cpp/simpleperf.cpp b/simpleperf/app_api/cpp/simpleperf.cpp index 74e17a3f..0ccf7ae0 100644 --- a/simpleperf/app_api/cpp/simpleperf.cpp +++ b/simpleperf/app_api/cpp/simpleperf.cpp @@ -26,9 +26,9 @@ #include <time.h> #include <unistd.h> +#include <android/log.h> #include <mutex> #include <sstream> -#include <android/log.h> namespace simpleperf { @@ -51,19 +51,18 @@ class RecordOptionsImpl { bool trace_offcpu = false; }; -RecordOptions::RecordOptions() : impl_(new RecordOptionsImpl) { -} +RecordOptions::RecordOptions() : impl_(new RecordOptionsImpl) {} RecordOptions::~RecordOptions() { delete impl_; } -RecordOptions& RecordOptions::SetOutputFilename(const std::string &filename) { +RecordOptions& RecordOptions::SetOutputFilename(const std::string& filename) { impl_->output_filename = filename; return *this; } -RecordOptions& RecordOptions::SetEvent(const std::string &event) { +RecordOptions& RecordOptions::SetEvent(const std::string& event) { impl_->event = event; return *this; } @@ -78,7 +77,7 @@ RecordOptions& RecordOptions::SetDuration(double duration_in_second) { return *this; } -RecordOptions& RecordOptions::SetSampleThreads(const std::vector<pid_t> &threads) { +RecordOptions& RecordOptions::SetSampleThreads(const std::vector<pid_t>& threads) { impl_->threads = threads; return *this; } @@ -158,8 +157,7 @@ static void Abort(const char* fmt, ...) { class ProfileSessionImpl { public: ProfileSessionImpl(const std::string& app_data_dir) - : app_data_dir_(app_data_dir), - simpleperf_data_dir_(app_data_dir + "/simpleperf_data") {} + : app_data_dir_(app_data_dir), simpleperf_data_dir_(app_data_dir + "/simpleperf_data") {} ~ProfileSessionImpl(); void StartRecording(const std::vector<std::string>& args); void PauseRecording(); @@ -202,7 +200,7 @@ ProfileSessionImpl::~ProfileSessionImpl() { } } -void ProfileSessionImpl::StartRecording(const std::vector<std::string> &args) { +void ProfileSessionImpl::StartRecording(const std::vector<std::string>& args) { std::lock_guard<std::mutex> guard(lock_); if (state_ != NOT_YET_STARTED) { Abort("startRecording: session in wrong state %d", state_); @@ -263,7 +261,7 @@ void ProfileSessionImpl::StopRecording() { void ProfileSessionImpl::SendCmd(const std::string& cmd) { std::string data = cmd + "\n"; if (TEMP_FAILURE_RETRY(write(control_fd_, &data[0], data.size())) != - static_cast<ssize_t>(data.size())) { + static_cast<ssize_t>(data.size())) { Abort("failed to send cmd to simpleperf: %s", strerror(errno)); } if (ReadReply() != "ok") { @@ -395,8 +393,8 @@ void ProfileSessionImpl::CreateSimpleperfDataDir() { } } -void ProfileSessionImpl::CreateSimpleperfProcess(const std::string &simpleperf_path, - const std::vector<std::string> &record_args) { +void ProfileSessionImpl::CreateSimpleperfProcess(const std::string& simpleperf_path, + const std::vector<std::string>& record_args) { // 1. Create control/reply pips. int control_fd[2]; int reply_fd[2]; @@ -494,12 +492,12 @@ ProfileSession::~ProfileSession() { delete impl_; } -void ProfileSession::StartRecording(const RecordOptions &options) { +void ProfileSession::StartRecording(const RecordOptions& options) { StartRecording(options.ToRecordArgs()); } -void ProfileSession::StartRecording(const std::vector<std::string> &record_args) { - impl_->StartRecording(record_args); +void ProfileSession::StartRecording(const std::vector<std::string>& record_args) { + impl_->StartRecording(record_args); } void ProfileSession::PauseRecording() { diff --git a/simpleperf/app_api/cpp/simpleperf.h b/simpleperf/app_api/cpp/simpleperf.h index 309b37b7..074b7ad0 100644 --- a/simpleperf/app_api/cpp/simpleperf.h +++ b/simpleperf/app_api/cpp/simpleperf.h @@ -153,6 +153,7 @@ class ProfileSession { * Stop recording and generate a recording file under appDataDir/simpleperf_data/. */ void StopRecording(); + private: ProfileSessionImpl* impl_; }; diff --git a/simpleperf/build_id.h b/simpleperf/build_id.h index 2a3690f8..fabf0fb5 100644 --- a/simpleperf/build_id.h +++ b/simpleperf/build_id.h @@ -17,9 +17,9 @@ #ifndef SIMPLE_PERF_BUILD_ID_H_ #define SIMPLE_PERF_BUILD_ID_H_ +#include <android-base/stringprintf.h> #include <string.h> #include <algorithm> -#include <android-base/stringprintf.h> constexpr size_t BUILD_ID_SIZE = 20; @@ -29,13 +29,9 @@ constexpr size_t BUILD_ID_SIZE = 20; // memory. class BuildId { public: - static size_t Size() { - return BUILD_ID_SIZE; - } + static size_t Size() { return BUILD_ID_SIZE; } - BuildId() { - memset(data_, '\0', BUILD_ID_SIZE); - } + BuildId() { memset(data_, '\0', BUILD_ID_SIZE); } // Copy build id from a byte array, like {0x76, 0x00, 0x32,...}. BuildId(const void* data, size_t len) : BuildId() { @@ -60,9 +56,7 @@ class BuildId { } } - const unsigned char* Data() const { - return data_; - } + const unsigned char* Data() const { return data_; } std::string ToString() const { std::string s = "0x"; @@ -76,9 +70,7 @@ class BuildId { return memcmp(data_, build_id.data_, BUILD_ID_SIZE) == 0; } - bool operator!=(const BuildId& build_id) const { - return !(*this == build_id); - } + bool operator!=(const BuildId& build_id) const { return !(*this == build_id); } bool IsEmpty() const { static BuildId empty_build_id; diff --git a/simpleperf/callchain.h b/simpleperf/callchain.h index b2a0457e..96d1e688 100644 --- a/simpleperf/callchain.h +++ b/simpleperf/callchain.h @@ -46,9 +46,8 @@ struct CallChainRoot { CallChainRoot() : duplicated(false), children_period(0) {} - void AddCallChain( - const std::vector<EntryT*>& callchain, uint64_t period, - std::function<bool(const EntryT*, const EntryT*)> is_same_sample) { + void AddCallChain(const std::vector<EntryT*>& callchain, uint64_t period, + std::function<bool(const EntryT*, const EntryT*)> is_same_sample) { children_period += period; NodeT* p = FindMatchingNode(children, callchain[0], is_same_sample); if (p == nullptr) { @@ -58,8 +57,7 @@ struct CallChainRoot { } size_t callchain_pos = 0; while (true) { - size_t match_length = - GetMatchingLengthInNode(p, callchain, callchain_pos, is_same_sample); + size_t match_length = GetMatchingLengthInNode(p, callchain, callchain_pos, is_same_sample); CHECK_GT(match_length, 0u); callchain_pos += match_length; bool find_child = true; @@ -73,15 +71,13 @@ struct CallChainRoot { } p->children_period += period; if (find_child) { - NodeT* np = FindMatchingNode(p->children, callchain[callchain_pos], - is_same_sample); + NodeT* np = FindMatchingNode(p->children, callchain[callchain_pos], is_same_sample); if (np != nullptr) { p = np; continue; } } - std::unique_ptr<NodeT> new_node = - AllocateNode(callchain, callchain_pos, period, 0); + std::unique_ptr<NodeT> new_node = AllocateNode(callchain, callchain_pos, period, 0); p->children.push_back(std::move(new_node)); break; } @@ -103,9 +99,8 @@ struct CallChainRoot { } private: - NodeT* FindMatchingNode( - const std::vector<std::unique_ptr<NodeT>>& nodes, const EntryT* sample, - std::function<bool(const EntryT*, const EntryT*)> is_same_sample) { + NodeT* FindMatchingNode(const std::vector<std::unique_ptr<NodeT>>& nodes, const EntryT* sample, + std::function<bool(const EntryT*, const EntryT*)> is_same_sample) { for (auto& node : nodes) { if (is_same_sample(node->chain.front(), sample)) { return node.get(); @@ -114,12 +109,10 @@ struct CallChainRoot { return nullptr; } - size_t GetMatchingLengthInNode( - NodeT* node, const std::vector<EntryT*>& chain, size_t chain_start, - std::function<bool(const EntryT*, const EntryT*)> is_same_sample) { + size_t GetMatchingLengthInNode(NodeT* node, const std::vector<EntryT*>& chain, size_t chain_start, + std::function<bool(const EntryT*, const EntryT*)> is_same_sample) { size_t i, j; - for (i = 0, j = chain_start; i < node->chain.size() && j < chain.size(); - ++i, ++j) { + for (i = 0, j = chain_start; i < node->chain.size() && j < chain.size(); ++i, ++j) { if (!is_same_sample(node->chain[i], chain[j])) { break; } @@ -128,8 +121,8 @@ struct CallChainRoot { } void SplitNode(NodeT* parent, size_t parent_length) { - std::unique_ptr<NodeT> child = AllocateNode( - parent->chain, parent_length, parent->period, parent->children_period); + std::unique_ptr<NodeT> child = + AllocateNode(parent->chain, parent_length, parent->period, parent->children_period); child->children = std::move(parent->children); parent->period = 0; parent->children_period = child->period + child->children_period; @@ -138,9 +131,8 @@ struct CallChainRoot { parent->children.push_back(std::move(child)); } - std::unique_ptr<NodeT> AllocateNode(const std::vector<EntryT*>& chain, - size_t chain_start, uint64_t period, - uint64_t children_period) { + std::unique_ptr<NodeT> AllocateNode(const std::vector<EntryT*>& chain, size_t chain_start, + uint64_t period, uint64_t children_period) { std::unique_ptr<NodeT> node(new NodeT); for (size_t i = chain_start; i < chain.size(); ++i) { node->chain.push_back(chain[i]); diff --git a/simpleperf/cmd_api.cpp b/simpleperf/cmd_api.cpp index e7226970..f875894a 100644 --- a/simpleperf/cmd_api.cpp +++ b/simpleperf/cmd_api.cpp @@ -30,8 +30,8 @@ #include "cmd_api_impl.h" #include "command.h" -#include "event_type.h" #include "environment.h" +#include "event_type.h" #include "utils.h" #include "workload.h" @@ -43,9 +43,8 @@ const std::string SIMPLEPERF_DATA_DIR = "simpleperf_data"; class PrepareCommand : public Command { public: PrepareCommand() - : Command("api-prepare", "Prepare recording via app api", - "Usage: simpleperf api-prepare\n" - ) {} + : Command("api-prepare", "Prepare recording via app api", "Usage: simpleperf api-prepare\n") { + } bool Run(const std::vector<std::string>& args); }; @@ -74,7 +73,8 @@ class CollectCommand : public Command { "--stop-signal-fd <fd> Stop recording when fd is readable.\n" #endif // clang-format on - ) {} + ) { + } bool Run(const std::vector<std::string>& args); private: @@ -153,8 +153,8 @@ void CollectCommand::HandleStopSignal() { } bool CollectCommand::CollectRecordingData() { - std::unique_ptr<FILE, decltype(&fclose)> fp(android::base::Fdopen(std::move(out_fd_), "w"), - fclose); + std::unique_ptr<FILE, decltype(&fclose)> fp(android::base::Fdopen(std::move(out_fd_), "w"), + fclose); if (fp == nullptr) { PLOG(ERROR) << "failed to call fdopen"; return false; @@ -217,10 +217,8 @@ bool CollectCommand::RemoveRecordingData() { namespace simpleperf { void RegisterAPICommands() { - RegisterCommand("api-prepare", - []{ return std::unique_ptr<Command>(new PrepareCommand()); }); - RegisterCommand("api-collect", - []{ return std::unique_ptr<Command>(new CollectCommand()); }); + RegisterCommand("api-prepare", [] { return std::unique_ptr<Command>(new PrepareCommand()); }); + RegisterCommand("api-collect", [] { return std::unique_ptr<Command>(new CollectCommand()); }); } } // namespace simpleperf diff --git a/simpleperf/cmd_debug_unwind.cpp b/simpleperf/cmd_debug_unwind.cpp index 2baf4860..481e24f8 100644 --- a/simpleperf/cmd_debug_unwind.cpp +++ b/simpleperf/cmd_debug_unwind.cpp @@ -27,9 +27,9 @@ #include <android-base/strings.h> #include "CallChainJoiner.h" +#include "OfflineUnwinder.h" #include "command.h" #include "environment.h" -#include "OfflineUnwinder.h" #include "perf_regs.h" #include "record_file.h" #include "thread_tree.h" @@ -56,7 +56,7 @@ struct MemStat { static bool GetMemStat(MemStat* stat) { std::string s; if (!android::base::ReadFileToString(android::base::StringPrintf("/proc/%d/status", getpid()), - &s)) { + &s)) { PLOG(ERROR) << "Failed to read process status"; return false; } @@ -91,13 +91,12 @@ class DebugUnwindCommand : public Command { "--symfs <dir> Look for files with symbols relative to this directory.\n" "--time time Only unwind samples recorded at selected time.\n" // clang-format on - ), - input_filename_("perf.data"), - output_filename_("perf.data.debug"), - offline_unwinder_(OfflineUnwinder::Create(true)), - callchain_joiner_(DEFAULT_CALL_CHAIN_JOINER_CACHE_SIZE, 1, true), - selected_time_(0) { - } + ), + input_filename_("perf.data"), + output_filename_("perf.data.debug"), + offline_unwinder_(OfflineUnwinder::Create(true)), + callchain_joiner_(DEFAULT_CALL_CHAIN_JOINER_CACHE_SIZE, 1, true), + selected_time_(0) {} bool Run(const std::vector<std::string>& args); @@ -190,7 +189,7 @@ bool DebugUnwindCommand::UnwindRecordFile() { std::string record_cmd = android::base::Join(reader_->ReadCmdlineFeature(), " "); if (record_cmd.find("--no-unwind") == std::string::npos || (record_cmd.find("-g") == std::string::npos && - record_cmd.find("--call-graph dwarf") == std::string::npos)) { + record_cmd.find("--call-graph dwarf") == std::string::npos)) { LOG(ERROR) << input_filename_ << " isn't recorded with \"-g --no-unwind\""; return false; } @@ -207,9 +206,7 @@ bool DebugUnwindCommand::UnwindRecordFile() { if (!GetMemStat(&stat_.mem_before_unwinding)) { return false; } - auto callback = [this](std::unique_ptr<Record> record) { - return ProcessRecord(record.get()); - }; + auto callback = [this](std::unique_ptr<Record> record) { return ProcessRecord(record.get()); }; if (!reader_->ReadDataSection(callback)) { return false; } @@ -238,15 +235,15 @@ bool DebugUnwindCommand::ProcessRecord(Record* record) { std::vector<uint64_t> ips; std::vector<uint64_t> sps; if (!offline_unwinder_->UnwindCallChain(*thread, regs, r.stack_user_data.data, - r.GetValidStackSize(), &ips, &sps)) { + r.GetValidStackSize(), &ips, &sps)) { return false; } const UnwindingResult& unwinding_result = offline_unwinder_->GetUnwindingResult(); stat_.unwinding_sample_count++; stat_.total_unwinding_time_in_ns += unwinding_result.used_time; - stat_.max_unwinding_time_in_ns = std::max(stat_.max_unwinding_time_in_ns, - unwinding_result.used_time); + stat_.max_unwinding_time_in_ns = + std::max(stat_.max_unwinding_time_in_ns, unwinding_result.used_time); if (!writer_->WriteRecord(UnwindingResultRecord(r.time_data.time, unwinding_result))) { return false; } @@ -388,10 +385,11 @@ bool DebugUnwindCommand::WriteFeatureSections() { void DebugUnwindCommand::PrintStat() { printf("Unwinding sample count: %" PRIu64 "\n", stat_.unwinding_sample_count); if (stat_.unwinding_sample_count > 0u) { - printf("Average unwinding time: %f us\n", static_cast<double>(stat_.total_unwinding_time_in_ns) - / 1000 / stat_.unwinding_sample_count); - printf("Max unwinding time: %f us\n", static_cast<double>(stat_.max_unwinding_time_in_ns) - / 1000); + printf("Average unwinding time: %f us\n", + static_cast<double>(stat_.total_unwinding_time_in_ns) / 1000 / + stat_.unwinding_sample_count); + printf("Max unwinding time: %f us\n", + static_cast<double>(stat_.max_unwinding_time_in_ns) / 1000); } printf("Memory change:\n"); PrintIndented(1, "VmPeak: %s -> %s\n", stat_.mem_before_unwinding.vm_peak.c_str(), @@ -410,7 +408,7 @@ namespace simpleperf { void RegisterDebugUnwindCommand() { RegisterCommand("debug-unwind", - []{ return std::unique_ptr<Command>(new DebugUnwindCommand()); }); + [] { return std::unique_ptr<Command>(new DebugUnwindCommand()); }); } } // namespace simpleperf diff --git a/simpleperf/cmd_debug_unwind_test.cpp b/simpleperf/cmd_debug_unwind_test.cpp index 8b65d424..4494d8d7 100644 --- a/simpleperf/cmd_debug_unwind_test.cpp +++ b/simpleperf/cmd_debug_unwind_test.cpp @@ -44,8 +44,8 @@ TEST(cmd_debug_unwind, smoke) { ASSERT_NE(capture.Finish().find("Unwinding sample count: 8"), std::string::npos); ASSERT_TRUE(capture.Start()); - ASSERT_TRUE(DebugUnwindCmd()->Run({"-i", input_data, "-o", tmp_file.path, "--time", - "1516379654300997"})); + ASSERT_TRUE( + DebugUnwindCmd()->Run({"-i", input_data, "-o", tmp_file.path, "--time", "1516379654300997"})); ASSERT_NE(capture.Finish().find("Unwinding sample count: 1"), std::string::npos); } @@ -54,8 +54,8 @@ TEST(cmd_debug_unwind, symfs_option) { CaptureStdout capture; TemporaryFile tmp_file; ASSERT_TRUE(capture.Start()); - ASSERT_TRUE(DebugUnwindCmd()->Run({"-i", input_data, "-o", tmp_file.path, "--symfs", - GetTestDataDir()})); + ASSERT_TRUE( + DebugUnwindCmd()->Run({"-i", input_data, "-o", tmp_file.path, "--symfs", GetTestDataDir()})); ASSERT_NE(capture.Finish().find("Unwinding sample count: 55"), std::string::npos); std::unique_ptr<RecordFileReader> reader = RecordFileReader::CreateInstance(tmp_file.path); ASSERT_TRUE(reader); @@ -70,8 +70,8 @@ TEST(cmd_debug_unwind, unwind_with_ip_zero_in_callchain) { TemporaryFile tmp_file; CaptureStdout capture; ASSERT_TRUE(capture.Start()); - ASSERT_TRUE(DebugUnwindCmd()->Run({"-i", GetTestData(PERF_DATA_WITH_IP_ZERO_IN_CALLCHAIN), - "-o", tmp_file.path})); + ASSERT_TRUE(DebugUnwindCmd()->Run( + {"-i", GetTestData(PERF_DATA_WITH_IP_ZERO_IN_CALLCHAIN), "-o", tmp_file.path})); ASSERT_NE(capture.Finish().find("Unwinding sample count: 1"), std::string::npos); } @@ -85,8 +85,8 @@ TEST(cmd_debug_unwind, unwind_embedded_lib_in_apk) { "--symfs", GetTestDataDir(), "-o", tmp_file.path})); CaptureStdout capture; ASSERT_TRUE(capture.Start()); - ASSERT_TRUE(CreateCommandInstance("report-sample")->Run( - {"--show-callchain", "-i", tmp_file.path})); + ASSERT_TRUE( + CreateCommandInstance("report-sample")->Run({"--show-callchain", "-i", tmp_file.path})); std::string output = capture.Finish(); ASSERT_NE(output.find("libnative-lib.so"), std::string::npos); ASSERT_NE(output.find("libc.so"), std::string::npos); diff --git a/simpleperf/cmd_dumprecord.cpp b/simpleperf/cmd_dumprecord.cpp index 148be69c..86860f71 100644 --- a/simpleperf/cmd_dumprecord.cpp +++ b/simpleperf/cmd_dumprecord.cpp @@ -25,9 +25,9 @@ #include <android-base/stringprintf.h> #include <android-base/strings.h> +#include "ETMDecoder.h" #include "command.h" #include "dso.h" -#include "ETMDecoder.h" #include "event_attr.h" #include "event_type.h" #include "perf_regs.h" @@ -47,8 +47,7 @@ struct SymbolInfo { uint64_t vaddr_in_file; }; -using ExtractFieldFn = - std::function<std::string(const TracingField&, const PerfSampleRawType&)>; +using ExtractFieldFn = std::function<std::string(const TracingField&, const PerfSampleRawType&)>; struct EventInfo { size_t tp_data_size = 0; @@ -154,17 +153,25 @@ ExtractFieldFn GetExtractFieldFunction(const TracingField& field) { } if (field.elem_count == 1) { switch (field.elem_size) { - case 1: return ExtractIntField<int8_t>; - case 2: return ExtractIntField<int16_t>; - case 4: return ExtractIntField<int32_t>; - case 8: return ExtractIntField<int64_t>; + case 1: + return ExtractIntField<int8_t>; + case 2: + return ExtractIntField<int16_t>; + case 4: + return ExtractIntField<int32_t>; + case 8: + return ExtractIntField<int64_t>; } } else { switch (field.elem_size) { - case 1: return ExtractIntArrayField<int8_t>; - case 2: return ExtractIntArrayField<int16_t>; - case 4: return ExtractIntArrayField<int32_t>; - case 8: return ExtractIntArrayField<int64_t>; + case 1: + return ExtractIntArrayField<int8_t>; + case 2: + return ExtractIntArrayField<int16_t>; + case 4: + return ExtractIntArrayField<int32_t>; + case 8: + return ExtractIntArrayField<int64_t>; } } return ExtractUnknownField; @@ -180,7 +187,7 @@ class DumpRecordCommand : public Command { "--dump-etm type1,type2,... Dump etm data. A type is one of raw, packet and element.\n" "--symdir <dir> Look for binaries in a directory recursively.\n" // clang-format on - ) {} + ) {} bool Run(const std::vector<std::string>& args); @@ -273,7 +280,7 @@ void DumpRecordCommand::DumpFileHeader() { printf("attr_size: %" PRId64 "\n", header.attr_size); if (header.attr_size != sizeof(FileAttr)) { LOG(WARNING) << "record file attr size " << header.attr_size - << " doesn't match expected attr size " << sizeof(FileAttr); + << " doesn't match expected attr size " << sizeof(FileAttr); } printf("attrs[file section]: offset %" PRId64 ", size %" PRId64 "\n", header.attrs.offset, header.attrs.size); @@ -315,9 +322,7 @@ bool DumpRecordCommand::DumpDataSection() { thread_tree_.ShowIpForUnknownSymbol(); record_file_reader_->LoadBuildIdAndFileFeatures(thread_tree_); - auto record_callback = [&](std::unique_ptr<Record> r) { - return ProcessRecord(r.get()); - }; + auto record_callback = [&](std::unique_ptr<Record> r) { return ProcessRecord(r.get()); }; return record_file_reader_->ReadDataSection(record_callback); } @@ -397,7 +402,7 @@ void DumpRecordCommand::ProcessCallChainRecord(const CallChainRecord& cr) { } SymbolInfo DumpRecordCommand::GetSymbolInfo(uint32_t pid, uint32_t tid, uint64_t ip, - bool in_kernel) { + bool in_kernel) { ThreadEntry* thread = thread_tree_.FindThreadOrNew(pid, tid); const MapEntry* map = thread_tree_.FindMap(thread, ip, in_kernel); SymbolInfo info; @@ -469,9 +474,9 @@ bool DumpRecordCommand::DumpFeatureSection() { std::vector<uint64_t> dex_file_offsets; size_t read_pos = 0; PrintIndented(1, "file:\n"); - while (record_file_reader_->ReadFileFeature(read_pos, &file_path, &file_type, - &min_vaddr, &file_offset_of_min_vaddr, - &symbols, &dex_file_offsets)) { + while (record_file_reader_->ReadFileFeature(read_pos, &file_path, &file_type, &min_vaddr, + &file_offset_of_min_vaddr, &symbols, + &dex_file_offsets)) { PrintIndented(2, "file_path %s\n", file_path.c_str()); PrintIndented(2, "file_type %s\n", DsoTypeToString(static_cast<DsoType>(file_type))); PrintIndented(2, "min_vaddr 0x%" PRIx64 "\n", min_vaddr); diff --git a/simpleperf/cmd_help.cpp b/simpleperf/cmd_help.cpp index 65bed775..8f45c62b 100644 --- a/simpleperf/cmd_help.cpp +++ b/simpleperf/cmd_help.cpp @@ -33,7 +33,7 @@ class HelpCommand : public Command { " Without subcommand, print short help string for every subcommand.\n" " With subcommand, print long help string for the subcommand.\n\n" // clang-format on - ) {} + ) {} bool Run(const std::vector<std::string>& args) override; @@ -75,7 +75,7 @@ void HelpCommand::PrintShortHelp() { " --version Print version of simpleperf.\n" "subcommands:\n" // clang-format on - ); + ); for (auto& cmd_name : GetAllCommandNames()) { std::unique_ptr<Command> cmd = CreateCommandInstance(cmd_name); printf(" %-20s%s\n", cmd_name.c_str(), cmd->ShortHelpString().c_str()); @@ -89,8 +89,7 @@ void HelpCommand::PrintLongHelpForOneCommand(const Command& command) { namespace simpleperf { void RegisterHelpCommand() { - RegisterCommand("help", - [] { return std::unique_ptr<Command>(new HelpCommand); }); + RegisterCommand("help", [] { return std::unique_ptr<Command>(new HelpCommand); }); } } // namespace simpleperf diff --git a/simpleperf/cmd_inject.cpp b/simpleperf/cmd_inject.cpp index 69b3452f..7487b21d 100644 --- a/simpleperf/cmd_inject.cpp +++ b/simpleperf/cmd_inject.cpp @@ -20,15 +20,14 @@ #include <regex> #include <string> +#include "ETMDecoder.h" #include "cmd_inject_impl.h" #include "command.h" -#include "ETMDecoder.h" #include "record_file.h" #include "system/extras/simpleperf/etm_branch_list.pb.h" #include "thread_tree.h" #include "utils.h" - using namespace simpleperf; namespace simpleperf { @@ -295,9 +294,7 @@ class InjectCommand : public Command { } // 2. Build branch map for each binary, convert them to instr ranges. - auto callback = [this](const ETMInstrRange& range) { - ProcessInstrRange(range); - }; + auto callback = [this](const ETMInstrRange& range) { ProcessInstrRange(range); }; auto check_build_id = [](Dso* dso, const BuildId& expected_build_id) { if (expected_build_id.IsEmpty()) { return true; diff --git a/simpleperf/cmd_inject_test.cpp b/simpleperf/cmd_inject_test.cpp index 64a32b87..fb264d6f 100644 --- a/simpleperf/cmd_inject_test.cpp +++ b/simpleperf/cmd_inject_test.cpp @@ -25,7 +25,9 @@ using namespace simpleperf; -static std::unique_ptr<Command> InjectCmd() { return CreateCommandInstance("inject"); } +static std::unique_ptr<Command> InjectCmd() { + return CreateCommandInstance("inject"); +} static bool RunInjectCmd(std::vector<std::string>&& args) { bool has_input = std::find(args.begin(), args.end(), "-i") != args.end(); diff --git a/simpleperf/cmd_kmem.cpp b/simpleperf/cmd_kmem.cpp index 454747b8..a4ff3d6f 100644 --- a/simpleperf/cmd_kmem.cpp +++ b/simpleperf/cmd_kmem.cpp @@ -32,19 +32,18 @@ namespace { struct SlabSample { - const Symbol* symbol; // the function making allocation - uint64_t ptr; // the start address of the allocated space - uint64_t bytes_req; // requested space size - uint64_t bytes_alloc; // allocated space size - uint64_t sample_count; // count of allocations - uint64_t gfp_flags; // flags used for allocation - uint64_t cross_cpu_allocations; // count of allocations freed not on the - // cpu allocating them + const Symbol* symbol; // the function making allocation + uint64_t ptr; // the start address of the allocated space + uint64_t bytes_req; // requested space size + uint64_t bytes_alloc; // allocated space size + uint64_t sample_count; // count of allocations + uint64_t gfp_flags; // flags used for allocation + uint64_t cross_cpu_allocations; // count of allocations freed not on the + // cpu allocating them CallChainRoot<SlabSample> callchain; // a callchain tree representing all // callchains in this sample - SlabSample(const Symbol* symbol, uint64_t ptr, uint64_t bytes_req, - uint64_t bytes_alloc, uint64_t sample_count, uint64_t gfp_flags, - uint64_t cross_cpu_allocations) + SlabSample(const Symbol* symbol, uint64_t ptr, uint64_t bytes_req, uint64_t bytes_alloc, + uint64_t sample_count, uint64_t gfp_flags, uint64_t cross_cpu_allocations) : symbol(symbol), ptr(ptr), bytes_req(bytes_req), @@ -53,9 +52,7 @@ struct SlabSample { gfp_flags(gfp_flags), cross_cpu_allocations(cross_cpu_allocations) {} - uint64_t GetPeriod() const { - return sample_count; - } + uint64_t GetPeriod() const { return sample_count; } }; struct SlabAccumulateInfo { @@ -67,26 +64,22 @@ BUILD_COMPARE_VALUE_FUNCTION(ComparePtr, ptr); BUILD_COMPARE_VALUE_FUNCTION_REVERSE(CompareBytesReq, bytes_req); BUILD_COMPARE_VALUE_FUNCTION_REVERSE(CompareBytesAlloc, bytes_alloc); BUILD_COMPARE_VALUE_FUNCTION(CompareGfpFlags, gfp_flags); -BUILD_COMPARE_VALUE_FUNCTION_REVERSE(CompareCrossCpuAllocations, - cross_cpu_allocations); +BUILD_COMPARE_VALUE_FUNCTION_REVERSE(CompareCrossCpuAllocations, cross_cpu_allocations); BUILD_DISPLAY_HEX64_FUNCTION(DisplayPtr, ptr); BUILD_DISPLAY_UINT64_FUNCTION(DisplayBytesReq, bytes_req); BUILD_DISPLAY_UINT64_FUNCTION(DisplayBytesAlloc, bytes_alloc); BUILD_DISPLAY_HEX64_FUNCTION(DisplayGfpFlags, gfp_flags); -BUILD_DISPLAY_UINT64_FUNCTION(DisplayCrossCpuAllocations, - cross_cpu_allocations); +BUILD_DISPLAY_UINT64_FUNCTION(DisplayCrossCpuAllocations, cross_cpu_allocations); -static int CompareFragment(const SlabSample* sample1, - const SlabSample* sample2) { +static int CompareFragment(const SlabSample* sample1, const SlabSample* sample2) { uint64_t frag1 = sample1->bytes_alloc - sample1->bytes_req; uint64_t frag2 = sample2->bytes_alloc - sample2->bytes_req; return Compare(frag2, frag1); } static std::string DisplayFragment(const SlabSample* sample) { - return android::base::StringPrintf("%" PRIu64, - sample->bytes_alloc - sample->bytes_req); + return android::base::StringPrintf("%" PRIu64, sample->bytes_alloc - sample->bytes_req); } struct SlabSampleTree { @@ -110,8 +103,7 @@ struct SlabFormat { TracingFieldPlace gfp_flags; }; -class SlabSampleTreeBuilder - : public SampleTreeBuilder<SlabSample, SlabAccumulateInfo> { +class SlabSampleTreeBuilder : public SampleTreeBuilder<SlabSample, SlabAccumulateInfo> { public: SlabSampleTreeBuilder(const SampleComparator<SlabSample>& sample_comparator, ThreadTree* thread_tree) @@ -133,8 +125,7 @@ class SlabSampleTreeBuilder return sample_tree; } - void AddSlabFormat(const std::vector<uint64_t>& event_ids, - SlabFormat format) { + void AddSlabFormat(const std::vector<uint64_t>& event_ids, SlabFormat format) { std::unique_ptr<SlabFormat> p(new SlabFormat(format)); for (auto id : event_ids) { event_id_to_format_map_[id] = p.get(); @@ -182,11 +173,9 @@ class SlabSampleTreeBuilder uint64_t bytes_req = format->bytes_req.ReadFromData(raw_data); uint64_t bytes_alloc = format->bytes_alloc.ReadFromData(raw_data); uint64_t gfp_flags = format->gfp_flags.ReadFromData(raw_data); - SlabSample* sample = - InsertSample(std::unique_ptr<SlabSample>(new SlabSample( - symbol, ptr, bytes_req, bytes_alloc, 1, gfp_flags, 0))); - alloc_cpu_record_map_.insert( - std::make_pair(ptr, std::make_pair(r.cpu_data.cpu, sample))); + SlabSample* sample = InsertSample(std::unique_ptr<SlabSample>( + new SlabSample(symbol, ptr, bytes_req, bytes_alloc, 1, gfp_flags, 0))); + alloc_cpu_record_map_.insert(std::make_pair(ptr, std::make_pair(r.cpu_data.cpu, sample))); acc_info->bytes_req = bytes_req; acc_info->bytes_alloc = bytes_alloc; return sample; @@ -206,23 +195,20 @@ class SlabSampleTreeBuilder return nullptr; } - SlabSample* CreateBranchSample(const SampleRecord&, - const BranchStackItemType&) override { + SlabSample* CreateBranchSample(const SampleRecord&, const BranchStackItemType&) override { return nullptr; } - SlabSample* CreateCallChainSample(const ThreadEntry*, - const SlabSample* sample, uint64_t ip, bool in_kernel, - const std::vector<SlabSample*>& callchain, - const SlabAccumulateInfo& acc_info) override { + SlabSample* CreateCallChainSample(const ThreadEntry*, const SlabSample* sample, uint64_t ip, + bool in_kernel, const std::vector<SlabSample*>& callchain, + const SlabAccumulateInfo& acc_info) override { if (!in_kernel) { return nullptr; } const Symbol* symbol = thread_tree_->FindKernelSymbol(ip); return InsertCallChainSample( - std::unique_ptr<SlabSample>( - new SlabSample(symbol, sample->ptr, acc_info.bytes_req, - acc_info.bytes_alloc, 1, sample->gfp_flags, 0)), + std::unique_ptr<SlabSample>(new SlabSample(symbol, sample->ptr, acc_info.bytes_req, + acc_info.bytes_alloc, 1, sample->gfp_flags, 0)), callchain); } @@ -256,14 +242,12 @@ class SlabSampleTreeBuilder std::unordered_map<uint64_t, SlabFormat*> event_id_to_format_map_; std::vector<std::unique_ptr<SlabFormat>> formats_; - std::unordered_map<uint64_t, std::pair<uint32_t, SlabSample*>> - alloc_cpu_record_map_; + std::unordered_map<uint64_t, std::pair<uint32_t, SlabSample*>> alloc_cpu_record_map_; }; using SlabSampleTreeSorter = SampleTreeSorter<SlabSample>; using SlabSampleTreeDisplayer = SampleTreeDisplayer<SlabSample, SlabSampleTree>; -using SlabSampleCallgraphDisplayer = - CallgraphDisplayer<SlabSample, CallChainNode<SlabSample>>; +using SlabSampleCallgraphDisplayer = CallgraphDisplayer<SlabSample, CallChainNode<SlabSample>>; struct EventAttrWithName { perf_event_attr attr; @@ -274,9 +258,8 @@ struct EventAttrWithName { class KmemCommand : public Command { public: KmemCommand() - : Command( - "kmem", "collect kernel memory allocation information", - // clang-format off + : Command("kmem", "collect kernel memory allocation information", + // clang-format off "Usage: kmem (record [record options] | report [report options])\n" "kmem record\n" "-g Enable call graph recording. Same as '--call-graph fp'.\n" @@ -309,8 +292,8 @@ class KmemCommand : public Command { " the cpu allocating them.\n" " The default slab sort keys are:\n" " hit,caller,bytes_req,bytes_alloc,fragment,pingpong.\n" - // clang-format on - ), + // clang-format on + ), is_record_(false), use_slab_(false), accumulate_callchain_(false), @@ -322,8 +305,7 @@ class KmemCommand : public Command { bool Run(const std::vector<std::string>& args); private: - bool ParseOptions(const std::vector<std::string>& args, - std::vector<std::string>* left_args); + bool ParseOptions(const std::vector<std::string>& args, std::vector<std::string>* left_args); bool RecordKmemInfo(const std::vector<std::string>& record_args); bool ReportKmemInfo(); bool PrepareToBuildSampleTree(); @@ -449,10 +431,9 @@ bool KmemCommand::ParseOptions(const std::vector<std::string>& args, bool KmemCommand::RecordKmemInfo(const std::vector<std::string>& record_args) { std::vector<std::string> args; if (use_slab_) { - std::vector<std::string> trace_events = { - "kmem:kmalloc", "kmem:kmem_cache_alloc", - "kmem:kmalloc_node", "kmem:kmem_cache_alloc_node", - "kmem:kfree", "kmem:kmem_cache_free"}; + std::vector<std::string> trace_events = {"kmem:kmalloc", "kmem:kmem_cache_alloc", + "kmem:kmalloc_node", "kmem:kmem_cache_alloc_node", + "kmem:kfree", "kmem:kmem_cache_free"}; for (const auto& name : trace_events) { if (ParseEventType(name)) { args.insert(args.end(), {"-e", name}); @@ -497,8 +478,7 @@ bool KmemCommand::ReportKmemInfo() { bool KmemCommand::PrepareToBuildSampleTree() { if (use_slab_) { if (slab_sort_keys_.empty()) { - slab_sort_keys_ = {"hit", "caller", "bytes_req", - "bytes_alloc", "fragment", "pingpong"}; + slab_sort_keys_ = {"hit", "caller", "bytes_req", "bytes_alloc", "fragment", "pingpong"}; } SampleComparator<SlabSample> comparator; SampleComparator<SlabSample> sort_comparator; @@ -512,8 +492,7 @@ bool KmemCommand::PrepareToBuildSampleTree() { for (const auto& key : slab_sort_keys_) { if (key == "hit") { sort_comparator.AddCompareFunction(CompareSampleCount); - displayer.AddDisplayFunction(accumulated_name + "Hit", - DisplaySampleCount); + displayer.AddDisplayFunction(accumulated_name + "Hit", DisplaySampleCount); } else if (key == "caller") { comparator.AddCompareFunction(CompareSymbol); displayer.AddDisplayFunction("Caller", DisplaySymbol); @@ -522,16 +501,13 @@ bool KmemCommand::PrepareToBuildSampleTree() { displayer.AddDisplayFunction("Ptr", DisplayPtr); } else if (key == "bytes_req") { sort_comparator.AddCompareFunction(CompareBytesReq); - displayer.AddDisplayFunction(accumulated_name + "BytesReq", - DisplayBytesReq); + displayer.AddDisplayFunction(accumulated_name + "BytesReq", DisplayBytesReq); } else if (key == "bytes_alloc") { sort_comparator.AddCompareFunction(CompareBytesAlloc); - displayer.AddDisplayFunction(accumulated_name + "BytesAlloc", - DisplayBytesAlloc); + displayer.AddDisplayFunction(accumulated_name + "BytesAlloc", DisplayBytesAlloc); } else if (key == "fragment") { sort_comparator.AddCompareFunction(CompareFragment); - displayer.AddDisplayFunction(accumulated_name + "Fragment", - DisplayFragment); + displayer.AddDisplayFunction(accumulated_name + "Fragment", DisplayFragment); } else if (key == "gfp_flags") { comparator.AddCompareFunction(CompareGfpFlags); displayer.AddDisplayFunction("GfpFlags", DisplayGfpFlags); @@ -542,10 +518,9 @@ bool KmemCommand::PrepareToBuildSampleTree() { LOG(ERROR) << "Unknown sort key for slab allocation: " << key; return false; } - slab_sample_tree_builder_.reset( - new SlabSampleTreeBuilder(comparator, &thread_tree_)); - slab_sample_tree_builder_->SetCallChainSampleOptions( - accumulate_callchain_, print_callgraph_, !callgraph_show_callee_); + slab_sample_tree_builder_.reset(new SlabSampleTreeBuilder(comparator, &thread_tree_)); + slab_sample_tree_builder_->SetCallChainSampleOptions(accumulate_callchain_, print_callgraph_, + !callgraph_show_callee_); sort_comparator.AddComparator(comparator); slab_sample_tree_sorter_.reset(new SlabSampleTreeSorter(sort_comparator)); slab_sample_tree_displayer_.reset(new SlabSampleTreeDisplayer(displayer)); @@ -567,8 +542,7 @@ void KmemCommand::ReadEventAttrsFromRecordFile() { bool KmemCommand::ReadFeaturesFromRecordFile() { record_file_reader_->LoadBuildIdAndFileFeatures(thread_tree_); - std::string arch = - record_file_reader_->ReadFeatureString(PerfFileFormat::FEAT_ARCH); + std::string arch = record_file_reader_->ReadFeatureString(PerfFileFormat::FEAT_ARCH); if (!arch.empty()) { record_file_arch_ = GetArchType(arch); if (record_file_arch_ == ARCH_UNSUPPORTED) { @@ -581,8 +555,8 @@ bool KmemCommand::ReadFeaturesFromRecordFile() { } if (record_file_reader_->HasFeature(PerfFileFormat::FEAT_TRACING_DATA)) { std::vector<char> tracing_data; - if (!record_file_reader_->ReadFeatureSection( - PerfFileFormat::FEAT_TRACING_DATA, &tracing_data)) { + if (!record_file_reader_->ReadFeatureSection(PerfFileFormat::FEAT_TRACING_DATA, + &tracing_data)) { return false; } ProcessTracingData(tracing_data); @@ -592,9 +566,7 @@ bool KmemCommand::ReadFeaturesFromRecordFile() { bool KmemCommand::ReadSampleTreeFromRecordFile() { if (!record_file_reader_->ReadDataSection( - [this](std::unique_ptr<Record> record) { - return ProcessRecord(std::move(record)); - })) { + [this](std::unique_ptr<Record> record) { return ProcessRecord(std::move(record)); })) { return false; } if (use_slab_) { @@ -628,8 +600,7 @@ void KmemCommand::ProcessTracingData(const std::vector<char>& data) { TracingFormat format = tracing.GetTracingFormatHavingId(trace_event_id); if (use_slab_) { if (format.name == "kmalloc" || format.name == "kmem_cache_alloc" || - format.name == "kmalloc_node" || - format.name == "kmem_cache_alloc_node") { + format.name == "kmalloc_node" || format.name == "kmem_cache_alloc_node") { SlabFormat f; f.type = SlabFormat::KMEM_ALLOC; format.GetField("call_site", f.call_site); @@ -665,8 +636,8 @@ bool KmemCommand::PrintReport() { if (use_slab_) { fprintf(report_fp, "\n\n"); PrintSlabReportContext(report_fp); - slab_sample_tree_displayer_->DisplaySamples( - report_fp, slab_sample_tree_.samples, &slab_sample_tree_); + slab_sample_tree_displayer_->DisplaySamples(report_fp, slab_sample_tree_.samples, + &slab_sample_tree_); } return true; } @@ -677,31 +648,28 @@ void KmemCommand::PrintReportContext(FILE* fp) { } fprintf(fp, "Arch: %s\n", GetArchString(record_file_arch_).c_str()); for (const auto& attr : event_attrs_) { - fprintf(fp, "Event: %s (type %u, config %llu)\n", attr.name.c_str(), - attr.attr.type, attr.attr.config); + fprintf(fp, "Event: %s (type %u, config %llu)\n", attr.name.c_str(), attr.attr.type, + attr.attr.config); } } void KmemCommand::PrintSlabReportContext(FILE* fp) { fprintf(fp, "Slab allocation information:\n"); - fprintf(fp, "Total requested bytes: %" PRIu64 "\n", - slab_sample_tree_.total_requested_bytes); - fprintf(fp, "Total allocated bytes: %" PRIu64 "\n", - slab_sample_tree_.total_allocated_bytes); - uint64_t fragment = slab_sample_tree_.total_allocated_bytes - - slab_sample_tree_.total_requested_bytes; + fprintf(fp, "Total requested bytes: %" PRIu64 "\n", slab_sample_tree_.total_requested_bytes); + fprintf(fp, "Total allocated bytes: %" PRIu64 "\n", slab_sample_tree_.total_allocated_bytes); + uint64_t fragment = + slab_sample_tree_.total_allocated_bytes - slab_sample_tree_.total_requested_bytes; double percentage = 0.0; if (slab_sample_tree_.total_allocated_bytes != 0) { percentage = 100.0 * fragment / slab_sample_tree_.total_allocated_bytes; } fprintf(fp, "Total fragment: %" PRIu64 ", %f%%\n", fragment, percentage); - fprintf(fp, "Total allocations: %" PRIu64 "\n", - slab_sample_tree_.nr_allocations); + fprintf(fp, "Total allocations: %" PRIu64 "\n", slab_sample_tree_.nr_allocations); fprintf(fp, "Total frees: %" PRIu64 "\n", slab_sample_tree_.nr_frees); percentage = 0.0; if (slab_sample_tree_.nr_allocations != 0) { - percentage = 100.0 * slab_sample_tree_.nr_cross_cpu_allocations / - slab_sample_tree_.nr_allocations; + percentage = + 100.0 * slab_sample_tree_.nr_cross_cpu_allocations / slab_sample_tree_.nr_allocations; } fprintf(fp, "Total cross cpu allocation/free: %" PRIu64 ", %f%%\n", slab_sample_tree_.nr_cross_cpu_allocations, percentage); @@ -713,8 +681,7 @@ void KmemCommand::PrintSlabReportContext(FILE* fp) { namespace simpleperf { void RegisterKmemCommand() { - RegisterCommand("kmem", - [] { return std::unique_ptr<Command>(new KmemCommand()); }); + RegisterCommand("kmem", [] { return std::unique_ptr<Command>(new KmemCommand()); }); } } // namespace simpleperf diff --git a/simpleperf/cmd_kmem_test.cpp b/simpleperf/cmd_kmem_test.cpp index 0fa30669..56ab91b6 100644 --- a/simpleperf/cmd_kmem_test.cpp +++ b/simpleperf/cmd_kmem_test.cpp @@ -44,14 +44,12 @@ static void KmemReportRawFile(const std::string& perf_data, ReportResult* result) { result->success = false; TemporaryFile tmp_file; - std::vector<std::string> args = {"report", "-i", perf_data, "-o", - tmp_file.path}; + std::vector<std::string> args = {"report", "-i", perf_data, "-o", tmp_file.path}; args.insert(args.end(), additional_args.begin(), additional_args.end()); ASSERT_TRUE(KmemCmd()->Run(args)); ASSERT_TRUE(android::base::ReadFileToString(tmp_file.path, &result->content)); ASSERT_TRUE(!result->content.empty()); - std::vector<std::string> raw_lines = - android::base::Split(result->content, "\n"); + std::vector<std::string> raw_lines = android::base::Split(result->content, "\n"); result->lines.clear(); for (const auto& line : raw_lines) { std::string s = android::base::Trim(line); @@ -64,16 +62,14 @@ static void KmemReportRawFile(const std::string& perf_data, } static void KmemReportFile(const std::string& perf_data, - const std::vector<std::string>& additional_args, - ReportResult* result) { + const std::vector<std::string>& additional_args, ReportResult* result) { KmemReportRawFile(GetTestData(perf_data), additional_args, result); } #if defined(__linux__) #include "environment.h" -static bool RunKmemRecordCmd(std::vector<std::string> v, - const char* output_file = nullptr) { +static bool RunKmemRecordCmd(std::vector<std::string> v, const char* output_file = nullptr) { std::unique_ptr<TemporaryFile> tmpfile; std::string out_file; if (output_file != nullptr) { @@ -130,9 +126,7 @@ TEST(kmem_cmd, report_all_sort_options) { ReportResult result; KmemReportFile( PERF_DATA_WITH_KMEM_SLAB_CALLGRAPH_RECORD, - {"--slab-sort", - "hit,caller,ptr,bytes_req,bytes_alloc,fragment,gfp_flags,pingpong"}, - &result); + {"--slab-sort", "hit,caller,ptr,bytes_req,bytes_alloc,fragment,gfp_flags,pingpong"}, &result); ASSERT_TRUE(result.success); ASSERT_NE(result.content.find("Ptr"), std::string::npos); ASSERT_NE(result.content.find("GfpFlags"), std::string::npos); diff --git a/simpleperf/cmd_list.cpp b/simpleperf/cmd_list.cpp index 2f746102..ceb04018 100644 --- a/simpleperf/cmd_list.cpp +++ b/simpleperf/cmd_list.cpp @@ -22,9 +22,9 @@ #include <android-base/file.h> #include <android-base/logging.h> +#include "ETMRecorder.h" #include "command.h" #include "environment.h" -#include "ETMRecorder.h" #include "event_attr.h" #include "event_fd.h" #include "event_selection_set.h" @@ -143,8 +143,7 @@ class ListCommand : public Command { " dwarf-based-call-graph\n" " trace-offcpu\n" // clang-format on - ) { - } + ) {} bool Run(const std::vector<std::string>& args) override; @@ -158,28 +157,22 @@ bool ListCommand::Run(const std::vector<std::string>& args) { } static std::map<std::string, std::pair<std::string, std::function<bool(const EventType&)>>> - type_map = { - {"hw", - {"hardware events", [](const EventType& e) { return e.type == PERF_TYPE_HARDWARE; }}}, - {"sw", - {"software events", [](const EventType& e) { return e.type == PERF_TYPE_SOFTWARE; }}}, - {"cache", - {"hw-cache events", [](const EventType& e) { return e.type == PERF_TYPE_HW_CACHE; }}}, - {"raw", - {"raw events provided by cpu pmu", - [](const EventType& e) { return e.type == PERF_TYPE_RAW; }}}, - {"tracepoint", - {"tracepoint events", - [](const EventType& e) { return e.type == PERF_TYPE_TRACEPOINT; }}}, + type_map = + { {"hw", {"hardware events", [](const EventType& e) { return e.type == PERF_TYPE_HARDWARE; }}}, + {"sw", {"software events", [](const EventType& e) { return e.type == PERF_TYPE_SOFTWARE; }}}, + {"cache", {"hw-cache events", [](const EventType& e) { return e.type == PERF_TYPE_HW_CACHE; }}}, + {"raw", + {"raw events provided by cpu pmu", + [](const EventType& e) { return e.type == PERF_TYPE_RAW; }}}, + {"tracepoint", + {"tracepoint events", [](const EventType& e) { return e.type == PERF_TYPE_TRACEPOINT; }}}, #if defined(__arm__) || defined(__aarch64__) - {"cs-etm", - {"coresight etm events", - [](const EventType& e) { - return e.type == ETMRecorder::GetInstance().GetEtmEventType(); - }}}, + {"cs-etm", + {"coresight etm events", + [](const EventType& e) { return e.type == ETMRecorder::GetInstance().GetEtmEventType(); }}}, #endif - {"pmu", {"pmu events", [](const EventType& e) { return e.IsPmuEvent(); }}}, - }; + {"pmu", {"pmu events", [](const EventType& e) { return e.IsPmuEvent(); }}}, + }; std::vector<std::string> names; if (args.empty()) { diff --git a/simpleperf/cmd_record.cpp b/simpleperf/cmd_record.cpp index 203c5cf2..43c906c9 100644 --- a/simpleperf/cmd_record.cpp +++ b/simpleperf/cmd_record.cpp @@ -28,8 +28,8 @@ #include <unordered_set> #include <vector> -#include <android-base/logging.h> #include <android-base/file.h> +#include <android-base/logging.h> #include <android-base/parseint.h> #include <android-base/scopeguard.h> #include <android-base/stringprintf.h> @@ -40,16 +40,16 @@ #endif #include "CallChainJoiner.h" -#include "cmd_record_impl.h" -#include "command.h" -#include "environment.h" #include "ETMRecorder.h" -#include "event_selection_set.h" -#include "event_type.h" #include "IOEventLoop.h" #include "JITDebugReader.h" #include "OfflineUnwinder.h" #include "ProbeEvents.h" +#include "cmd_record_impl.h" +#include "command.h" +#include "environment.h" +#include "event_selection_set.h" +#include "event_type.h" #include "read_apk.h" #include "read_elf.h" #include "read_symbol_map.h" @@ -312,8 +312,7 @@ class RecordCommand : public Command { bool Run(const std::vector<std::string>& args); private: - bool ParseOptions(const std::vector<std::string>& args, - std::vector<std::string>* non_option_args, + bool ParseOptions(const std::vector<std::string>& args, std::vector<std::string>* non_option_args, ProbeEvents* probe_events); bool AdjustPerfEventLimit(); bool PrepareRecording(Workload* workload); @@ -322,8 +321,7 @@ class RecordCommand : public Command { bool TraceOffCpu(); bool SetEventSelectionFlags(); bool CreateAndInitRecordFile(); - std::unique_ptr<RecordFileWriter> CreateRecordFile( - const std::string& filename); + std::unique_ptr<RecordFileWriter> CreateRecordFile(const std::string& filename); bool DumpKernelSymbol(); bool DumpTracingData(); bool DumpKernelMaps(); @@ -482,8 +480,7 @@ bool RecordCommand::PrepareRecording(Workload* workload) { } if (unwind_dwarf_callchain_ && allow_callchain_joiner_) { callchain_joiner_.reset(new CallChainJoiner(DEFAULT_CALL_CHAIN_JOINER_CACHE_SIZE, - callchain_joiner_min_matching_nodes_, - false)); + callchain_joiner_min_matching_nodes_, false)); } // 4. Add monitored targets. @@ -501,8 +498,7 @@ bool RecordCommand::PrepareRecording(Workload* workload) { event_selection_set_.AddMonitoredProcesses(pids); need_to_check_targets = true; } else { - LOG(ERROR) - << "No threads to monitor. Try `simpleperf help record` for help"; + LOG(ERROR) << "No threads to monitor. Try `simpleperf help record` for help"; return false; } } else { @@ -528,15 +524,14 @@ bool RecordCommand::PrepareRecording(Workload* workload) { if (!event_selection_set_.OpenEventFiles(cpus_)) { return false; } - size_t record_buffer_size = system_wide_collection_ ? kSystemWideRecordBufferSize - : kRecordBufferSize; + size_t record_buffer_size = + system_wide_collection_ ? kSystemWideRecordBufferSize : kRecordBufferSize; if (!event_selection_set_.MmapEventFiles(mmap_page_range_.first, mmap_page_range_.second, aux_buffer_size_, record_buffer_size, allow_cutting_samples_, exclude_perf_)) { return false; } - auto callback = - std::bind(&RecordCommand::ProcessRecord, this, std::placeholders::_1); + auto callback = std::bind(&RecordCommand::ProcessRecord, this, std::placeholders::_1); if (!event_selection_set_.PrepareToReadMmapEventData(callback)) { return false; } @@ -551,9 +546,7 @@ bool RecordCommand::PrepareRecording(Workload* workload) { return false; } IOEventLoop* loop = event_selection_set_.GetIOEventLoop(); - auto exit_loop_callback = [loop]() { - return loop->ExitLoop(); - }; + auto exit_loop_callback = [loop]() { return loop->ExitLoop(); }; if (!loop->AddSignalEvents({SIGCHLD, SIGINT, SIGTERM}, exit_loop_callback)) { return false; } @@ -650,7 +643,8 @@ bool RecordCommand::DoRecording(Workload* workload) { return true; } -static bool WriteRecordDataToOutFd(const std::string& in_filename, android::base::unique_fd out_fd) { +static bool WriteRecordDataToOutFd(const std::string& in_filename, + android::base::unique_fd out_fd) { android::base::unique_fd in_fd(FileHelper::OpenReadOnly(in_filename)); if (in_fd == -1) { PLOG(ERROR) << "Failed to open " << in_filename; @@ -734,13 +728,13 @@ bool RecordCommand::PostProcessRecording(const std::vector<std::string>& args) { } } LOG(DEBUG) << "Prepare recording time " - << (time_stat_.start_recording_time - time_stat_.prepare_recording_time) / 1e6 - << " ms, recording time " - << (time_stat_.stop_recording_time - time_stat_.start_recording_time) / 1e6 - << " ms, stop recording time " - << (time_stat_.finish_recording_time - time_stat_.stop_recording_time) / 1e6 - << " ms, post process time " - << (time_stat_.post_process_time - time_stat_.finish_recording_time) / 1e6 << " ms."; + << (time_stat_.start_recording_time - time_stat_.prepare_recording_time) / 1e6 + << " ms, recording time " + << (time_stat_.stop_recording_time - time_stat_.start_recording_time) / 1e6 + << " ms, stop recording time " + << (time_stat_.finish_recording_time - time_stat_.stop_recording_time) / 1e6 + << " ms, post process time " + << (time_stat_.post_process_time - time_stat_.finish_recording_time) / 1e6 << " ms."; return true; } @@ -1141,8 +1135,7 @@ bool RecordCommand::SetEventSelectionFlags() { if (fp_callchain_sampling_) { event_selection_set_.EnableFpCallChainSampling(); } else if (dwarf_callchain_sampling_) { - if (!event_selection_set_.EnableDwarfCallChainSampling( - dump_stack_size_in_dwarf_sampling_)) { + if (!event_selection_set_.EnableDwarfCallChainSampling(dump_stack_size_in_dwarf_sampling_)) { return false; } } @@ -1164,10 +1157,8 @@ bool RecordCommand::CreateAndInitRecordFile() { DumpAuxTraceInfo(); } -std::unique_ptr<RecordFileWriter> RecordCommand::CreateRecordFile( - const std::string& filename) { - std::unique_ptr<RecordFileWriter> writer = - RecordFileWriter::CreateInstance(filename); +std::unique_ptr<RecordFileWriter> RecordCommand::CreateRecordFile(const std::string& filename) { + std::unique_ptr<RecordFileWriter> writer = RecordFileWriter::CreateInstance(filename); if (writer == nullptr) { return nullptr; } @@ -1181,8 +1172,7 @@ std::unique_ptr<RecordFileWriter> RecordCommand::CreateRecordFile( bool RecordCommand::DumpKernelSymbol() { if (can_dump_kernel_symbols_) { std::string kallsyms; - if (event_selection_set_.NeedKernelSymbol() && - CheckKernelSymbolAddresses()) { + if (event_selection_set_.NeedKernelSymbol() && CheckKernelSymbolAddresses()) { if (!android::base::ReadFileToString("/proc/kallsyms", &kallsyms)) { PLOG(ERROR) << "failed to read /proc/kallsyms"; return false; @@ -1197,8 +1187,7 @@ bool RecordCommand::DumpKernelSymbol() { } bool RecordCommand::DumpTracingData() { - std::vector<const EventType*> tracepoint_event_types = - event_selection_set_.GetTracepointEvents(); + std::vector<const EventType*> tracepoint_event_types = event_selection_set_.GetTracepointEvents(); if (tracepoint_event_types.empty() || !CanRecordRawData() || in_app_context_) { return true; // No need to dump tracing data, or can't do it. } @@ -1282,8 +1271,8 @@ bool RecordCommand::DumpProcessMaps(pid_t pid, const std::unordered_set<pid_t>& if (!(map.prot & PROT_EXEC) && !event_selection_set_.RecordNotExecutableMaps()) { continue; } - Mmap2Record record(attr, false, pid, pid, map.start_addr, map.len, - map.pgoff, map.prot, map.name, event_id, last_record_timestamp_); + Mmap2Record record(attr, false, pid, pid, map.start_addr, map.len, map.pgoff, map.prot, + map.name, event_id, last_record_timestamp_); if (!ProcessRecord(&record)) { return false; } @@ -1442,8 +1431,8 @@ bool RecordCommand::ProcessJITDebugInfo(const std::vector<JITDebugInfo>& debug_i 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_; + 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, info.jit_code_len, info.file_offset, map_flags::PROT_JIT_SYMFILE_MAP, info.file_path, attr_id.ids[0], timestamp); @@ -1453,8 +1442,8 @@ bool RecordCommand::ProcessJITDebugInfo(const std::vector<JITDebugInfo>& debug_i } else { if (info.extracted_dex_file_map) { ThreadMmap& map = *info.extracted_dex_file_map; - uint64_t timestamp = jit_debug_reader_->SyncWithRecords() ? info.timestamp - : last_record_timestamp_; + 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); if (!ProcessRecord(&record)) { @@ -1562,13 +1551,10 @@ void RecordCommand::UpdateRecord(Record* record) { } bool RecordCommand::UnwindRecord(SampleRecord& r) { - if ((r.sample_type & PERF_SAMPLE_CALLCHAIN) && - (r.sample_type & PERF_SAMPLE_REGS_USER) && - (r.regs_user_data.reg_mask != 0) && - (r.sample_type & PERF_SAMPLE_STACK_USER) && + if ((r.sample_type & PERF_SAMPLE_CALLCHAIN) && (r.sample_type & PERF_SAMPLE_REGS_USER) && + (r.regs_user_data.reg_mask != 0) && (r.sample_type & PERF_SAMPLE_STACK_USER) && (r.GetValidStackSize() > 0)) { - ThreadEntry* thread = - thread_tree_.FindThreadOrNew(r.tid_data.pid, r.tid_data.tid); + ThreadEntry* thread = thread_tree_.FindThreadOrNew(r.tid_data.pid, r.tid_data.tid); RegSet regs(r.regs_user_data.abi, r.regs_user_data.reg_mask, r.regs_user_data.regs); std::vector<uint64_t> ips; std::vector<uint64_t> sps; @@ -1680,8 +1666,8 @@ void LoadSymbolMapFile(int pid, const std::string& package, ThreadTree* thread_t // For now, use /data/local/tmp/perf-<pid>.map, which works for standalone programs, // and /data/data/<package>/perf-<pid>.map, which works for apps. auto path = package.empty() - ? android::base::StringPrintf("/data/local/tmp/perf-%d.map", pid) - : android::base::StringPrintf("/data/data/%s/perf-%d.map", package.c_str(), pid); + ? android::base::StringPrintf("/data/local/tmp/perf-%d.map", pid) + : android::base::StringPrintf("/data/data/%s/perf-%d.map", package.c_str(), pid); auto symbols = ReadSymbolMapFromFile(path); if (!symbols.empty()) { @@ -1691,8 +1677,7 @@ void LoadSymbolMapFile(int pid, const std::string& package, ThreadTree* thread_t } // namespace -bool RecordCommand::DumpAdditionalFeatures( - const std::vector<std::string>& args) { +bool RecordCommand::DumpAdditionalFeatures(const std::vector<std::string>& args) { // Read data section of perf.data to collect hit file information. thread_tree_.ClearThreadAndMap(); bool kernel_symbols_available = false; @@ -1741,12 +1726,10 @@ bool RecordCommand::DumpAdditionalFeatures( PLOG(ERROR) << "uname() failed"; return false; } - if (!record_file_writer_->WriteFeatureString(PerfFileFormat::FEAT_OSRELEASE, - uname_buf.release)) { + if (!record_file_writer_->WriteFeatureString(PerfFileFormat::FEAT_OSRELEASE, uname_buf.release)) { return false; } - if (!record_file_writer_->WriteFeatureString(PerfFileFormat::FEAT_ARCH, - uname_buf.machine)) { + if (!record_file_writer_->WriteFeatureString(PerfFileFormat::FEAT_ARCH, uname_buf.machine)) { return false; } @@ -1759,8 +1742,7 @@ bool RecordCommand::DumpAdditionalFeatures( if (!record_file_writer_->WriteCmdlineFeature(cmdline)) { return false; } - if (branch_sampling_ != 0 && - !record_file_writer_->WriteBranchStackFeature()) { + if (branch_sampling_ != 0 && !record_file_writer_->WriteBranchStackFeature()) { return false; } if (!DumpMetaInfoFeature(kernel_symbols_available)) { @@ -1790,8 +1772,7 @@ bool RecordCommand::DumpBuildIdFeature() { if (!GetKernelBuildId(&build_id)) { continue; } - build_id_records.push_back( - BuildIdRecord(true, UINT_MAX, build_id, dso->Path())); + build_id_records.push_back(BuildIdRecord(true, UINT_MAX, build_id, dso->Path())); } else if (dso->type() == DSO_KERNEL_MODULE) { std::string path = dso->Path(); std::string module_name = basename(&path[0]); @@ -1811,8 +1792,7 @@ bool RecordCommand::DumpBuildIdFeature() { LOG(DEBUG) << "Can't read build_id from file " << dso->Path(); continue; } - build_id_records.push_back( - BuildIdRecord(false, UINT_MAX, build_id, dso->Path())); + build_id_records.push_back(BuildIdRecord(false, UINT_MAX, build_id, dso->Path())); } } if (!record_file_writer_->WriteBuildIdFeature(build_id_records)) { @@ -1834,10 +1814,10 @@ bool RecordCommand::DumpMetaInfoFeature(bool kernel_symbols_available) { // understanding of event types, even if they are on another machine. info_map["event_type_info"] = ScopedEventTypes::BuildString(event_selection_set_.GetEvents()); #if defined(__ANDROID__) - info_map["product_props"] = android::base::StringPrintf("%s:%s:%s", - android::base::GetProperty("ro.product.manufacturer", "").c_str(), - android::base::GetProperty("ro.product.model", "").c_str(), - android::base::GetProperty("ro.product.name", "").c_str()); + info_map["product_props"] = android::base::StringPrintf( + "%s:%s:%s", android::base::GetProperty("ro.product.manufacturer", "").c_str(), + android::base::GetProperty("ro.product.model", "").c_str(), + android::base::GetProperty("ro.product.name", "").c_str()); info_map["android_version"] = android::base::GetProperty("ro.build.version.release", ""); if (!app_package_name_.empty()) { info_map["app_package_name"] = app_package_name_; @@ -1853,10 +1833,8 @@ bool RecordCommand::DumpMetaInfoFeature(bool kernel_symbols_available) { } void RecordCommand::CollectHitFileInfo(const SampleRecord& r) { - const ThreadEntry* thread = - thread_tree_.FindThreadOrNew(r.tid_data.pid, r.tid_data.tid); - const MapEntry* map = - thread_tree_.FindMap(thread, r.ip_data.ip, r.InKernel()); + const ThreadEntry* thread = thread_tree_.FindThreadOrNew(r.tid_data.pid, r.tid_data.tid); + const MapEntry* map = thread_tree_.FindMap(thread, r.ip_data.ip, r.InKernel()); Dso* dso = map->dso; const Symbol* symbol; if (dump_symbols_) { @@ -1882,8 +1860,7 @@ void RecordCommand::CollectHitFileInfo(const SampleRecord& r) { in_kernel = false; break; default: - LOG(DEBUG) << "Unexpected perf_context in callchain: " << std::hex - << ip; + LOG(DEBUG) << "Unexpected perf_context in callchain: " << std::hex << ip; } } else { if (first_ip) { @@ -1979,8 +1956,7 @@ std::vector<AddrFilter> ParseAddrFilterOption(const std::string& s) { } void RegisterRecordCommand() { - RegisterCommand("record", - [] { return std::unique_ptr<Command>(new RecordCommand()); }); + RegisterCommand("record", [] { return std::unique_ptr<Command>(new RecordCommand()); }); } } // namespace simpleperf diff --git a/simpleperf/cmd_record_test.cpp b/simpleperf/cmd_record_test.cpp index 87cef355..c6401209 100644 --- a/simpleperf/cmd_record_test.cpp +++ b/simpleperf/cmd_record_test.cpp @@ -34,13 +34,13 @@ #include <regex> #include <thread> +#include "ETMRecorder.h" +#include "ProbeEvents.h" #include "cmd_record_impl.h" #include "command.h" #include "environment.h" -#include "ETMRecorder.h" #include "event_selection_set.h" #include "get_test_data.h" -#include "ProbeEvents.h" #include "record.h" #include "record_file.h" #include "test_util.h" @@ -59,8 +59,7 @@ static const char* GetDefaultEvent() { return HasHardwareCounter() ? "cpu-cycles" : "task-clock"; } -static bool RunRecordCmd(std::vector<std::string> v, - const char* output_file = nullptr) { +static bool RunRecordCmd(std::vector<std::string> v, const char* output_file = nullptr) { bool has_event = false; for (auto& arg : v) { if (arg == "-e" || arg == "--group") { @@ -135,8 +134,8 @@ TEST(record_cmd, freq_option) { TEST(record_cmd, multiple_freq_or_sample_period_option) { TemporaryFile tmpfile; - ASSERT_TRUE(RunRecordCmd({"-f", "99", "-e", "task-clock", "-c", "1000000", "-e", - "cpu-clock"}, tmpfile.path)); + ASSERT_TRUE(RunRecordCmd({"-f", "99", "-e", "task-clock", "-c", "1000000", "-e", "cpu-clock"}, + tmpfile.path)); CheckEventType(tmpfile.path, "task-clock", 0, 99u); CheckEventType(tmpfile.path, "cpu-clock", 1000000u, 0u); } @@ -149,16 +148,14 @@ TEST(record_cmd, output_file_option) { TEST(record_cmd, dump_kernel_mmap) { TemporaryFile tmpfile; ASSERT_TRUE(RunRecordCmd({}, tmpfile.path)); - std::unique_ptr<RecordFileReader> reader = - RecordFileReader::CreateInstance(tmpfile.path); + std::unique_ptr<RecordFileReader> reader = RecordFileReader::CreateInstance(tmpfile.path); ASSERT_TRUE(reader != nullptr); std::vector<std::unique_ptr<Record>> records = reader->DataSection(); ASSERT_GT(records.size(), 0U); bool have_kernel_mmap = false; for (auto& record : records) { if (record->type() == PERF_RECORD_MMAP) { - const MmapRecord* mmap_record = - static_cast<const MmapRecord*>(record.get()); + const MmapRecord* mmap_record = static_cast<const MmapRecord*>(record.get()); if (strcmp(mmap_record->filename, DEFAULT_KERNEL_MMAP_NAME) == 0 || strcmp(mmap_record->filename, DEFAULT_KERNEL_MMAP_NAME_PERF) == 0) { have_kernel_mmap = true; @@ -172,12 +169,10 @@ TEST(record_cmd, dump_kernel_mmap) { TEST(record_cmd, dump_build_id_feature) { TemporaryFile tmpfile; ASSERT_TRUE(RunRecordCmd({}, tmpfile.path)); - std::unique_ptr<RecordFileReader> reader = - RecordFileReader::CreateInstance(tmpfile.path); + std::unique_ptr<RecordFileReader> reader = RecordFileReader::CreateInstance(tmpfile.path); ASSERT_TRUE(reader != nullptr); const FileHeader& file_header = reader->FileHeader(); - ASSERT_TRUE(file_header.features[FEAT_BUILD_ID / 8] & - (1 << (FEAT_BUILD_ID % 8))); + ASSERT_TRUE(file_header.features[FEAT_BUILD_ID / 8] & (1 << (FEAT_BUILD_ID % 8))); ASSERT_GT(reader->FeatureSectionDescriptors().size(), 0u); } @@ -398,8 +393,8 @@ TEST(record_cmd, post_unwind_option) { TEST(record_cmd, existing_processes) { std::vector<std::unique_ptr<Workload>> workloads; CreateProcesses(2, &workloads); - std::string pid_list = android::base::StringPrintf( - "%d,%d", workloads[0]->GetPid(), workloads[1]->GetPid()); + std::string pid_list = + android::base::StringPrintf("%d,%d", workloads[0]->GetPid(), workloads[1]->GetPid()); ASSERT_TRUE(RunRecordCmd({"-p", pid_list})); } @@ -407,8 +402,8 @@ TEST(record_cmd, existing_threads) { std::vector<std::unique_ptr<Workload>> workloads; CreateProcesses(2, &workloads); // Process id can also be used as thread id in linux. - std::string tid_list = android::base::StringPrintf( - "%d,%d", workloads[0]->GetPid(), workloads[1]->GetPid()); + std::string tid_list = + android::base::StringPrintf("%d,%d", workloads[0]->GetPid(), workloads[1]->GetPid()); ASSERT_TRUE(RunRecordCmd({"-t", tid_list})); } @@ -429,11 +424,9 @@ TEST(record_cmd, mmap_page_option) { ASSERT_FALSE(RunRecordCmd({"-m", "7"})); } -static void CheckKernelSymbol(const std::string& path, bool need_kallsyms, - bool* success) { +static void CheckKernelSymbol(const std::string& path, bool need_kallsyms, bool* success) { *success = false; - std::unique_ptr<RecordFileReader> reader = - RecordFileReader::CreateInstance(path); + std::unique_ptr<RecordFileReader> reader = RecordFileReader::CreateInstance(path); ASSERT_TRUE(reader != nullptr); std::vector<std::unique_ptr<Record>> records = reader->DataSection(); bool has_kernel_symbol_records = false; @@ -531,9 +524,9 @@ TEST(record_cmd, dump_kernel_symbols) { TEST(record_cmd, group_option) { ASSERT_TRUE(RunRecordCmd({"--group", "task-clock,cpu-clock", "-m", "16"})); - ASSERT_TRUE(RunRecordCmd({"--group", "task-clock,cpu-clock", "--group", - "task-clock:u,cpu-clock:u", "--group", - "task-clock:k,cpu-clock:k", "-m", "16"})); + ASSERT_TRUE( + RunRecordCmd({"--group", "task-clock,cpu-clock", "--group", "task-clock:u,cpu-clock:u", + "--group", "task-clock:k,cpu-clock:k", "-m", "16"})); } TEST(record_cmd, symfs_option) { @@ -551,8 +544,7 @@ TEST(record_cmd, duration_option) { TEST(record_cmd, support_modifier_for_clock_events) { for (const std::string& e : {"cpu-clock", "task-clock"}) { for (const std::string& m : {"u", "k"}) { - ASSERT_TRUE(RunRecordCmd({"-e", e + ":" + m})) << "event " << e << ":" - << m; + ASSERT_TRUE(RunRecordCmd({"-e", e + ":" + m})) << "event " << e << ":" << m; } } } @@ -585,7 +577,8 @@ TEST(record_cmd, stop_when_no_more_targets) { sleep(1); }); thread.detach(); - while (tid == 0); + while (tid == 0) + ; ASSERT_TRUE(RecordCmd()->Run( {"-o", tmpfile.path, "-t", std::to_string(tid), "--in-app", "-e", GetDefaultEvent()})); } @@ -640,8 +633,8 @@ TEST(record_cmd, cpu_clock_for_a_long_time) { CreateProcesses(1, &workloads); std::string pid = std::to_string(workloads[0]->GetPid()); TemporaryFile tmpfile; - ASSERT_TRUE(RecordCmd()->Run( - {"-e", "cpu-clock", "-o", tmpfile.path, "-p", pid, "--duration", "3"})); + ASSERT_TRUE( + RecordCmd()->Run({"-e", "cpu-clock", "-o", tmpfile.path, "-p", pid, "--duration", "3"})); } TEST(record_cmd, dump_regs_for_tracepoint_events) { @@ -813,9 +806,7 @@ class RecordingAppHelper { return app_helper_.InstallApk(apk_path, package_name); } - bool StartApp(const std::string& start_cmd) { - return app_helper_.StartApp(start_cmd); - } + bool StartApp(const std::string& start_cmd) { return app_helper_.StartApp(start_cmd); } bool RecordData(const std::string& record_cmd) { std::vector<std::string> args = android::base::Split(record_cmd, " "); @@ -854,7 +845,7 @@ static void TestRecordingApps(const std::string& app_name) { const std::string expected_method_name = "run"; auto process_symbol = [&](const char* name) { return strstr(name, expected_class_name.c_str()) != nullptr && - strstr(name, expected_method_name.c_str()) != nullptr; + strstr(name, expected_method_name.c_str()) != nullptr; }; ASSERT_TRUE(helper.CheckData(process_symbol)); } @@ -1125,7 +1116,6 @@ TEST(record_cmd, ParseAddrFilterOption) { std::string path; ASSERT_TRUE(Realpath(GetTestData(ELF_FILE), &path)); - // Test file filters. ASSERT_EQ(option_to_str("filter " + path), "filter 0x0/0x73c@" + path); ASSERT_EQ(option_to_str("filter 0x400502-0x400527@" + path), "filter 0x502/0x25@" + path); diff --git a/simpleperf/cmd_report.cpp b/simpleperf/cmd_report.cpp index f1afa1da..d866e1d5 100644 --- a/simpleperf/cmd_report.cpp +++ b/simpleperf/cmd_report.cpp @@ -46,7 +46,10 @@ using android::base::Split; namespace { static std::set<std::string> branch_sort_keys = { - "dso_from", "dso_to", "symbol_from", "symbol_to", + "dso_from", + "dso_to", + "symbol_from", + "symbol_to", }; struct BranchFromEntry { const MapEntry* map; @@ -54,8 +57,7 @@ struct BranchFromEntry { uint64_t vaddr_in_file; uint64_t flags; - BranchFromEntry() - : map(nullptr), symbol(nullptr), vaddr_in_file(0), flags(0) {} + BranchFromEntry() : map(nullptr), symbol(nullptr), vaddr_in_file(0), flags(0) {} }; struct SampleEntry { @@ -94,9 +96,7 @@ struct SampleEntry { SampleEntry(SampleEntry&&) = default; SampleEntry(SampleEntry&) = delete; - uint64_t GetPeriod() const { - return period; - } + uint64_t GetPeriod() const { return period; } }; struct SampleTree { @@ -138,9 +138,7 @@ class ReportCmdSampleTreeBuilder : public SampleTreeBuilder<SampleEntry, uint64_ symbol_filter_ = symbol_filter; } - void SetEventName(const std::string& event_name) { - event_name_ = event_name; - } + void SetEventName(const std::string& event_name) { event_name_ = event_name; } SampleTree GetSampleTree() { AddCallChainDuplicateInfo(); @@ -164,33 +162,25 @@ class ReportCmdSampleTreeBuilder : public SampleTreeBuilder<SampleEntry, uint64_ protected: virtual uint64_t GetPeriod(const SampleRecord& r) = 0; - SampleEntry* CreateSample(const SampleRecord& r, bool in_kernel, - uint64_t* acc_info) override { - const ThreadEntry* thread = - thread_tree_->FindThreadOrNew(r.tid_data.pid, r.tid_data.tid); - const MapEntry* map = - thread_tree_->FindMap(thread, r.ip_data.ip, in_kernel); + SampleEntry* CreateSample(const SampleRecord& r, bool in_kernel, uint64_t* acc_info) override { + const ThreadEntry* thread = thread_tree_->FindThreadOrNew(r.tid_data.pid, r.tid_data.tid); + const MapEntry* map = thread_tree_->FindMap(thread, r.ip_data.ip, in_kernel); uint64_t vaddr_in_file; - const Symbol* symbol = - thread_tree_->FindSymbol(map, r.ip_data.ip, &vaddr_in_file); + const Symbol* symbol = thread_tree_->FindSymbol(map, r.ip_data.ip, &vaddr_in_file); uint64_t period = GetPeriod(r); *acc_info = period; return InsertSample(std::make_unique<SampleEntry>(r.time_data.time, period, 0, 1, r.Cpu(), thread, map, symbol, vaddr_in_file)); } - SampleEntry* CreateBranchSample(const SampleRecord& r, - const BranchStackItemType& item) override { - const ThreadEntry* thread = - thread_tree_->FindThreadOrNew(r.tid_data.pid, r.tid_data.tid); + SampleEntry* CreateBranchSample(const SampleRecord& r, const BranchStackItemType& item) override { + const ThreadEntry* thread = thread_tree_->FindThreadOrNew(r.tid_data.pid, r.tid_data.tid); const MapEntry* from_map = thread_tree_->FindMap(thread, item.from); uint64_t from_vaddr_in_file; - const Symbol* from_symbol = - thread_tree_->FindSymbol(from_map, item.from, &from_vaddr_in_file); + const Symbol* from_symbol = thread_tree_->FindSymbol(from_map, item.from, &from_vaddr_in_file); const MapEntry* to_map = thread_tree_->FindMap(thread, item.to); uint64_t to_vaddr_in_file; - const Symbol* to_symbol = - thread_tree_->FindSymbol(to_map, item.to, &to_vaddr_in_file); + const Symbol* to_symbol = thread_tree_->FindSymbol(to_map, item.to, &to_vaddr_in_file); auto sample = std::make_unique<SampleEntry>(r.time_data.time, r.period_data.period, 0, 1, r.Cpu(), thread, to_map, to_symbol, to_vaddr_in_file); @@ -223,9 +213,7 @@ class ReportCmdSampleTreeBuilder : public SampleTreeBuilder<SampleEntry, uint64_ return thread_tree_->FindThreadOrNew(sample->pid, sample->tid); } - uint64_t GetPeriodForCallChain(const uint64_t& acc_info) override { - return acc_info; - } + uint64_t GetPeriodForCallChain(const uint64_t& acc_info) override { return acc_info; } bool FilterSample(const SampleEntry* sample) override { if (!cpu_filter_.empty() && cpu_filter_.count(sample->cpu) == 0) { @@ -282,12 +270,10 @@ class EventCountSampleTreeBuilder : public ReportCmdSampleTreeBuilder { public: EventCountSampleTreeBuilder(const SampleComparator<SampleEntry>& sample_comparator, ThreadTree* thread_tree) - : ReportCmdSampleTreeBuilder(sample_comparator, thread_tree) { } + : ReportCmdSampleTreeBuilder(sample_comparator, thread_tree) {} protected: - uint64_t GetPeriod(const SampleRecord& r) override { - return r.period_data.period; - } + uint64_t GetPeriod(const SampleRecord& r) override { return r.period_data.period; } }; // Build sample tree based on the time difference between current sample and next sample. @@ -295,7 +281,7 @@ class TimestampSampleTreeBuilder : public ReportCmdSampleTreeBuilder { public: TimestampSampleTreeBuilder(const SampleComparator<SampleEntry>& sample_comparator, ThreadTree* thread_tree) - : ReportCmdSampleTreeBuilder(sample_comparator, thread_tree) { } + : ReportCmdSampleTreeBuilder(sample_comparator, thread_tree) {} void ReportCmdProcessSampleRecord(std::shared_ptr<SampleRecord>& r) override { pid_t tid = static_cast<pid_t>(r->tid_data.tid); @@ -355,18 +341,14 @@ struct SampleTreeBuilderOptions { }; using ReportCmdSampleTreeSorter = SampleTreeSorter<SampleEntry>; -using ReportCmdSampleTreeDisplayer = - SampleTreeDisplayer<SampleEntry, SampleTree>; +using ReportCmdSampleTreeDisplayer = SampleTreeDisplayer<SampleEntry, SampleTree>; -using ReportCmdCallgraphDisplayer = - CallgraphDisplayer<SampleEntry, CallChainNode<SampleEntry>>; +using ReportCmdCallgraphDisplayer = CallgraphDisplayer<SampleEntry, CallChainNode<SampleEntry>>; -class ReportCmdCallgraphDisplayerWithVaddrInFile - : public ReportCmdCallgraphDisplayer { +class ReportCmdCallgraphDisplayerWithVaddrInFile : public ReportCmdCallgraphDisplayer { protected: std::string PrintSampleName(const SampleEntry* sample) override { - return android::base::StringPrintf("%s [+0x%" PRIx64 "]", - sample->symbol->DemangledName(), + return android::base::StringPrintf("%s [+0x%" PRIx64 "]", sample->symbol->DemangledName(), sample->vaddr_in_file); } }; @@ -379,9 +361,8 @@ struct EventAttrWithName { class ReportCommand : public Command { public: ReportCommand() - : Command( - "report", "report sampling information in perf.data", - // clang-format off + : Command("report", "report sampling information in perf.data", + // clang-format off "Usage: simpleperf report [options]\n" "The default options are: -i perf.data --sort comm,pid,tid,dso,symbol.\n" "-b Use the branch-to addresses in sampled take branches instead of the\n" @@ -433,8 +414,8 @@ class ReportCommand : public Command { "--symfs <dir> Look for files with symbols relative to this directory.\n" "--tids tid1,tid2,... Report only for selected tids.\n" "--vmlinux <file> Parse kernel symbols from <file>.\n" - // clang-format on - ), + // clang-format on + ), record_filename_("perf.data"), record_file_arch_(GetBuildArch()), use_branch_address_(false), @@ -528,29 +509,29 @@ bool ReportCommand::Run(const std::vector<std::string>& args) { bool ReportCommand::ParseOptions(const std::vector<std::string>& args) { static OptionFormatMap option_formats = { - {"-b", {OptionValueType::NONE, OptionType::SINGLE}}, - {"--children", {OptionValueType::NONE, OptionType::SINGLE}}, - {"--comms", {OptionValueType::STRING, OptionType::MULTIPLE}}, - {"--cpu", {OptionValueType::STRING, OptionType::MULTIPLE}}, - {"--csv", {OptionValueType::NONE, OptionType::SINGLE}}, - {"--dsos", {OptionValueType::STRING, OptionType::MULTIPLE}}, - {"--full-callgraph", {OptionValueType::NONE, OptionType::SINGLE}}, - {"-g", {OptionValueType::OPT_STRING, OptionType::SINGLE}}, - {"-i", {OptionValueType::STRING, OptionType::SINGLE}}, - {"--kallsyms", {OptionValueType::STRING, OptionType::SINGLE}}, - {"--max-stack", {OptionValueType::UINT, OptionType::SINGLE}}, - {"-n", {OptionValueType::NONE, OptionType::SINGLE}}, - {"--no-demangle", {OptionValueType::NONE, OptionType::SINGLE}}, - {"--no-show-ip", {OptionValueType::NONE, OptionType::SINGLE}}, - {"-o", {OptionValueType::STRING, OptionType::SINGLE}}, - {"--percent-limit", {OptionValueType::DOUBLE, OptionType::SINGLE}}, - {"--pids", {OptionValueType::STRING, OptionType::MULTIPLE}}, - {"--tids", {OptionValueType::STRING, OptionType::MULTIPLE}}, - {"--raw-period", {OptionValueType::NONE, OptionType::SINGLE}}, - {"--sort", {OptionValueType::STRING, OptionType::SINGLE}}, - {"--symbols", {OptionValueType::STRING, OptionType::MULTIPLE}}, - {"--symfs", {OptionValueType::STRING, OptionType::SINGLE}}, - {"--vmlinux", {OptionValueType::STRING, OptionType::SINGLE}}, + {"-b", {OptionValueType::NONE, OptionType::SINGLE}}, + {"--children", {OptionValueType::NONE, OptionType::SINGLE}}, + {"--comms", {OptionValueType::STRING, OptionType::MULTIPLE}}, + {"--cpu", {OptionValueType::STRING, OptionType::MULTIPLE}}, + {"--csv", {OptionValueType::NONE, OptionType::SINGLE}}, + {"--dsos", {OptionValueType::STRING, OptionType::MULTIPLE}}, + {"--full-callgraph", {OptionValueType::NONE, OptionType::SINGLE}}, + {"-g", {OptionValueType::OPT_STRING, OptionType::SINGLE}}, + {"-i", {OptionValueType::STRING, OptionType::SINGLE}}, + {"--kallsyms", {OptionValueType::STRING, OptionType::SINGLE}}, + {"--max-stack", {OptionValueType::UINT, OptionType::SINGLE}}, + {"-n", {OptionValueType::NONE, OptionType::SINGLE}}, + {"--no-demangle", {OptionValueType::NONE, OptionType::SINGLE}}, + {"--no-show-ip", {OptionValueType::NONE, OptionType::SINGLE}}, + {"-o", {OptionValueType::STRING, OptionType::SINGLE}}, + {"--percent-limit", {OptionValueType::DOUBLE, OptionType::SINGLE}}, + {"--pids", {OptionValueType::STRING, OptionType::MULTIPLE}}, + {"--tids", {OptionValueType::STRING, OptionType::MULTIPLE}}, + {"--raw-period", {OptionValueType::NONE, OptionType::SINGLE}}, + {"--sort", {OptionValueType::STRING, OptionType::SINGLE}}, + {"--symbols", {OptionValueType::STRING, OptionType::MULTIPLE}}, + {"--symfs", {OptionValueType::STRING, OptionType::SINGLE}}, + {"--vmlinux", {OptionValueType::STRING, OptionType::SINGLE}}, }; OptionValueMap options; @@ -685,8 +666,7 @@ bool ReportCommand::BuildSampleComparatorAndDisplayer(bool print_sample_count, } for (auto& key : sort_keys) { - if (!use_branch_address_ && - branch_sort_keys.find(key) != branch_sort_keys.end()) { + if (!use_branch_address_ && branch_sort_keys.find(key) != branch_sort_keys.end()) { LOG(ERROR) << "sort key '" << key << "' can only be used with -b option."; return false; } @@ -748,8 +728,7 @@ bool ReportCommand::BuildSampleComparatorAndDisplayer(bool print_sample_count, } if (has_symbol_key) { if (has_vaddr_in_file_key) { - displayer.AddExclusiveDisplayFunction( - ReportCmdCallgraphDisplayerWithVaddrInFile()); + displayer.AddExclusiveDisplayFunction(ReportCmdCallgraphDisplayerWithVaddrInFile()); } else { displayer.AddExclusiveDisplayFunction(ReportCmdCallgraphDisplayer( callgraph_max_stack_, callgraph_percent_limit_, brief_callgraph_)); @@ -799,8 +778,7 @@ bool ReportCommand::ReadEventAttrFromRecordFile() { } } if (!has_branch_stack) { - LOG(ERROR) << record_filename_ - << " is not recorded with branch stack sampling option."; + LOG(ERROR) << record_filename_ << " is not recorded with branch stack sampling option."; return false; } } @@ -820,8 +798,7 @@ bool ReportCommand::ReadEventAttrFromRecordFile() { bool ReportCommand::ReadFeaturesFromRecordFile() { record_file_reader_->LoadBuildIdAndFileFeatures(thread_tree_); - std::string arch = - record_file_reader_->ReadFeatureString(PerfFileFormat::FEAT_ARCH); + std::string arch = record_file_reader_->ReadFeatureString(PerfFileFormat::FEAT_ARCH); if (!arch.empty()) { record_file_arch_ = GetArchType(arch); if (record_file_arch_ == ARCH_UNSUPPORTED) { @@ -840,9 +817,8 @@ bool ReportCommand::ReadFeaturesFromRecordFile() { if (s == "-a") { system_wide_collection_ = true; break; - } else if (s == "--call-graph" || s == "--cpu" || s == "-e" || - s == "-f" || s == "-F" || s == "-j" || s == "-m" || - s == "-o" || s == "-p" || s == "-t") { + } else if (s == "--call-graph" || s == "--cpu" || s == "-e" || s == "-f" || s == "-F" || + s == "-j" || s == "-m" || s == "-o" || s == "-p" || s == "-t") { i++; } else if (!s.empty() && s[0] != '-') { break; @@ -852,8 +828,8 @@ bool ReportCommand::ReadFeaturesFromRecordFile() { } if (record_file_reader_->HasFeature(PerfFileFormat::FEAT_TRACING_DATA)) { std::vector<char> tracing_data; - if (!record_file_reader_->ReadFeatureSection( - PerfFileFormat::FEAT_TRACING_DATA, &tracing_data)) { + if (!record_file_reader_->ReadFeatureSection(PerfFileFormat::FEAT_TRACING_DATA, + &tracing_data)) { return false; } if (!ProcessTracingData(tracing_data)) { @@ -880,9 +856,7 @@ bool ReportCommand::ReadSampleTreeFromRecordFile() { } if (!record_file_reader_->ReadDataSection( - [this](std::unique_ptr<Record> record) { - return ProcessRecord(std::move(record)); - })) { + [this](std::unique_ptr<Record> record) { return ProcessRecord(std::move(record)); })) { return false; } for (size_t i = 0; i < sample_tree_builder_.size(); ++i) { @@ -912,7 +886,6 @@ bool ReportCommand::ProcessRecord(std::unique_ptr<Record> record) { return true; } - void ReportCommand::ProcessSampleRecordInTraceOffCpuMode(std::unique_ptr<Record> record, size_t attr_id) { std::shared_ptr<SampleRecord> r(static_cast<SampleRecord*>(record.release())); @@ -962,8 +935,8 @@ bool ReportCommand::PrintReport() { } EventAttrWithName& attr = event_attrs_[i]; SampleTree& sample_tree = sample_tree_[i]; - fprintf(report_fp, "Event: %s (type %u, config %llu)\n", attr.name.c_str(), - attr.attr.type, attr.attr.config); + fprintf(report_fp, "Event: %s (type %u, config %llu)\n", attr.name.c_str(), attr.attr.type, + attr.attr.config); fprintf(report_fp, "Samples: %" PRIu64 "\n", sample_tree.total_samples); if (sample_tree.total_error_callchains != 0) { fprintf(report_fp, "Error Callchains: %" PRIu64 ", %f%%\n", @@ -994,8 +967,7 @@ void ReportCommand::PrintReportContext(FILE* report_fp) { namespace simpleperf { void RegisterReportCommand() { - RegisterCommand("report", - [] { return std::unique_ptr<Command>(new ReportCommand()); }); + RegisterCommand("report", [] { return std::unique_ptr<Command>(new ReportCommand()); }); } } // namespace simpleperf diff --git a/simpleperf/cmd_report_sample.cpp b/simpleperf/cmd_report_sample.cpp index 98ab3ccd..2315f6e4 100644 --- a/simpleperf/cmd_report_sample.cpp +++ b/simpleperf/cmd_report_sample.cpp @@ -57,9 +57,7 @@ class ProtobufFileReader : public google::protobuf::io::CopyingInputStream { public: explicit ProtobufFileReader(FILE* in_fp) : in_fp_(in_fp) {} - int Read(void* buffer, int size) override { - return fread(buffer, 1, size, in_fp_); - } + int Read(void* buffer, int size) override { return fread(buffer, 1, size, in_fp_); } private: FILE* in_fp_; @@ -74,9 +72,8 @@ struct CallEntry { class ReportSampleCommand : public Command { public: ReportSampleCommand() - : Command( - "report-sample", "report raw sample information in perf.data", - // clang-format off + : Command("report-sample", "report raw sample information in perf.data", + // clang-format off "Usage: simpleperf report-sample [options]\n" "--dump-protobuf-report <file>\n" " Dump report file generated by\n" @@ -92,8 +89,8 @@ class ReportSampleCommand : public Command { " are not available in perf.data.\n" "--show-art-frames Show frames of internal methods in the ART Java interpreter.\n" "--symdir <dir> Look for files with symbols in a directory recursively.\n" - // clang-format on - ), + // clang-format on + ), record_filename_("perf.data"), show_callchain_(false), use_protobuf_(false), @@ -192,10 +189,8 @@ bool ReportSampleCommand::Run(const std::vector<std::string>& args) { return false; } protobuf_writer.reset(new ProtobufFileWriter(report_fp_)); - protobuf_os.reset(new google::protobuf::io::CopyingOutputStreamAdaptor( - protobuf_writer.get())); - protobuf_coded_os.reset( - new google::protobuf::io::CodedOutputStream(protobuf_os.get())); + protobuf_os.reset(new google::protobuf::io::CopyingOutputStreamAdaptor(protobuf_writer.get())); + protobuf_coded_os.reset(new google::protobuf::io::CodedOutputStream(protobuf_os.get())); coded_os_ = protobuf_coded_os.get(); } @@ -204,9 +199,7 @@ bool ReportSampleCommand::Run(const std::vector<std::string>& args) { return false; } if (!record_file_reader_->ReadDataSection( - [this](std::unique_ptr<Record> record) { - return ProcessRecord(std::move(record)); - })) { + [this](std::unique_ptr<Record> record) { return ProcessRecord(std::move(record)); })) { return false; } @@ -283,8 +276,7 @@ bool ReportSampleCommand::ParseOptions(const std::vector<std::string>& args) { bool ReportSampleCommand::DumpProtobufReport(const std::string& filename) { GOOGLE_PROTOBUF_VERIFY_VERSION; - std::unique_ptr<FILE, decltype(&fclose)> fp(fopen(filename.c_str(), "rb"), - fclose); + std::unique_ptr<FILE, decltype(&fclose)> fp(fopen(filename.c_str(), "rb"), fclose); if (fp == nullptr) { PLOG(ERROR) << "failed to open " << filename; return false; @@ -344,8 +336,7 @@ bool ReportSampleCommand::DumpProtobufReport(const std::string& filename) { FprintIndented(report_fp_, 1, "callchain:\n"); for (int i = 0; i < sample.callchain_size(); ++i) { const proto::Sample_CallChainEntry& callchain = sample.callchain(i); - FprintIndented(report_fp_, 2, "vaddr_in_file: %" PRIx64 "\n", - callchain.vaddr_in_file()); + FprintIndented(report_fp_, 2, "vaddr_in_file: %" PRIx64 "\n", callchain.vaddr_in_file()); FprintIndented(report_fp_, 2, "file_id: %u\n", callchain.file_id()); int32_t symbol_id = callchain.symbol_id(); FprintIndented(report_fp_, 2, "symbol_id: %d\n", symbol_id); @@ -361,10 +352,8 @@ bool ReportSampleCommand::DumpProtobufReport(const std::string& filename) { } else if (proto_record.has_lost()) { auto& lost = proto_record.lost(); FprintIndented(report_fp_, 0, "lost_situation:\n"); - FprintIndented(report_fp_, 1, "sample_count: %" PRIu64 "\n", - lost.sample_count()); - FprintIndented(report_fp_, 1, "lost_count: %" PRIu64 "\n", - lost.lost_count()); + FprintIndented(report_fp_, 1, "sample_count: %" PRIu64 "\n", lost.sample_count()); + FprintIndented(report_fp_, 1, "lost_count: %" PRIu64 "\n", lost.lost_count()); } else if (proto_record.has_file()) { auto& file = proto_record.file(); FprintIndented(report_fp_, 0, "file:\n"); @@ -377,8 +366,8 @@ bool ReportSampleCommand::DumpProtobufReport(const std::string& filename) { FprintIndented(report_fp_, 1, "mangled_symbol: %s\n", file.mangled_symbol(i).c_str()); } if (file.id() != files.size()) { - LOG(ERROR) << "file id doesn't increase orderly, expected " - << files.size() << ", really " << file.id(); + LOG(ERROR) << "file id doesn't increase orderly, expected " << files.size() << ", really " + << file.id(); return false; } files.push_back(file.symbol_size()); @@ -405,13 +394,12 @@ bool ReportSampleCommand::DumpProtobufReport(const std::string& filename) { } for (auto pair : max_symbol_id_map) { if (pair.first >= files.size()) { - LOG(ERROR) << "file_id(" << pair.first << ") >= file count (" - << files.size() << ")"; + LOG(ERROR) << "file_id(" << pair.first << ") >= file count (" << files.size() << ")"; return false; } if (static_cast<uint32_t>(pair.second) >= files[pair.first]) { - LOG(ERROR) << "symbol_id(" << pair.second << ") >= symbol count (" - << files[pair.first] << ") in file_id( " << pair.first << ")"; + LOG(ERROR) << "symbol_id(" << pair.second << ") >= symbol count (" << files[pair.first] + << ") in file_id( " << pair.first << ")"; return false; } } @@ -556,9 +544,8 @@ bool ReportSampleCommand::PrintSampleRecordInProtobuf(const SampleRecord& r, // the call chain ends at __start_thread in libc.so. // The call chain of the main thread can go beyond __libc_init, to _start (<= android O) or // _start_main (> android O). - if (node.dso->FileName() == "libc.so" && - (strcmp(node.symbol->Name(), "__libc_init") == 0 || - strcmp(node.symbol->Name(), "__start_thread") == 0)) { + if (node.dso->FileName() == "libc.so" && (strcmp(node.symbol->Name(), "__libc_init") == 0 || + strcmp(node.symbol->Name(), "__start_thread") == 0)) { break; } } @@ -574,10 +561,8 @@ bool ReportSampleCommand::WriteRecordInProtobuf(proto::Record& proto_record) { return true; } -bool ReportSampleCommand::GetCallEntry(const ThreadEntry* thread, - bool in_kernel, uint64_t ip, - bool omit_unknown_dso, - CallEntry* entry) { +bool ReportSampleCommand::GetCallEntry(const ThreadEntry* thread, bool in_kernel, uint64_t ip, + bool omit_unknown_dso, CallEntry* entry) { const MapEntry* map = thread_tree_.FindMap(thread, ip, in_kernel); if (omit_unknown_dso && thread_tree_.IsUnknownDso(map->dso)) { return false; @@ -625,8 +610,7 @@ bool ReportSampleCommand::PrintFileInfoInProtobuf() { dump_symbols.push_back(&sym); } } - std::sort(dump_symbols.begin(), dump_symbols.end(), - Symbol::CompareByDumpId); + std::sort(dump_symbols.begin(), dump_symbols.end(), Symbol::CompareByDumpId); for (const auto& sym : dump_symbols) { std::string* symbol = file->add_symbol(); @@ -694,9 +678,8 @@ void ReportSampleCommand::PrintLostSituation() { namespace simpleperf { void RegisterReportSampleCommand() { - RegisterCommand("report-sample", [] { - return std::unique_ptr<Command>(new ReportSampleCommand()); - }); + RegisterCommand("report-sample", + [] { return std::unique_ptr<Command>(new ReportSampleCommand()); }); } } // namespace simpleperf diff --git a/simpleperf/cmd_report_sample_test.cpp b/simpleperf/cmd_report_sample_test.cpp index c8529efc..3f29d3d8 100644 --- a/simpleperf/cmd_report_sample_test.cpp +++ b/simpleperf/cmd_report_sample_test.cpp @@ -28,20 +28,19 @@ static std::unique_ptr<Command> ReportSampleCmd() { } TEST(cmd_report_sample, text) { - ASSERT_TRUE( - ReportSampleCmd()->Run({"-i", GetTestData(PERF_DATA_WITH_SYMBOLS)})); + ASSERT_TRUE(ReportSampleCmd()->Run({"-i", GetTestData(PERF_DATA_WITH_SYMBOLS)})); } TEST(cmd_report_sample, output_option) { TemporaryFile tmpfile; - ASSERT_TRUE(ReportSampleCmd()->Run( - {"-i", GetTestData(PERF_DATA_WITH_SYMBOLS), "-o", tmpfile.path})); + ASSERT_TRUE( + ReportSampleCmd()->Run({"-i", GetTestData(PERF_DATA_WITH_SYMBOLS), "-o", tmpfile.path})); } TEST(cmd_report_sample, show_callchain_option) { TemporaryFile tmpfile; - ASSERT_TRUE(ReportSampleCmd()->Run({"-i", GetTestData(CALLGRAPH_FP_PERF_DATA), - "-o", tmpfile.path, "--show-callchain"})); + ASSERT_TRUE(ReportSampleCmd()->Run( + {"-i", GetTestData(CALLGRAPH_FP_PERF_DATA), "-o", tmpfile.path, "--show-callchain"})); } static void GetProtobufReport(const std::string& test_data_file, std::string* protobuf_report, @@ -52,8 +51,8 @@ static void GetProtobufReport(const std::string& test_data_file, std::string* pr "--protobuf"}; args.insert(args.end(), extra_args.begin(), extra_args.end()); ASSERT_TRUE(ReportSampleCmd()->Run(args)); - ASSERT_TRUE(ReportSampleCmd()->Run({"--dump-protobuf-report", tmpfile.path, - "-o", tmpfile2.path})); + ASSERT_TRUE( + ReportSampleCmd()->Run({"--dump-protobuf-report", tmpfile.path, "-o", tmpfile2.path})); ASSERT_TRUE(android::base::ReadFileToString(tmpfile2.path, protobuf_report)); } @@ -107,8 +106,7 @@ TEST(cmd_report_sample, app_package_name_in_meta_info) { TEST(cmd_report_sample, remove_unknown_kernel_symbols) { std::string data; // Test --remove-unknown-kernel-symbols on perf.data with kernel_symbols_available=false. - GetProtobufReport(PERF_DATA_WITH_KERNEL_SYMBOLS_AVAILABLE_FALSE, &data, - {"--show-callchain"}); + GetProtobufReport(PERF_DATA_WITH_KERNEL_SYMBOLS_AVAILABLE_FALSE, &data, {"--show-callchain"}); ASSERT_NE(data.find("time: 1368182962424044"), std::string::npos); ASSERT_NE(data.find("path: [kernel.kallsyms]"), std::string::npos); ASSERT_NE(data.find("path: /system/lib64/libc.so"), std::string::npos); @@ -123,8 +121,7 @@ TEST(cmd_report_sample, remove_unknown_kernel_symbols) { ASSERT_NE(data.find("path: /system/lib64/libc.so"), std::string::npos); // Test --remove-unknown-kernel-symbols on perf.data with kernel_symbols_available=true. - GetProtobufReport(PERF_DATA_WITH_KERNEL_SYMBOLS_AVAILABLE_TRUE, &data, - {"--show-callchain"}); + GetProtobufReport(PERF_DATA_WITH_KERNEL_SYMBOLS_AVAILABLE_TRUE, &data, {"--show-callchain"}); ASSERT_NE(data.find("time: 1368297633794862"), std::string::npos); ASSERT_NE(data.find("path: [kernel.kallsyms]"), std::string::npos); ASSERT_NE(data.find("symbol: binder_ioctl_write_read"), std::string::npos); diff --git a/simpleperf/cmd_report_test.cpp b/simpleperf/cmd_report_test.cpp index 01f513ee..fb79c931 100644 --- a/simpleperf/cmd_report_test.cpp +++ b/simpleperf/cmd_report_test.cpp @@ -38,19 +38,17 @@ static std::unique_ptr<Command> ReportCmd() { class ReportCommandTest : public ::testing::Test { protected: - void Report( - const std::string& perf_data, - const std::vector<std::string>& add_args = std::vector<std::string>()) { + void Report(const std::string& perf_data, + const std::vector<std::string>& add_args = std::vector<std::string>()) { ReportRaw(GetTestData(perf_data), add_args); } - void ReportRaw( - const std::string& perf_data, - const std::vector<std::string>& add_args = std::vector<std::string>()) { + void ReportRaw(const std::string& perf_data, + const std::vector<std::string>& add_args = std::vector<std::string>()) { success = false; TemporaryFile tmp_file; - std::vector<std::string> args = { - "-i", perf_data, "--symfs", GetTestDataDir(), "-o", tmp_file.path}; + std::vector<std::string> args = {"-i", perf_data, "--symfs", GetTestDataDir(), + "-o", tmp_file.path}; args.insert(args.end(), add_args.begin(), add_args.end()); ASSERT_TRUE(ReportCmd()->Run(args)); ASSERT_TRUE(android::base::ReadFileToString(tmp_file.path, &content)); @@ -99,8 +97,7 @@ TEST_F(ReportCommandTest, sort_option_pid) { Report(PERF_DATA, {"--sort", "pid"}); ASSERT_TRUE(success); size_t line_index = 0; - while (line_index < lines.size() && - lines[line_index].find("Pid") == std::string::npos) { + while (line_index < lines.size() && lines[line_index].find("Pid") == std::string::npos) { line_index++; } ASSERT_LT(line_index + 2, lines.size()); @@ -110,8 +107,7 @@ TEST_F(ReportCommandTest, sort_option_more_than_one) { Report(PERF_DATA, {"--sort", "comm,pid,dso,symbol"}); ASSERT_TRUE(success); size_t line_index = 0; - while (line_index < lines.size() && - lines[line_index].find("Overhead") == std::string::npos) { + while (line_index < lines.size() && lines[line_index].find("Overhead") == std::string::npos) { line_index++; } ASSERT_LT(line_index + 1, lines.size()); @@ -129,8 +125,7 @@ TEST_F(ReportCommandTest, children_option) { for (size_t i = 0; i < lines.size(); ++i) { char name[1024]; std::pair<double, double> pair; - if (sscanf(lines[i].c_str(), "%lf%%%lf%%%s", &pair.first, &pair.second, - name) == 3) { + if (sscanf(lines[i].c_str(), "%lf%%%lf%%%s", &pair.first, &pair.second, name) == 3) { map.insert(std::make_pair(name, pair)); } } @@ -182,8 +177,7 @@ TEST_F(ReportCommandTest, callgraph_option) { static bool AllItemsWithString(std::vector<std::string>& lines, const std::vector<std::string>& strs) { size_t line_index = 0; - while (line_index < lines.size() && - lines[line_index].find("Overhead") == std::string::npos) { + while (line_index < lines.size() && lines[line_index].find("Overhead") == std::string::npos) { line_index++; } if (line_index == lines.size() || line_index + 1 == lines.size()) { @@ -210,19 +204,16 @@ TEST_F(ReportCommandTest, pid_filter_option) { ASSERT_TRUE(success); ASSERT_FALSE(AllItemsWithString(lines, {"17441"})); ASSERT_FALSE(AllItemsWithString(lines, {"17441", "17443"})); - Report(PERF_DATA_WITH_MULTIPLE_PIDS_AND_TIDS, - {"--sort", "pid", "--pids", "17441"}); + Report(PERF_DATA_WITH_MULTIPLE_PIDS_AND_TIDS, {"--sort", "pid", "--pids", "17441"}); ASSERT_TRUE(success); ASSERT_TRUE(AllItemsWithString(lines, {"17441"})); - Report(PERF_DATA_WITH_MULTIPLE_PIDS_AND_TIDS, - {"--sort", "pid", "--pids", "17441,17443"}); + Report(PERF_DATA_WITH_MULTIPLE_PIDS_AND_TIDS, {"--sort", "pid", "--pids", "17441,17443"}); ASSERT_TRUE(success); ASSERT_TRUE(AllItemsWithString(lines, {"17441", "17443"})); // Test that --pids option is not the same as --tids option. // Thread 17445 and 17441 are in process 17441. - Report(PERF_DATA_WITH_MULTIPLE_PIDS_AND_TIDS, - {"--sort", "tid", "--pids", "17441"}); + Report(PERF_DATA_WITH_MULTIPLE_PIDS_AND_TIDS, {"--sort", "tid", "--pids", "17441"}); ASSERT_TRUE(success); ASSERT_NE(content.find("17441"), std::string::npos); ASSERT_NE(content.find("17445"), std::string::npos); @@ -242,12 +233,10 @@ TEST_F(ReportCommandTest, tid_filter_option) { ASSERT_TRUE(success); ASSERT_FALSE(AllItemsWithString(lines, {"17441"})); ASSERT_FALSE(AllItemsWithString(lines, {"17441", "17445"})); - Report(PERF_DATA_WITH_MULTIPLE_PIDS_AND_TIDS, - {"--sort", "tid", "--tids", "17441"}); + Report(PERF_DATA_WITH_MULTIPLE_PIDS_AND_TIDS, {"--sort", "tid", "--tids", "17441"}); ASSERT_TRUE(success); ASSERT_TRUE(AllItemsWithString(lines, {"17441"})); - Report(PERF_DATA_WITH_MULTIPLE_PIDS_AND_TIDS, - {"--sort", "tid", "--tids", "17441,17445"}); + Report(PERF_DATA_WITH_MULTIPLE_PIDS_AND_TIDS, {"--sort", "tid", "--tids", "17441,17445"}); ASSERT_TRUE(success); ASSERT_TRUE(AllItemsWithString(lines, {"17441", "17445"})); } @@ -292,12 +281,10 @@ TEST_F(ReportCommandTest, symbol_filter_option) { ASSERT_TRUE(success); ASSERT_FALSE(AllItemsWithString(lines, {"func2(int, int)"})); ASSERT_FALSE(AllItemsWithString(lines, {"main", "func2(int, int)"})); - Report(PERF_DATA_WITH_SYMBOLS, - {"--sort", "symbol", "--symbols", "func2(int, int)"}); + Report(PERF_DATA_WITH_SYMBOLS, {"--sort", "symbol", "--symbols", "func2(int, int)"}); ASSERT_TRUE(success); ASSERT_TRUE(AllItemsWithString(lines, {"func2(int, int)"})); - Report(PERF_DATA_WITH_SYMBOLS, - {"--sort", "symbol", "--symbols", "main;func2(int, int)"}); + Report(PERF_DATA_WITH_SYMBOLS, {"--sort", "symbol", "--symbols", "main;func2(int, int)"}); ASSERT_TRUE(success); ASSERT_TRUE(AllItemsWithString(lines, {"main", "func2(int, int)"})); } @@ -317,19 +304,16 @@ TEST_F(ReportCommandTest, use_branch_address) { } } } - ASSERT_NE(hit_set.find(std::make_pair<std::string, std::string>( - "GlobalFunc", "CalledFunc")), + ASSERT_NE(hit_set.find(std::make_pair<std::string, std::string>("GlobalFunc", "CalledFunc")), hit_set.end()); - ASSERT_NE(hit_set.find(std::make_pair<std::string, std::string>( - "CalledFunc", "GlobalFunc")), + ASSERT_NE(hit_set.find(std::make_pair<std::string, std::string>("CalledFunc", "GlobalFunc")), hit_set.end()); } TEST_F(ReportCommandTest, report_symbols_of_nativelib_in_apk) { Report(NATIVELIB_IN_APK_PERF_DATA); ASSERT_TRUE(success); - ASSERT_NE(content.find(GetUrlInApk(APK_FILE, NATIVELIB_IN_APK)), - std::string::npos); + ASSERT_NE(content.find(GetUrlInApk(APK_FILE, NATIVELIB_IN_APK)), std::string::npos); ASSERT_NE(content.find("Func2"), std::string::npos); } @@ -377,8 +361,7 @@ TEST_F(ReportCommandTest, report_sort_vaddr_in_file) { } TEST_F(ReportCommandTest, check_build_id) { - Report(PERF_DATA_FOR_BUILD_ID_CHECK, - {"--symfs", GetTestData(CORRECT_SYMFS_FOR_BUILD_ID_CHECK)}); + Report(PERF_DATA_FOR_BUILD_ID_CHECK, {"--symfs", GetTestData(CORRECT_SYMFS_FOR_BUILD_ID_CHECK)}); ASSERT_TRUE(success); ASSERT_NE(content.find("main"), std::string::npos); ASSERT_EXIT( @@ -408,8 +391,7 @@ TEST_F(ReportCommandTest, no_show_ip_option) { TEST_F(ReportCommandTest, no_symbol_table_warning) { ASSERT_EXIT( { - Report(PERF_DATA, - {"--symfs", GetTestData(SYMFS_FOR_NO_SYMBOL_TABLE_WARNING)}); + Report(PERF_DATA, {"--symfs", GetTestData(SYMFS_FOR_NO_SYMBOL_TABLE_WARNING)}); if (!success) { exit(1); } @@ -424,8 +406,7 @@ TEST_F(ReportCommandTest, no_symbol_table_warning) { TEST_F(ReportCommandTest, read_elf_file_warning) { ASSERT_EXIT( { - Report(PERF_DATA, - {"--symfs", GetTestData(SYMFS_FOR_READ_ELF_FILE_WARNING)}); + Report(PERF_DATA, {"--symfs", GetTestData(SYMFS_FOR_READ_ELF_FILE_WARNING)}); if (!success) { exit(1); } @@ -454,12 +435,10 @@ TEST_F(ReportCommandTest, max_stack_and_percent_limit_option) { ASSERT_TRUE(success); ASSERT_NE(content.find("89.03"), std::string::npos); - Report(PERF_DATA_MAX_STACK_AND_PERCENT_LIMIT, - {"-g", "--percent-limit", "90"}); + Report(PERF_DATA_MAX_STACK_AND_PERCENT_LIMIT, {"-g", "--percent-limit", "90"}); ASSERT_TRUE(success); ASSERT_EQ(content.find("89.03"), std::string::npos); - Report(PERF_DATA_MAX_STACK_AND_PERCENT_LIMIT, - {"-g", "--percent-limit", "70"}); + Report(PERF_DATA_MAX_STACK_AND_PERCENT_LIMIT, {"-g", "--percent-limit", "70"}); ASSERT_TRUE(success); ASSERT_NE(content.find("89.03"), std::string::npos); } @@ -568,16 +547,14 @@ TEST_F(ReportCommandTest, dwarf_callgraph) { CreateProcesses(1, &workloads); std::string pid = std::to_string(workloads[0]->GetPid()); TemporaryFile tmp_file; - ASSERT_TRUE( - RecordCmd()->Run({"-p", pid, "-g", "-o", tmp_file.path, "sleep", SLEEP_SEC})); + ASSERT_TRUE(RecordCmd()->Run({"-p", pid, "-g", "-o", tmp_file.path, "sleep", SLEEP_SEC})); ReportRaw(tmp_file.path, {"-g"}); ASSERT_TRUE(success); } TEST_F(ReportCommandTest, report_dwarf_callgraph_of_nativelib_in_apk) { Report(NATIVELIB_IN_APK_PERF_DATA, {"-g"}); - ASSERT_NE(content.find(GetUrlInApk(APK_FILE, NATIVELIB_IN_APK)), - std::string::npos); + ASSERT_NE(content.find(GetUrlInApk(APK_FILE, NATIVELIB_IN_APK)), std::string::npos); ASSERT_NE(content.find("Func2"), std::string::npos); ASSERT_NE(content.find("Func1"), std::string::npos); ASSERT_NE(content.find("GlobalFunc"), std::string::npos); @@ -591,8 +568,8 @@ TEST_F(ReportCommandTest, exclude_kernel_callchain) { CreateProcesses(1, &workloads); std::string pid = std::to_string(workloads[0]->GetPid()); TemporaryFile tmpfile; - ASSERT_TRUE(RecordCmd()->Run({"--trace-offcpu", "-e", "cpu-cycles:u", "-p", pid, - "--duration", "2", "-o", tmpfile.path, "-g"})); + ASSERT_TRUE(RecordCmd()->Run({"--trace-offcpu", "-e", "cpu-cycles:u", "-p", pid, "--duration", + "2", "-o", tmpfile.path, "-g"})); ReportRaw(tmpfile.path, {"-g"}); ASSERT_TRUE(success); ASSERT_EQ(content.find("[kernel.kallsyms]"), std::string::npos); diff --git a/simpleperf/cmd_stat.cpp b/simpleperf/cmd_stat.cpp index a3963834..b9139743 100644 --- a/simpleperf/cmd_stat.cpp +++ b/simpleperf/cmd_stat.cpp @@ -33,6 +33,7 @@ #include <android-base/strings.h> #include <android-base/unique_fd.h> +#include "IOEventLoop.h" #include "cmd_stat_impl.h" #include "command.h" #include "environment.h" @@ -40,7 +41,6 @@ #include "event_fd.h" #include "event_selection_set.h" #include "event_type.h" -#include "IOEventLoop.h" #include "utils.h" #include "workload.h" @@ -342,8 +342,9 @@ class DevfreqCounters { class StatCommand : public Command { public: StatCommand() - : Command("stat", "gather performance counter information", - // clang-format off + : Command( + "stat", "gather performance counter information", + // clang-format off "Usage: simpleperf stat [options] [command [command-args]]\n" " Gather performance counter information of running [command].\n" " And -a/-p/-t option can be used to change target of counter information.\n" @@ -413,8 +414,8 @@ class StatCommand : public Command { "--out-fd <fd> Write output to a file descriptor.\n" "--stop-signal-fd <fd> Stop stating when fd is readable.\n" #endif - // clang-format on - ), + // clang-format on + ), verbose_mode_(false), system_wide_collection_(false), child_inherit_(true), @@ -439,8 +440,7 @@ class StatCommand : public Command { void SetEventSelectionFlags(); void MonitorEachThread(); void AdjustToIntervalOnlyValues(std::vector<CountersInfo>& counters); - bool ShowCounters(const std::vector<CountersInfo>& counters, - double duration_in_sec, FILE* fp); + bool ShowCounters(const std::vector<CountersInfo>& counters, double duration_in_sec, FILE* fp); bool verbose_mode_; bool system_wide_collection_; @@ -521,8 +521,7 @@ bool StatCommand::Run(const std::vector<std::string>& args) { std::set<pid_t> pids = WaitForAppProcesses(app_package_name_); event_selection_set_.AddMonitoredProcesses(pids); } else { - LOG(ERROR) - << "No threads to monitor. Try `simpleperf help stat` for help\n"; + LOG(ERROR) << "No threads to monitor. Try `simpleperf help stat` for help\n"; return false; } } else { @@ -568,9 +567,7 @@ bool StatCommand::Run(const std::vector<std::string>& args) { if (need_to_check_targets && !event_selection_set_.StopWhenNoMoreTargets()) { return false; } - auto exit_loop_callback = [loop]() { - return loop->ExitLoop(); - }; + auto exit_loop_callback = [loop]() { return loop->ExitLoop(); }; if (!loop->AddSignalEvents({SIGCHLD, SIGINT, SIGTERM, SIGHUP}, exit_loop_callback)) { return false; } @@ -585,26 +582,23 @@ bool StatCommand::Run(const std::vector<std::string>& args) { } } auto print_counters = [&]() { - auto end_time = std::chrono::steady_clock::now(); - if (!event_selection_set_.ReadCounters(&counters)) { - return false; - } - double duration_in_sec = - std::chrono::duration_cast<std::chrono::duration<double>>(end_time - - start_time) - .count(); - if (interval_only_values_) { - AdjustToIntervalOnlyValues(counters); - } - if (!ShowCounters(counters, duration_in_sec, fp)) { - return false; - } - return true; + auto end_time = std::chrono::steady_clock::now(); + if (!event_selection_set_.ReadCounters(&counters)) { + return false; + } + double duration_in_sec = + std::chrono::duration_cast<std::chrono::duration<double>>(end_time - start_time).count(); + if (interval_only_values_) { + AdjustToIntervalOnlyValues(counters); + } + if (!ShowCounters(counters, duration_in_sec, fp)) { + return false; + } + return true; }; if (interval_in_ms_ != 0) { - if (!loop->AddPeriodicEvent(SecondToTimeval(interval_in_ms_ / 1000.0), - print_counters)) { + if (!loop->AddPeriodicEvent(SecondToTimeval(interval_in_ms_ / 1000.0), print_counters)) { return false; } } @@ -746,8 +740,7 @@ bool StatCommand::AddDefaultMeasuredEventTypes() { // It is not an error when some event types in the default list are not // supported by the kernel. const EventType* type = FindEventTypeByName(name); - if (type != nullptr && - IsEventAttrSupported(CreateDefaultPerfEventAttr(*type), name)) { + if (type != nullptr && IsEventAttrSupported(CreateDefaultPerfEventAttr(*type), name)) { if (!event_selection_set_.AddEventType(name)) { return false; } @@ -811,8 +804,8 @@ void StatCommand::AdjustToIntervalOnlyValues(std::vector<CountersInfo>& counters } } -bool StatCommand::ShowCounters(const std::vector<CountersInfo>& counters, - double duration_in_sec, FILE* fp) { +bool StatCommand::ShowCounters(const std::vector<CountersInfo>& counters, double duration_in_sec, + FILE* fp) { if (csv_) { fprintf(fp, "Performance counter statistics,\n"); } else { @@ -823,19 +816,18 @@ bool StatCommand::ShowCounters(const std::vector<CountersInfo>& counters, for (auto& counters_info : counters) { for (auto& counter_info : counters_info.counters) { if (csv_) { - fprintf(fp, "%s,tid,%d,cpu,%d,count,%" PRIu64 ",time_enabled,%" PRIu64 - ",time running,%" PRIu64 ",id,%" PRIu64 ",\n", - counters_info.event_name.c_str(), counter_info.tid, - counter_info.cpu, counter_info.counter.value, - counter_info.counter.time_enabled, + fprintf(fp, + "%s,tid,%d,cpu,%d,count,%" PRIu64 ",time_enabled,%" PRIu64 + ",time running,%" PRIu64 ",id,%" PRIu64 ",\n", + counters_info.event_name.c_str(), counter_info.tid, counter_info.cpu, + counter_info.counter.value, counter_info.counter.time_enabled, counter_info.counter.time_running, counter_info.counter.id); } else { fprintf(fp, "%s(tid %d, cpu %d): count %" PRIu64 ", time_enabled %" PRIu64 ", time running %" PRIu64 ", id %" PRIu64 "\n", - counters_info.event_name.c_str(), counter_info.tid, - counter_info.cpu, counter_info.counter.value, - counter_info.counter.time_enabled, + counters_info.event_name.c_str(), counter_info.tid, counter_info.cpu, + counter_info.counter.value, counter_info.counter.time_enabled, counter_info.counter.time_running, counter_info.counter.id); } } @@ -895,8 +887,7 @@ bool StatCommand::ShowCounters(const std::vector<CountersInfo>& counters, namespace simpleperf { void RegisterStatCommand() { - RegisterCommand("stat", - [] { return std::unique_ptr<Command>(new StatCommand); }); + RegisterCommand("stat", [] { return std::unique_ptr<Command>(new StatCommand); }); } } // namespace simpleperf diff --git a/simpleperf/cmd_stat_impl.h b/simpleperf/cmd_stat_impl.h index da8a559b..facd85eb 100644 --- a/simpleperf/cmd_stat_impl.h +++ b/simpleperf/cmd_stat_impl.h @@ -27,9 +27,9 @@ #include <android-base/stringprintf.h> +#include "SampleComparator.h" #include "command.h" #include "event_selection_set.h" -#include "SampleComparator.h" namespace simpleperf { diff --git a/simpleperf/cmd_stat_test.cpp b/simpleperf/cmd_stat_test.cpp index 0be03cf8..3e68ac6b 100644 --- a/simpleperf/cmd_stat_test.cpp +++ b/simpleperf/cmd_stat_test.cpp @@ -35,7 +35,9 @@ static std::unique_ptr<Command> StatCmd() { return CreateCommandInstance("stat"); } -TEST(stat_cmd, no_options) { ASSERT_TRUE(StatCmd()->Run({"sleep", "1"})); } +TEST(stat_cmd, no_options) { + ASSERT_TRUE(StatCmd()->Run({"sleep", "1"})); +} TEST(stat_cmd, event_option) { ASSERT_TRUE(StatCmd()->Run({"-e", "cpu-clock,task-clock", "sleep", "1"})); @@ -50,8 +52,7 @@ TEST(stat_cmd, verbose_option) { } TEST(stat_cmd, tracepoint_event) { - TEST_IN_ROOT(ASSERT_TRUE( - StatCmd()->Run({"-a", "-e", "sched:sched_switch", "sleep", "1"}))); + TEST_IN_ROOT(ASSERT_TRUE(StatCmd()->Run({"-a", "-e", "sched:sched_switch", "sleep", "1"}))); } TEST(stat_cmd, rN_event) { @@ -86,25 +87,23 @@ TEST(stat_cmd, pmu_event) { GTEST_LOG_(INFO) << "Omit arch " << GetBuildArch(); return; } - TEST_IN_ROOT(ASSERT_TRUE( - StatCmd()->Run({"-a", "-e", event_string, "sleep", "1"}))); + TEST_IN_ROOT(ASSERT_TRUE(StatCmd()->Run({"-a", "-e", event_string, "sleep", "1"}))); } TEST(stat_cmd, event_modifier) { TEST_REQUIRE_HW_COUNTER(); - ASSERT_TRUE( - StatCmd()->Run({"-e", "cpu-cycles:u,cpu-cycles:k", "sleep", "1"})); + ASSERT_TRUE(StatCmd()->Run({"-e", "cpu-cycles:u,cpu-cycles:k", "sleep", "1"})); } void RunWorkloadFunction() { while (true) { - for (volatile int i = 0; i < 10000; ++i); + for (volatile int i = 0; i < 10000; ++i) + ; usleep(1); } } -void CreateProcesses(size_t count, - std::vector<std::unique_ptr<Workload>>* workloads) { +void CreateProcesses(size_t count, std::vector<std::unique_ptr<Workload>>* workloads) { workloads->clear(); // Create workloads run longer than profiling time. for (size_t i = 0; i < count; ++i) { @@ -119,8 +118,8 @@ void CreateProcesses(size_t count, TEST(stat_cmd, existing_processes) { std::vector<std::unique_ptr<Workload>> workloads; CreateProcesses(2, &workloads); - std::string pid_list = android::base::StringPrintf( - "%d,%d", workloads[0]->GetPid(), workloads[1]->GetPid()); + std::string pid_list = + android::base::StringPrintf("%d,%d", workloads[0]->GetPid(), workloads[1]->GetPid()); ASSERT_TRUE(StatCmd()->Run({"-p", pid_list, "sleep", "1"})); } @@ -128,8 +127,8 @@ TEST(stat_cmd, existing_threads) { std::vector<std::unique_ptr<Workload>> workloads; CreateProcesses(2, &workloads); // Process id can be used as thread id in linux. - std::string tid_list = android::base::StringPrintf( - "%d,%d", workloads[0]->GetPid(), workloads[1]->GetPid()); + std::string tid_list = + android::base::StringPrintf("%d,%d", workloads[0]->GetPid(), workloads[1]->GetPid()); ASSERT_TRUE(StatCmd()->Run({"-t", tid_list, "sleep", "1"})); } @@ -140,8 +139,7 @@ TEST(stat_cmd, no_monitored_threads) { TEST(stat_cmd, group_option) { TEST_REQUIRE_HW_COUNTER(); - ASSERT_TRUE( - StatCmd()->Run({"--group", "cpu-clock,page-faults", "sleep", "1"})); + ASSERT_TRUE(StatCmd()->Run({"--group", "cpu-clock,page-faults", "sleep", "1"})); ASSERT_TRUE(StatCmd()->Run({"--group", "cpu-cycles,instructions", "--group", "cpu-cycles:u,instructions:u", "--group", "cpu-cycles:k,instructions:k", "sleep", "1"})); @@ -150,8 +148,8 @@ TEST(stat_cmd, group_option) { TEST(stat_cmd, auto_generated_summary) { TEST_REQUIRE_HW_COUNTER(); TemporaryFile tmp_file; - ASSERT_TRUE(StatCmd()->Run({"--group", "instructions:u,instructions:k", "-o", - tmp_file.path, "sleep", "1"})); + ASSERT_TRUE(StatCmd()->Run( + {"--group", "instructions:u,instructions:k", "-o", tmp_file.path, "sleep", "1"})); std::string s; ASSERT_TRUE(android::base::ReadFileToString(tmp_file.path, &s)); size_t pos = s.find("instructions:u"); @@ -164,24 +162,22 @@ TEST(stat_cmd, auto_generated_summary) { } TEST(stat_cmd, duration_option) { - ASSERT_TRUE( - StatCmd()->Run({"--duration", "1.2", "-p", std::to_string(getpid()), "--in-app"})); + ASSERT_TRUE(StatCmd()->Run({"--duration", "1.2", "-p", std::to_string(getpid()), "--in-app"})); ASSERT_TRUE(StatCmd()->Run({"--duration", "1", "sleep", "2"})); } TEST(stat_cmd, interval_option) { TemporaryFile tmp_file; - ASSERT_TRUE( - StatCmd()->Run({"--interval", "500.0", "--duration", "1.2", "-o", - tmp_file.path, "sleep", "2"})); + ASSERT_TRUE(StatCmd()->Run( + {"--interval", "500.0", "--duration", "1.2", "-o", tmp_file.path, "sleep", "2"})); std::string s; ASSERT_TRUE(android::base::ReadFileToString(tmp_file.path, &s)); size_t count = 0; size_t pos = 0; std::string subs = "statistics:"; - while((pos = s.find(subs, pos)) != s.npos) { + while ((pos = s.find(subs, pos)) != s.npos) { pos += subs.size(); - ++count ; + ++count; } ASSERT_EQ(count, 2UL); } @@ -192,8 +188,8 @@ TEST(stat_cmd, interval_option_in_system_wide) { TEST(stat_cmd, interval_only_values_option) { ASSERT_TRUE(StatCmd()->Run({"--interval", "500", "--interval-only-values", "sleep", "2"})); - TEST_IN_ROOT(ASSERT_TRUE(StatCmd()->Run({"-a", "--interval", "100", "--interval-only-values", - "--duration", "0.3"}))); + TEST_IN_ROOT(ASSERT_TRUE( + StatCmd()->Run({"-a", "--interval", "100", "--interval-only-values", "--duration", "0.3"}))); } TEST(stat_cmd, no_modifier_for_clock_events) { @@ -221,7 +217,8 @@ TEST(stat_cmd, stop_when_no_more_targets) { sleep(1); }); thread.detach(); - while (tid == 0); + while (tid == 0) + ; ASSERT_TRUE(StatCmd()->Run({"-t", std::to_string(tid), "--in-app"})); } @@ -253,8 +250,8 @@ TEST(stat_cmd, calculating_cpu_frequency) { if (line.find("task-clock") != std::string::npos) { ASSERT_EQ(sscanf(line.c_str(), "%lf(ms)", &task_clock_in_ms), 1); } else if (line.find("cpu-cycles") != std::string::npos) { - ASSERT_EQ(sscanf(line.c_str(), "%" SCNu64 ",cpu-cycles,%lf", &cpu_cycle_count, - &cpu_frequency), 2); + ASSERT_EQ( + sscanf(line.c_str(), "%" SCNu64 ",cpu-cycles,%lf", &cpu_cycle_count, &cpu_frequency), 2); } } ASSERT_NE(task_clock_in_ms, 0.0f); @@ -276,10 +273,12 @@ TEST(stat_cmd, set_comm_in_another_thread) { std::thread child([&]() { child_tid = gettid(); // stay on a cpu to make the monitored events of the child thread on that cpu. - while (!stop_child) {} + while (!stop_child) { + } }); - while (child_tid == 0) {} + while (child_tid == 0) { + } { EventSelectionSet set(true); @@ -346,7 +345,8 @@ TEST(stat_cmd, per_core_option) { } TEST(stat_cmd, sort_option) { - ASSERT_TRUE(StatCmd()->Run({"--per-thread", "--per-core", "--sort", "cpu,count", "sleep", "0.1"})); + ASSERT_TRUE( + StatCmd()->Run({"--per-thread", "--per-core", "--sort", "cpu,count", "sleep", "0.1"})); } TEST(stat_cmd, counter_sum) { @@ -384,9 +384,7 @@ class StatCmdSummaryBuilderTest : public ::testing::Test { int time_running = 1; }; - void SetUp() override { - sort_keys_ = {"count_per_thread", "tid", "cpu", "count"}; - } + void SetUp() override { sort_keys_ = {"count_per_thread", "tid", "cpu", "count"}; } void AddCounter(const CounterArg& arg) { if (thread_map_.count(arg.tid) == 0) { diff --git a/simpleperf/cmd_trace_sched.cpp b/simpleperf/cmd_trace_sched.cpp index 2977a756..42c49545 100644 --- a/simpleperf/cmd_trace_sched.cpp +++ b/simpleperf/cmd_trace_sched.cpp @@ -24,11 +24,11 @@ #include <android-base/logging.h> #include <android-base/stringprintf.h> +#include "SampleDisplayer.h" #include "command.h" #include "event_selection_set.h" #include "record.h" #include "record_file.h" -#include "SampleDisplayer.h" #include "tracing.h" #include "utils.h" @@ -38,7 +38,7 @@ using namespace simpleperf; namespace { struct SampleInfo { - uint64_t timestamp; // the time when the kernel generates the sample + uint64_t timestamp; // the time when the kernel generates the sample uint64_t runtime_in_ns; // the runtime of the thread in the sample SampleInfo(uint64_t timestamp = 0, uint64_t runtime_in_ns = 0) : timestamp(timestamp), runtime_in_ns(runtime_in_ns) {} @@ -92,8 +92,7 @@ class TraceSchedCommand : public Command { duration_in_sec_(10.0), spinloop_check_period_in_sec_(1.0), spinloop_check_rate_(0.8), - show_threads_(false) { - } + show_threads_(false) {} bool Run(const std::vector<std::string>& args); @@ -173,9 +172,13 @@ bool TraceSchedCommand::RecordSchedEvents(const std::string& record_file_path) { } std::unique_ptr<Command> record_cmd = CreateCommandInstance("record"); CHECK(record_cmd); - std::vector<std::string> record_args = {"-e", "sched:sched_stat_runtime", "-a", - "--duration", std::to_string(duration_in_sec_), - "-o", record_file_path}; + std::vector<std::string> record_args = {"-e", + "sched:sched_stat_runtime", + "-a", + "--duration", + std::to_string(duration_in_sec_), + "-o", + record_file_path}; if (IsSettingClockIdSupported()) { record_args.push_back("--clockid"); record_args.push_back("monotonic"); @@ -266,8 +269,8 @@ void TraceSchedCommand::ProcessSampleRecord(const SampleRecord& record) { if (thread.spin_info.runtime_in_check_period > time_period_in_ns * spinloop_check_rate_) { // Detect a spin loop. thread.spin_info.spinloop_count++; - double rate = std::min(1.0, - static_cast<double>(thread.spin_info.runtime_in_check_period) / time_period_in_ns); + double rate = std::min( + 1.0, static_cast<double>(thread.spin_info.runtime_in_check_period) / time_period_in_ns); if (rate > thread.spin_info.max_rate) { thread.spin_info.max_rate = rate; thread.spin_info.max_rate_start_timestamp = start_timestamp; @@ -378,12 +381,9 @@ void TraceSchedCommand::ReportProcessInfo(const std::vector<ProcessInfo>& proces displayer.AddDisplayFunction("Percentage", [](const ReportEntry* entry) { return StringPrintf("%.2f%%", entry->percentage); }); - displayer.AddDisplayFunction("Pid", [](const ReportEntry* entry) { - return StringPrintf("%d", entry->pid); - }); - displayer.AddDisplayFunction("Name", [](const ReportEntry* entry) { - return entry->name; - }); + displayer.AddDisplayFunction( + "Pid", [](const ReportEntry* entry) { return StringPrintf("%d", entry->pid); }); + displayer.AddDisplayFunction("Name", [](const ReportEntry* entry) { return entry->name; }); for (auto& entry : entries) { displayer.AdjustWidth(&entry); } @@ -396,17 +396,17 @@ void TraceSchedCommand::ReportProcessInfo(const std::vector<ProcessInfo>& proces for (auto& thread : process.threads) { if (thread->spin_info.spinloop_count != 0u) { double percentage = 100.0 * thread->spin_info.max_rate; - double duration_in_ns = thread->spin_info.max_rate_end_timestamp - - thread->spin_info.max_rate_start_timestamp; + double duration_in_ns = + thread->spin_info.max_rate_end_timestamp - thread->spin_info.max_rate_start_timestamp; double running_time_in_ns = duration_in_ns * thread->spin_info.max_rate; - printf("Detect %" PRIu64 " spin loops in process %s (%d) thread %s (%d),\n" + printf("Detect %" PRIu64 + " spin loops in process %s (%d) thread %s (%d),\n" "max rate at [%.6f s - %.6f s], taken %.3f ms / %.3f ms (%.2f%%).\n", thread->spin_info.spinloop_count, process.name.c_str(), process.process_id, thread->name.c_str(), thread->thread_id, thread->spin_info.max_rate_start_timestamp / 1e9, - thread->spin_info.max_rate_end_timestamp / 1e9, - running_time_in_ns / 1e6, duration_in_ns / 1e6, - percentage); + thread->spin_info.max_rate_end_timestamp / 1e9, running_time_in_ns / 1e6, + duration_in_ns / 1e6, percentage); } } } diff --git a/simpleperf/cmd_trace_sched_test.cpp b/simpleperf/cmd_trace_sched_test.cpp index b50e3a31..11ba3ba5 100644 --- a/simpleperf/cmd_trace_sched_test.cpp +++ b/simpleperf/cmd_trace_sched_test.cpp @@ -44,21 +44,20 @@ static std::unique_ptr<Command> TraceSchedCmd() { } TEST(trace_sched_cmd, smoke) { - TEST_IN_ROOT({ - ASSERT_TRUE(TraceSchedCmd()->Run({"--duration", "1"})); - }); + TEST_IN_ROOT({ ASSERT_TRUE(TraceSchedCmd()->Run({"--duration", "1"})); }); } TEST(trace_sched_cmd, report_smoke) { CaptureStdout capture; ASSERT_TRUE(capture.Start()); - ASSERT_TRUE(TraceSchedCmd()->Run({"--record-file", GetTestData(PERF_DATA_SCHED_STAT_RUNTIME), - "--show-threads"})); + ASSERT_TRUE(TraceSchedCmd()->Run( + {"--record-file", GetTestData(PERF_DATA_SCHED_STAT_RUNTIME), "--show-threads"})); std::string data = capture.Finish(); ASSERT_NE(data.find("Process 3845.961 ms 94.90% 8603 examplepurejava"), std::string::npos); ASSERT_NE(data.find("Thread 3845.961 ms 94.90% 8615 BusyThread"), std::string::npos); ASSERT_NE(data.find("Detect 3 spin loops in process examplepurejava (8603) thread " "BusyThread (8615),\nmax rate at [326962.439095 s - 326963.442418 s], " - "taken 997.813 ms / 1003.323 ms (99.45%)."), std::string::npos); + "taken 997.813 ms / 1003.323 ms (99.45%)."), + std::string::npos); } diff --git a/simpleperf/command.cpp b/simpleperf/command.cpp index c9bcd752..01e659d0 100644 --- a/simpleperf/command.cpp +++ b/simpleperf/command.cpp @@ -209,8 +209,8 @@ class CommandRegister { CommandRegister command_register; -static void StderrLogger(android::base::LogId, android::base::LogSeverity severity, - const char*, const char* file, unsigned int line, const char* message) { +static void StderrLogger(android::base::LogId, android::base::LogSeverity severity, const char*, + const char* file, unsigned int line, const char* message) { static const char log_characters[] = "VDIWEFF"; char severity_char = log_characters[severity]; fprintf(stderr, "simpleperf %c %s:%u] %s\n", severity_char, file, line, message); @@ -240,8 +240,8 @@ bool RunSimpleperfCmd(int argc, char** argv) { if (option_name == "-h" || option_name == "--help") { args.insert(args.begin(), "help"); } else if (option_name == "--log") { - if (!GetLogSeverity(argv[i+1], &log_severity)) { - LOG(ERROR) << "Unknown log severity: " << argv[i+1]; + if (!GetLogSeverity(argv[i + 1], &log_severity)) { + LOG(ERROR) << "Unknown log severity: " << argv[i + 1]; } ++i; #if defined(__ANDROID__) diff --git a/simpleperf/command.h b/simpleperf/command.h index 88c1c08c..d06c5154 100644 --- a/simpleperf/command.h +++ b/simpleperf/command.h @@ -35,9 +35,9 @@ namespace simpleperf { using OptionName = std::string; enum class OptionType { - SINGLE, // this option has a single value (use the last one in the arg list) + SINGLE, // this option has a single value (use the last one in the arg list) MULTIPLE, // this option can have multiple values (keep all values appeared in the arg list) - ORDERED, // keep the order of this option in the arg list + ORDERED, // keep the order of this option in the arg list }; enum class OptionValueType { @@ -73,9 +73,7 @@ union OptionValue { struct OptionValueMap { std::multimap<OptionName, OptionValue> values; - bool PullBoolValue(const OptionName& name) { - return PullValue(name).has_value(); - } + bool PullBoolValue(const OptionName& name) { return PullValue(name).has_value(); } template <typename T> bool PullUintValue(const OptionName& name, T* value, uint64_t min = 0, @@ -149,23 +147,15 @@ class Command { public: Command(const std::string& name, const std::string& short_help_string, const std::string& long_help_string) - : name_(name), short_help_string_(short_help_string), long_help_string_(long_help_string) { - } + : name_(name), short_help_string_(short_help_string), long_help_string_(long_help_string) {} - virtual ~Command() { - } + virtual ~Command() {} - const std::string& Name() const { - return name_; - } + const std::string& Name() const { return name_; } - const std::string& ShortHelpString() const { - return short_help_string_; - } + const std::string& ShortHelpString() const { return short_help_string_; } - const std::string LongHelpString() const { - return long_help_string_; - } + const std::string LongHelpString() const { return long_help_string_; } virtual bool Run(const std::vector<std::string>& args) = 0; diff --git a/simpleperf/command_test.cpp b/simpleperf/command_test.cpp index 216c864f..ce713669 100644 --- a/simpleperf/command_test.cpp +++ b/simpleperf/command_test.cpp @@ -22,12 +22,9 @@ using namespace simpleperf; class MockCommand : public Command { public: - MockCommand() : Command("mock", "mock_short_help", "mock_long_help") { - } + MockCommand() : Command("mock", "mock_short_help", "mock_long_help") {} - bool Run(const std::vector<std::string>&) override { - return true; - } + bool Run(const std::vector<std::string>&) override { return true; } }; TEST(command, CreateCommandInstance) { @@ -93,20 +90,11 @@ TEST(command, PreprocessOptions) { }; // Check options. - std::vector<std::string> args = {"--bool-option", - "--str-option", - "str1", - "--str-option", - "str1_2", - "--str2-option", - "str2_value", - "--opt-str-option", - "--opt-str-option", - "opt_str", - "--uint-option", - "34", - "--double-option", - "-32.75"}; + std::vector<std::string> args = { + "--bool-option", "--str-option", "str1", "--str-option", + "str1_2", "--str2-option", "str2_value", "--opt-str-option", + "--opt-str-option", "opt_str", "--uint-option", "34", + "--double-option", "-32.75"}; ASSERT_TRUE(cmd.PreprocessOptions(args, option_formats, &options, &ordered_options, nullptr)); ASSERT_TRUE(options.PullBoolValue("--bool-option")); auto values = options.PullValues("--str-option"); diff --git a/simpleperf/cpu_hotplug_test.cpp b/simpleperf/cpu_hotplug_test.cpp index c882d8f4..9b78c644 100644 --- a/simpleperf/cpu_hotplug_test.cpp +++ b/simpleperf/cpu_hotplug_test.cpp @@ -86,8 +86,7 @@ class ScopedMpdecisionKiller { #else class ScopedMpdecisionKiller { public: - ScopedMpdecisionKiller() { - } + ScopedMpdecisionKiller() {} }; #endif @@ -138,9 +137,10 @@ static bool SetCpuOnline(int cpu, bool online) { break; } LOG(ERROR) << "reading cpu retry count = " << retry_count << ", requested = " << online - << ", real = " << ret; + << ", real = " << ret; if (++retry_count == 10000) { - LOG(ERROR) << "setting cpu " << cpu << (online ? " online" : " offline") << " seems not to take effect"; + LOG(ERROR) << "setting cpu " << cpu << (online ? " online" : " offline") + << " seems not to take effect"; return false; } std::this_thread::sleep_for(std::chrono::milliseconds(1)); @@ -200,9 +200,7 @@ struct CpuToggleThreadArg { std::atomic<bool> end_flag; std::atomic<bool> cpu_hotplug_failed; - CpuToggleThreadArg(int cpu) - : toggle_cpu(cpu), end_flag(false), cpu_hotplug_failed(false) { - } + CpuToggleThreadArg(int cpu) : toggle_cpu(cpu), end_flag(false), cpu_hotplug_failed(false) {} }; static void CpuToggleThread(CpuToggleThreadArg* arg) { @@ -314,7 +312,6 @@ TEST(cpu_offline, offline_while_ioctl_enable) { GTEST_LOG_(INFO) << "Have Tested " << (diff.count() / 60.0) << " minutes."; } cur_time = std::chrono::steady_clock::now(); - } std::unique_ptr<EventFd> event_fd = EventFd::OpenEventFile(attr, -1, test_cpu, nullptr, event_type_modifier->name, false); @@ -327,7 +324,8 @@ TEST(cpu_offline, offline_while_ioctl_enable) { ASSERT_TRUE(event_fd->SetEnableEvent(true)); iterations++; if (verbose_mode) { - GTEST_LOG_(INFO) << "Test offline while ioctl(PERF_EVENT_IOC_ENABLE) for " << iterations << " times."; + GTEST_LOG_(INFO) << "Test offline while ioctl(PERF_EVENT_IOC_ENABLE) for " << iterations + << " times."; } } if (cpu_toggle_arg.cpu_hotplug_failed) { @@ -395,7 +393,7 @@ TEST(cpu_offline, offline_while_user_process_profiling) { auto diff = std::chrono::duration_cast<std::chrono::seconds>( std::chrono::steady_clock::now() - start_time); if (verbose_mode) { - GTEST_LOG_(INFO) << "Have Tested " << (diff.count() / 60.0) << " minutes."; + GTEST_LOG_(INFO) << "Have Tested " << (diff.count() / 60.0) << " minutes."; } cur_time = std::chrono::steady_clock::now(); } @@ -413,7 +411,8 @@ TEST(cpu_offline, offline_while_user_process_profiling) { std::this_thread::sleep_for(std::chrono::milliseconds(1)); iterations++; if (verbose_mode) { - GTEST_LOG_(INFO) << "Test offline while user process profiling for " << iterations << " times."; + GTEST_LOG_(INFO) << "Test offline while user process profiling for " << iterations + << " times."; } } if (cpu_toggle_arg.cpu_hotplug_failed) { @@ -471,11 +470,12 @@ int main(int argc, char** argv) { for (int i = 1; i < argc; ++i) { if (strcmp(argv[i], "--help") == 0) { printf("--long_test_duration <second> Set test duration for long tests. Default is 120s.\n"); - printf("--cpu_hotplug_interval <microseconds> Set cpu hotplug interval. Default is 1000us.\n"); + printf( + "--cpu_hotplug_interval <microseconds> Set cpu hotplug interval. Default is 1000us.\n"); printf("--verbose Show verbose log.\n"); } else if (strcmp(argv[i], "--long_test_duration") == 0) { if (i + 1 < argc) { - int second_count = atoi(argv[i+1]); + int second_count = atoi(argv[i + 1]); if (second_count <= 0) { fprintf(stderr, "Invalid arg for --long_test_duration.\n"); return 1; @@ -485,7 +485,7 @@ int main(int argc, char** argv) { } } else if (strcmp(argv[i], "--cpu_hotplug_interval") == 0) { if (i + 1 < argc) { - int microsecond_count = atoi(argv[i+1]); + int microsecond_count = atoi(argv[i + 1]); if (microsecond_count <= 0) { fprintf(stderr, "Invalid arg for --cpu_hotplug_interval\n"); return 1; diff --git a/simpleperf/demo/.clang-format b/simpleperf/demo/.clang-format new file mode 120000 index 00000000..81ff3c41 --- /dev/null +++ b/simpleperf/demo/.clang-format @@ -0,0 +1 @@ +../../.clang-format-none
\ No newline at end of file diff --git a/simpleperf/dso.cpp b/simpleperf/dso.cpp index a21d50a6..f962677d 100644 --- a/simpleperf/dso.cpp +++ b/simpleperf/dso.cpp @@ -29,8 +29,8 @@ #include <android-base/logging.h> #include <android-base/strings.h> -#include "environment.h" #include "JITDebugReader.h" +#include "environment.h" #include "read_apk.h" #include "read_dex_file.h" #include "read_elf.h" @@ -199,7 +199,7 @@ std::string DebugElfFileFinder::GetPathInSymFsDir(const std::string& path) { std::replace(elf_path.begin(), elf_path.end(), '/', OS_PATH_SEPARATOR); return add_symfs_prefix(elf_path); } -} // namespace simpleperf_dso_imp +} // namespace simpleperf_dso_impl static OneTimeFreeAllocator symbol_name_allocator; @@ -208,8 +208,7 @@ Symbol::Symbol(std::string_view name, uint64_t addr, uint64_t len) len(len), name_(symbol_name_allocator.AllocateString(name)), demangled_name_(nullptr), - dump_id_(UINT_MAX) { -} + dump_id_(UINT_MAX) {} const char* Symbol::DemangledName() const { if (demangled_name_ == nullptr) { @@ -232,10 +231,11 @@ size_t Dso::dso_count_; uint32_t Dso::g_dump_id_; simpleperf_dso_impl::DebugElfFileFinder Dso::debug_elf_file_finder_; -void Dso::SetDemangle(bool demangle) { demangle_ = demangle; } +void Dso::SetDemangle(bool demangle) { + demangle_ = demangle; +} -extern "C" char* __cxa_demangle(const char* mangled_name, char* buf, size_t* n, - int* status); +extern "C" char* __cxa_demangle(const char* mangled_name, char* buf, size_t* n, int* status); std::string Dso::Demangle(const std::string& name) { if (!demangle_) { @@ -270,14 +270,14 @@ bool Dso::AddSymbolDir(const std::string& symbol_dir) { return debug_elf_file_finder_.AddSymbolDir(symbol_dir); } -void Dso::SetVmlinux(const std::string& vmlinux) { vmlinux_ = vmlinux; } +void Dso::SetVmlinux(const std::string& vmlinux) { + vmlinux_ = vmlinux; +} -void Dso::SetBuildIds( - const std::vector<std::pair<std::string, BuildId>>& build_ids) { +void Dso::SetBuildIds(const std::vector<std::pair<std::string, BuildId>>& build_ids) { std::unordered_map<std::string, BuildId> map; for (auto& pair : build_ids) { - LOG(DEBUG) << "build_id_map: " << pair.first << ", " - << pair.second.ToString(); + LOG(DEBUG) << "build_id_map: " << pair.first << ", " << pair.second.ToString(); map.insert(pair); } build_id_map_ = std::move(map); @@ -345,8 +345,7 @@ const Symbol* Dso::FindSymbol(uint64_t vaddr_in_dso) { if (!is_loaded_) { Load(); } - auto it = std::upper_bound(symbols_.begin(), symbols_.end(), - Symbol("", vaddr_in_dso, 0), + auto it = std::upper_bound(symbols_.begin(), symbols_.end(), Symbol("", vaddr_in_dso, 0), Symbol::CompareValueByAddr); if (it != symbols_.begin()) { --it; @@ -401,8 +400,8 @@ void Dso::Load() { } } -static void ReportReadElfSymbolResult(ElfStatus result, const std::string& path, - const std::string& debug_file_path, +static void ReportReadElfSymbolResult( + ElfStatus result, const std::string& path, const std::string& debug_file_path, android::base::LogSeverity warning_loglevel = android::base::WARNING) { if (result == ElfStatus::NO_ERROR) { LOG(VERBOSE) << "Read symbols from " << debug_file_path << " successfully"; @@ -435,17 +434,14 @@ class DexFileDso : public Dso { : Dso(DSO_DEX_FILE, path, debug_file_path) {} void AddDexFileOffset(uint64_t dex_file_offset) override { - auto it = std::lower_bound(dex_file_offsets_.begin(), dex_file_offsets_.end(), - dex_file_offset); + auto it = std::lower_bound(dex_file_offsets_.begin(), dex_file_offsets_.end(), dex_file_offset); if (it != dex_file_offsets_.end() && *it == dex_file_offset) { return; } dex_file_offsets_.insert(it, dex_file_offset); } - const std::vector<uint64_t>* DexFileOffsets() override { - return &dex_file_offsets_; - } + const std::vector<uint64_t>* DexFileOffsets() override { return &dex_file_offsets_; } uint64_t IpToVaddrInFile(uint64_t ip, uint64_t map_start, uint64_t map_pgoff) override { return ip - map_start + map_pgoff; @@ -460,8 +456,8 @@ class DexFileDso : public Dso { std::unique_ptr<ArchiveHelper> ahelper = ArchiveHelper::CreateInstance(std::get<1>(tuple)); ZipEntry entry; std::vector<uint8_t> data; - if (ahelper && - ahelper->FindEntry(std::get<2>(tuple), &entry) && ahelper->GetEntryData(entry, &data)) { + if (ahelper && ahelper->FindEntry(std::get<2>(tuple), &entry) && + ahelper->GetEntryData(entry, &data)) { status = ReadSymbolsFromDexFileInMemory(data.data(), data.size(), dex_file_offsets_, &dex_file_symbols); } @@ -469,8 +465,8 @@ class DexFileDso : public Dso { status = ReadSymbolsFromDexFile(debug_file_path_, dex_file_offsets_, &dex_file_symbols); } if (!status) { - android::base::LogSeverity level = symbols_.empty() ? android::base::WARNING - : android::base::DEBUG; + android::base::LogSeverity level = + symbols_.empty() ? android::base::WARNING : android::base::DEBUG; LOG(level) << "Failed to read symbols from " << debug_file_path_; return symbols; } @@ -596,9 +592,7 @@ class KernelDso : public Dso { KernelDso(const std::string& path, const std::string& debug_file_path) : Dso(DSO_KERNEL, path, debug_file_path) {} - uint64_t IpToVaddrInFile(uint64_t ip, uint64_t, uint64_t) override { - return ip; - } + uint64_t IpToVaddrInFile(uint64_t ip, uint64_t, uint64_t) override { return ip; } protected: std::vector<Symbol> LoadSymbols() override { @@ -707,14 +701,10 @@ class UnknownDso : public Dso { public: UnknownDso(const std::string& path) : Dso(DSO_UNKNOWN_FILE, path, path) {} - uint64_t IpToVaddrInFile(uint64_t ip, uint64_t, uint64_t) override { - return ip; - } + uint64_t IpToVaddrInFile(uint64_t ip, uint64_t, uint64_t) override { return ip; } protected: - std::vector<Symbol> LoadSymbols() override { - return std::vector<Symbol>(); - } + std::vector<Symbol> LoadSymbols() override { return std::vector<Symbol>(); } }; std::unique_ptr<Dso> Dso::CreateDso(DsoType dso_type, const std::string& dso_path, @@ -722,8 +712,8 @@ std::unique_ptr<Dso> Dso::CreateDso(DsoType dso_type, const std::string& dso_pat switch (dso_type) { case DSO_ELF_FILE: { BuildId build_id = FindExpectedBuildIdForPath(dso_path); - return std::unique_ptr<Dso>(new ElfDso(dso_path, - debug_elf_file_finder_.FindDebugFile(dso_path, force_64bit, build_id))); + return std::unique_ptr<Dso>(new ElfDso( + dso_path, debug_elf_file_finder_.FindDebugFile(dso_path, force_64bit, build_id))); } case DSO_KERNEL: return std::unique_ptr<Dso>(new KernelDso(dso_path, dso_path)); diff --git a/simpleperf/dso.h b/simpleperf/dso.h index aa7ca048..84ac0210 100644 --- a/simpleperf/dso.h +++ b/simpleperf/dso.h @@ -29,7 +29,6 @@ #include "build_id.h" #include "read_elf.h" - namespace simpleperf_dso_impl { // Find elf files with symbol table and debug information. @@ -39,8 +38,7 @@ class DebugElfFileFinder { bool SetSymFsDir(const std::string& symfs_dir); bool AddSymbolDir(const std::string& symbol_dir); void SetVdsoFile(const std::string& vdso_file, bool is_64bit); - std::string FindDebugFile(const std::string& dso_path, bool force_64bit, - BuildId& build_id); + std::string FindDebugFile(const std::string& dso_path, bool force_64bit, BuildId& build_id); // Only for testing std::string GetPathInSymFsDir(const std::string& path); @@ -65,9 +63,7 @@ struct Symbol { const char* DemangledName() const; - bool HasDumpId() const { - return dump_id_ != UINT_MAX; - } + bool HasDumpId() const { return dump_id_ != UINT_MAX; } bool GetDumpId(uint32_t* pdump_id) const { if (!HasDumpId()) { @@ -85,13 +81,9 @@ struct Symbol { return id1 < id2; } - static bool CompareByAddr(const Symbol* s1, const Symbol* s2) { - return s1->addr < s2->addr; - } + static bool CompareByAddr(const Symbol* s1, const Symbol* s2) { return s1->addr < s2->addr; } - static bool CompareValueByAddr(const Symbol& s1, const Symbol& s2) { - return s1.addr < s2.addr; - } + static bool CompareValueByAddr(const Symbol& s1, const Symbol& s2) { return s1.addr < s2.addr; } private: const char* name_; @@ -130,11 +122,8 @@ class Dso { kallsyms_ = std::move(kallsyms); } } - static void ReadKernelSymbolsFromProc() { - read_kernel_symbols_from_proc_ = true; - } - static void SetBuildIds( - const std::vector<std::pair<std::string, BuildId>>& build_ids); + static void ReadKernelSymbolsFromProc() { read_kernel_symbols_from_proc_ = true; } + static void SetBuildIds(const std::vector<std::pair<std::string, BuildId>>& build_ids); static BuildId FindExpectedBuildIdForPath(const std::string& path); static void SetVdsoFile(const std::string& vdso_file, bool is_64bit); @@ -155,9 +144,7 @@ class Dso { // Return the file name without directory info. const std::string& FileName() const { return file_name_; } - bool HasDumpId() { - return dump_id_ != UINT_MAX; - } + bool HasDumpId() { return dump_id_ != UINT_MAX; } bool GetDumpId(uint32_t* pdump_id) { if (!HasDumpId()) { diff --git a/simpleperf/environment.cpp b/simpleperf/environment.cpp index b05fec8c..9f3fd3bc 100644 --- a/simpleperf/environment.cpp +++ b/simpleperf/environment.cpp @@ -32,8 +32,8 @@ #include <android-base/file.h> #include <android-base/logging.h> #include <android-base/parseint.h> -#include <android-base/strings.h> #include <android-base/stringprintf.h> +#include <android-base/strings.h> #include <procinfo/process.h> #include <procinfo/process_map.h> @@ -41,9 +41,9 @@ #include <android-base/properties.h> #endif +#include "IOEventLoop.h" #include "command.h" #include "event_type.h" -#include "IOEventLoop.h" #include "read_elf.h" #include "thread_tree.h" #include "utils.h" @@ -53,8 +53,7 @@ using namespace simpleperf; class LineReader { public: - explicit LineReader(FILE* fp) : fp_(fp), buf_(nullptr), bufsize_(0) { - } + explicit LineReader(FILE* fp) : fp_(fp), buf_(nullptr), bufsize_(0) {} ~LineReader() { free(buf_); @@ -68,9 +67,7 @@ class LineReader { return nullptr; } - size_t MaxLineSize() { - return bufsize_; - } + size_t MaxLineSize() { return bufsize_; } private: FILE* fp_; @@ -238,11 +235,10 @@ std::vector<pid_t> GetAllProcesses() { bool GetThreadMmapsInProcess(pid_t pid, std::vector<ThreadMmap>* thread_mmaps) { thread_mmaps->clear(); - return android::procinfo::ReadProcessMaps( - pid, [&](uint64_t start, uint64_t end, uint16_t flags, uint64_t pgoff, - ino_t, const char* name) { - thread_mmaps->emplace_back(start, end - start, pgoff, name, flags); - }); + return android::procinfo::ReadProcessMaps(pid, [&](uint64_t start, uint64_t end, uint16_t flags, + uint64_t pgoff, ino_t, const char* name) { + thread_mmaps->emplace_back(start, end - start, pgoff, name, flags); + }); } bool GetKernelBuildId(BuildId* build_id) { @@ -300,12 +296,18 @@ bool CanRecordRawData() { static const char* GetLimitLevelDescription(int limit_level) { switch (limit_level) { - case -1: return "unlimited"; - case 0: return "disallowing raw tracepoint access for unpriv"; - case 1: return "disallowing cpu events for unpriv"; - case 2: return "disallowing kernel profiling for unpriv"; - case 3: return "disallowing user profiling for unpriv"; - default: return "unknown level"; + case -1: + return "unlimited"; + case 0: + return "disallowing raw tracepoint access for unpriv"; + case 1: + return "disallowing cpu events for unpriv"; + case 2: + return "disallowing kernel profiling for unpriv"; + case 3: + return "disallowing user profiling for unpriv"; + default: + return "unknown level"; } } @@ -350,8 +352,8 @@ bool CheckPerfEventLimit() { return false; #else if (can_read_allow_file) { - LOG(WARNING) << perf_event_allow_path << " is " << limit_level - << ", " << GetLimitLevelDescription(limit_level) << "."; + LOG(WARNING) << perf_event_allow_path << " is " << limit_level << ", " + << GetLimitLevelDescription(limit_level) << "."; return false; } #endif @@ -482,8 +484,8 @@ bool CheckKernelSymbolAddresses() { return true; } LOG(WARNING) << "Access to kernel symbol addresses is restricted. If " - << "possible, please do `echo 0 >/proc/sys/kernel/kptr_restrict` " - << "to fix this."; + << "possible, please do `echo 0 >/proc/sys/kernel/kptr_restrict` " + << "to fix this."; return false; } @@ -612,6 +614,7 @@ class InAppRunner { bool RunCmdInApp(const std::string& cmd, const std::vector<std::string>& args, size_t workload_args_size, const std::string& output_filepath, bool need_tracepoint_events); + protected: virtual std::vector<std::string> GetPrefixArgs(const std::string& cmd) = 0; @@ -699,8 +702,10 @@ bool InAppRunner::RunCmdInApp(const std::string& cmd, const std::vector<std::str if (!SignalIsIgnored(SIGHUP)) { stop_signals.push_back(SIGHUP); } - if (!loop.AddSignalEvents(stop_signals, - [&]() { need_to_stop_child = true; return loop.ExitLoop(); })) { + if (!loop.AddSignalEvents(stop_signals, [&]() { + need_to_stop_child = true; + return loop.ExitLoop(); + })) { return false; } if (!loop.AddSignalEvent(SIGCHLD, [&]() { return loop.ExitLoop(); })) { @@ -778,9 +783,7 @@ class SimpleperfAppRunner : public InAppRunner { public: SimpleperfAppRunner(int user_id, const std::string& package_name) : InAppRunner(user_id, package_name) {} - bool Prepare() override { - return GetAndroidVersion() >= kAndroidVersionP + 1; - } + bool Prepare() override { return GetAndroidVersion() >= kAndroidVersionP + 1; } protected: std::vector<std::string> GetPrefixArgs(const std::string& cmd) { @@ -936,11 +939,9 @@ bool MappedFileOnlyExistInMemory(const char* filename) { // /dev/* // //anon: generated by kernel/events/core.c. // /memfd: created by memfd_create. - return filename[0] == '\0' || - (filename[0] == '[' && strcmp(filename, "[vdso]") != 0) || - strncmp(filename, "//", 2) == 0 || - strncmp(filename, "/dev/", 5) == 0 || - strncmp(filename, "/memfd:", 7) == 0; + return filename[0] == '\0' || (filename[0] == '[' && strcmp(filename, "[vdso]") != 0) || + strncmp(filename, "//", 2) == 0 || strncmp(filename, "/dev/", 5) == 0 || + strncmp(filename, "/memfd:", 7) == 0; } std::string GetCompleteProcessName(pid_t pid) { diff --git a/simpleperf/environment_test.cpp b/simpleperf/environment_test.cpp index 076293e7..8188ddb4 100644 --- a/simpleperf/environment_test.cpp +++ b/simpleperf/environment_test.cpp @@ -36,14 +36,15 @@ TEST(environment, PrepareVdsoFile) { TemporaryDir tmpdir; ScopedTempFiles scoped_temp_files(tmpdir.path); PrepareVdsoFile(); - std::unique_ptr<Dso> dso = Dso::CreateDso(DSO_ELF_FILE, "[vdso]", - sizeof(size_t) == sizeof(uint64_t)); + std::unique_ptr<Dso> dso = + Dso::CreateDso(DSO_ELF_FILE, "[vdso]", sizeof(size_t) == sizeof(uint64_t)); ASSERT_TRUE(dso != nullptr); ASSERT_NE(dso->GetDebugFilePath(), "[vdso]"); } TEST(environment, GetHardwareFromCpuInfo) { - std::string cpu_info = "CPU revision : 10\n\n" + std::string cpu_info = + "CPU revision : 10\n\n" "Hardware : Symbol i.MX6 Freeport_Plat Quad/DualLite (Device Tree)\n"; ASSERT_EQ("Symbol i.MX6 Freeport_Plat Quad/DualLite (Device Tree)", GetHardwareFromCpuInfo(cpu_info)); diff --git a/simpleperf/event_attr.cpp b/simpleperf/event_attr.cpp index 7458716e..21f3c19e 100644 --- a/simpleperf/event_attr.cpp +++ b/simpleperf/event_attr.cpp @@ -89,7 +89,7 @@ perf_event_attr CreateDefaultPerfEventAttr(const EventType& event_type) { attr.read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_TOTAL_TIME_RUNNING | PERF_FORMAT_ID; attr.sample_type |= PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_TIME | PERF_SAMPLE_PERIOD | - PERF_SAMPLE_CPU | PERF_SAMPLE_ID; + PERF_SAMPLE_CPU | PERF_SAMPLE_ID; if (attr.type == PERF_TYPE_TRACEPOINT) { // Tracepoint information are stored in raw data in sample records. @@ -144,8 +144,8 @@ void DumpPerfEventAttr(const perf_event_attr& attr, size_t indent) { } bool GetCommonEventIdPositionsForAttrs(std::vector<perf_event_attr>& attrs, - size_t* event_id_pos_in_sample_records, - size_t* event_id_reverse_pos_in_non_sample_records) { + size_t* event_id_pos_in_sample_records, + size_t* event_id_reverse_pos_in_non_sample_records) { // When there are more than one perf_event_attrs, we need to read event id // in each record to decide current record should use which attr. So // we need to determine the event id position in a record here. @@ -160,7 +160,7 @@ bool GetCommonEventIdPositionsForAttrs(std::vector<perf_event_attr>& attrs, bool identifier_enabled = true; bool id_enabled = true; uint64_t flags_before_id_mask = PERF_SAMPLE_IDENTIFIER | PERF_SAMPLE_IP | PERF_SAMPLE_TID | - PERF_SAMPLE_TIME | PERF_SAMPLE_ADDR; + PERF_SAMPLE_TIME | PERF_SAMPLE_ADDR; uint64_t flags_before_id = sample_types[0] & flags_before_id_mask; bool flags_before_id_are_the_same = true; for (auto type : sample_types) { @@ -216,7 +216,8 @@ bool GetCommonEventIdPositionsForAttrs(std::vector<perf_event_attr>& attrs, } *event_id_reverse_pos_in_non_sample_records = pos; } else { - LOG(ERROR) << "perf_event_attrs don't have a common event id reverse position in non sample records"; + LOG(ERROR) + << "perf_event_attrs don't have a common event id reverse position in non sample records"; return false; } return true; diff --git a/simpleperf/event_fd.cpp b/simpleperf/event_fd.cpp index 0010af9d..d3eb1f6b 100644 --- a/simpleperf/event_fd.cpp +++ b/simpleperf/event_fd.cpp @@ -16,6 +16,7 @@ #define ATRACE_TAG ATRACE_TAG_ALWAYS #include "event_fd.h" +#include <cutils/trace.h> #include <fcntl.h> #include <stdio.h> #include <string.h> @@ -23,10 +24,9 @@ #include <sys/mman.h> #include <sys/syscall.h> #include <sys/types.h> +#include <utils/Trace.h> #include <atomic> #include <memory> -#include <cutils/trace.h> -#include <utils/Trace.h> #include <android-base/file.h> #include <android-base/logging.h> @@ -38,8 +38,8 @@ #include "perf_event.h" #include "utils.h" -static int perf_event_open(const perf_event_attr& attr, pid_t pid, int cpu, - int group_fd, unsigned long flags) { // NOLINT +static int perf_event_open(const perf_event_attr& attr, pid_t pid, int cpu, int group_fd, + unsigned long flags) { // NOLINT return syscall(__NR_perf_event_open, &attr, pid, cpu, group_fd, flags); } @@ -65,30 +65,25 @@ std::unique_ptr<EventFd> EventFd::OpenEventFile(const perf_event_attr& attr, pid int perf_event_fd = perf_event_open(real_attr, tid, cpu, group_fd, 0); if (perf_event_fd == -1) { if (report_error) { - PLOG(ERROR) << "open perf_event_file (event " << event_name << ", tid " - << tid << ", cpu " << cpu << ", group_fd " << group_fd - << ") failed"; + PLOG(ERROR) << "open perf_event_file (event " << event_name << ", tid " << tid << ", cpu " + << cpu << ", group_fd " << group_fd << ") failed"; } else { - PLOG(DEBUG) << "open perf_event_file (event " << event_name << ", tid " - << tid << ", cpu " << cpu << ", group_fd " << group_fd - << ") failed"; + PLOG(DEBUG) << "open perf_event_file (event " << event_name << ", tid " << tid << ", cpu " + << cpu << ", group_fd " << group_fd << ") failed"; } return nullptr; } if (fcntl(perf_event_fd, F_SETFD, FD_CLOEXEC) == -1) { if (report_error) { - PLOG(ERROR) << "fcntl(FD_CLOEXEC) for perf_event_file (event " - << event_name << ", tid " << tid << ", cpu " << cpu - << ", group_fd " << group_fd << ") failed"; + PLOG(ERROR) << "fcntl(FD_CLOEXEC) for perf_event_file (event " << event_name << ", tid " + << tid << ", cpu " << cpu << ", group_fd " << group_fd << ") failed"; } else { - PLOG(DEBUG) << "fcntl(FD_CLOEXEC) for perf_event_file (event " - << event_name << ", tid " << tid << ", cpu " << cpu - << ", group_fd " << group_fd << ") failed"; + PLOG(DEBUG) << "fcntl(FD_CLOEXEC) for perf_event_file (event " << event_name << ", tid " + << tid << ", cpu " << cpu << ", group_fd " << group_fd << ") failed"; } return nullptr; } - return std::unique_ptr<EventFd>( - new EventFd(real_attr, perf_event_fd, event_name, tid, cpu)); + return std::unique_ptr<EventFd>(new EventFd(real_attr, perf_event_fd, event_name, tid, cpu)); } EventFd::~EventFd() { @@ -98,9 +93,8 @@ EventFd::~EventFd() { } std::string EventFd::Name() const { - return android::base::StringPrintf( - "perf_event_file(event %s, tid %d, cpu %d)", event_name_.c_str(), tid_, - cpu_); + return android::base::StringPrintf("perf_event_file(event %s, tid %d, cpu %d)", + event_name_.c_str(), tid_, cpu_); } uint64_t EventFd::Id() const { @@ -145,13 +139,12 @@ bool EventFd::ReadCounter(PerfCounter* counter) { } // Trace is always available to systrace if enabled if (tid_ > 0) { - ATRACE_INT64(android::base::StringPrintf( - "%s_tid%d_cpu%d", event_name_.c_str(), tid_, - cpu_).c_str(), counter->value - last_counter_value_); + ATRACE_INT64( + android::base::StringPrintf("%s_tid%d_cpu%d", event_name_.c_str(), tid_, cpu_).c_str(), + counter->value - last_counter_value_); } else { - ATRACE_INT64(android::base::StringPrintf( - "%s_cpu%d", event_name_.c_str(), - cpu_).c_str(), counter->value - last_counter_value_); + ATRACE_INT64(android::base::StringPrintf("%s_cpu%d", event_name_.c_str(), cpu_).c_str(), + counter->value - last_counter_value_); } last_counter_value_ = counter->value; return true; @@ -161,8 +154,7 @@ bool EventFd::CreateMappedBuffer(size_t mmap_pages, bool report_error) { CHECK(IsPowerOfTwo(mmap_pages)); size_t page_size = sysconf(_SC_PAGE_SIZE); size_t mmap_len = (mmap_pages + 1) * page_size; - void* mmap_addr = mmap(nullptr, mmap_len, PROT_READ | PROT_WRITE, MAP_SHARED, - perf_event_fd_, 0); + void* mmap_addr = mmap(nullptr, mmap_len, PROT_READ | PROT_WRITE, MAP_SHARED, perf_event_fd_, 0); if (mmap_addr == MAP_FAILED) { bool is_perm_error = (errno == EPERM); if (report_error) { @@ -171,9 +163,8 @@ bool EventFd::CreateMappedBuffer(size_t mmap_pages, bool report_error) { PLOG(DEBUG) << "mmap(" << mmap_pages << ") failed for " << Name(); } if (report_error && is_perm_error) { - LOG(ERROR) - << "It seems the kernel doesn't allow allocating enough " - << "buffer for dumping samples, consider decreasing mmap pages(-m)."; + LOG(ERROR) << "It seems the kernel doesn't allow allocating enough " + << "buffer for dumping samples, consider decreasing mmap pages(-m)."; } return false; } @@ -188,12 +179,11 @@ bool EventFd::CreateMappedBuffer(size_t mmap_pages, bool report_error) { bool EventFd::ShareMappedBuffer(const EventFd& event_fd, bool report_error) { CHECK(!HasMappedBuffer()); CHECK(event_fd.HasMappedBuffer()); - int result = - ioctl(perf_event_fd_, PERF_EVENT_IOC_SET_OUTPUT, event_fd.perf_event_fd_); + int result = ioctl(perf_event_fd_, PERF_EVENT_IOC_SET_OUTPUT, event_fd.perf_event_fd_); if (result != 0) { if (report_error) { - PLOG(ERROR) << "failed to share mapped buffer of " - << event_fd.perf_event_fd_ << " with " << perf_event_fd_; + PLOG(ERROR) << "failed to share mapped buffer of " << event_fd.perf_event_fd_ << " with " + << perf_event_fd_; } return false; } @@ -320,13 +310,14 @@ void EventFd::DiscardAuxData(size_t discard_size) { mmap_metadata_page_->aux_tail += discard_size; } -bool EventFd::StartPolling(IOEventLoop& loop, - const std::function<bool()>& callback) { +bool EventFd::StartPolling(IOEventLoop& loop, const std::function<bool()>& callback) { ioevent_ref_ = loop.AddReadEvent(perf_event_fd_, callback); return ioevent_ref_ != nullptr; } -bool EventFd::StopPolling() { return IOEventLoop::DelEvent(ioevent_ref_); } +bool EventFd::StopPolling() { + return IOEventLoop::DelEvent(ioevent_ref_); +} bool IsEventAttrSupported(const perf_event_attr& attr, const std::string& event_name) { return EventFd::OpenEventFile(attr, getpid(), -1, nullptr, event_name, false) != nullptr; diff --git a/simpleperf/event_fd.h b/simpleperf/event_fd.h index d687054f..2112978f 100644 --- a/simpleperf/event_fd.h +++ b/simpleperf/event_fd.h @@ -29,7 +29,7 @@ #include "perf_event.h" struct PerfCounter { - uint64_t value; // The value of the event specified by the perf_event_file. + uint64_t value; // The value of the event specified by the perf_event_file. uint64_t time_enabled; // The enabled time. uint64_t time_running; // The running time. uint64_t id; // The id of the perf_event_file. @@ -107,8 +107,8 @@ class EventFd { virtual bool StopPolling(); protected: - EventFd(const perf_event_attr& attr, int perf_event_fd, - const std::string& event_name, pid_t tid, int cpu) + EventFd(const perf_event_attr& attr, int perf_event_fd, const std::string& event_name, pid_t tid, + int cpu) : attr_(attr), perf_event_fd_(perf_event_fd), id_(0), diff --git a/simpleperf/event_selection_set.cpp b/simpleperf/event_selection_set.cpp index bdca76ef..ae9549c9 100644 --- a/simpleperf/event_selection_set.cpp +++ b/simpleperf/event_selection_set.cpp @@ -21,18 +21,18 @@ #include <thread> #include <android-base/logging.h> -#include <android-base/strings.h> #include <android-base/stringprintf.h> +#include <android-base/strings.h> -#include "environment.h" #include "ETMRecorder.h" +#include "IOEventLoop.h" +#include "RecordReadThread.h" +#include "environment.h" #include "event_attr.h" #include "event_type.h" -#include "IOEventLoop.h" #include "perf_regs.h" #include "tracing.h" #include "utils.h" -#include "RecordReadThread.h" using android::base::StringPrintf; @@ -55,8 +55,7 @@ bool IsDwarfCallChainSamplingSupported() { return false; } perf_event_attr attr = CreateDefaultPerfEventAttr(*type); - attr.sample_type |= - PERF_SAMPLE_CALLCHAIN | PERF_SAMPLE_REGS_USER | PERF_SAMPLE_STACK_USER; + attr.sample_type |= PERF_SAMPLE_CALLCHAIN | PERF_SAMPLE_REGS_USER | PERF_SAMPLE_STACK_USER; attr.exclude_callchain_user = 1; attr.sample_regs_user = GetSupportedRegMask(GetBuildArch()); attr.sample_stack_user = 8192; @@ -165,11 +164,9 @@ bool EventSelectionSet::BuildAndCheckEventSelection(const std::string& event_nam return false; } if (for_stat_cmd_) { - if (event_type->event_type.name == "cpu-clock" || - event_type->event_type.name == "task-clock") { + if (event_type->event_type.name == "cpu-clock" || event_type->event_type.name == "task-clock") { if (event_type->exclude_user || event_type->exclude_kernel) { - LOG(ERROR) << "Modifier u and modifier k used in event type " - << event_type->event_type.name + LOG(ERROR) << "Modifier u and modifier k used in event type " << event_type->event_type.name << " are not supported by the kernel."; return false; } @@ -221,8 +218,7 @@ bool EventSelectionSet::BuildAndCheckEventSelection(const std::string& event_nam // PMU events are provided by kernel, so they should be supported if (!event_type->event_type.IsPmuEvent() && !IsEventAttrSupported(selection->event_attr, selection->event_type_modifier.name)) { - LOG(ERROR) << "Event type '" << event_type->name - << "' is not supported on the device"; + LOG(ERROR) << "Event type '" << event_type->name << "' is not supported on the device"; return false; } if (set_default_sample_freq) { @@ -234,8 +230,7 @@ bool EventSelectionSet::BuildAndCheckEventSelection(const std::string& event_nam for (const auto& group : groups_) { for (const auto& sel : group) { if (sel.event_type_modifier.name == selection->event_type_modifier.name) { - LOG(ERROR) << "Event type '" << sel.event_type_modifier.name - << "' appears more than once"; + LOG(ERROR) << "Event type '" << sel.event_type_modifier.name << "' appears more than once"; return false; } } @@ -247,8 +242,8 @@ bool EventSelectionSet::AddEventType(const std::string& event_name, size_t* grou return AddEventGroup(std::vector<std::string>(1, event_name), group_id); } -bool EventSelectionSet::AddEventGroup( - const std::vector<std::string>& event_names, size_t* group_id) { +bool EventSelectionSet::AddEventGroup(const std::vector<std::string>& event_names, + size_t* group_id) { EventSelectionGroup group; bool first_event = groups_.empty(); bool first_in_group = true; @@ -292,8 +287,7 @@ std::vector<const EventType*> EventSelectionSet::GetTracepointEvents() const { std::vector<const EventType*> result; for (const auto& group : groups_) { for (const auto& selection : group) { - if (selection.event_type_modifier.event_type.type == - PERF_TYPE_TRACEPOINT) { + if (selection.event_type_modifier.event_type.type == PERF_TYPE_TRACEPOINT) { result.push_back(&selection.event_type_modifier.event_type); } } @@ -396,11 +390,9 @@ void EventSelectionSet::SetSampleSpeed(size_t group_id, const SampleSpeed& speed bool EventSelectionSet::SetBranchSampling(uint64_t branch_sample_type) { if (branch_sample_type != 0 && - (branch_sample_type & - (PERF_SAMPLE_BRANCH_ANY | PERF_SAMPLE_BRANCH_ANY_CALL | - PERF_SAMPLE_BRANCH_ANY_RETURN | PERF_SAMPLE_BRANCH_IND_CALL)) == 0) { - LOG(ERROR) << "Invalid branch_sample_type: 0x" << std::hex - << branch_sample_type; + (branch_sample_type & (PERF_SAMPLE_BRANCH_ANY | PERF_SAMPLE_BRANCH_ANY_CALL | + PERF_SAMPLE_BRANCH_ANY_RETURN | PERF_SAMPLE_BRANCH_IND_CALL)) == 0) { + LOG(ERROR) << "Invalid branch_sample_type: 0x" << std::hex << branch_sample_type; return false; } if (branch_sample_type != 0 && !IsBranchSamplingSupported()) { @@ -436,12 +428,10 @@ bool EventSelectionSet::EnableDwarfCallChainSampling(uint32_t dump_stack_size) { } for (auto& group : groups_) { for (auto& selection : group) { - selection.event_attr.sample_type |= PERF_SAMPLE_CALLCHAIN | - PERF_SAMPLE_REGS_USER | - PERF_SAMPLE_STACK_USER; + selection.event_attr.sample_type |= + PERF_SAMPLE_CALLCHAIN | PERF_SAMPLE_REGS_USER | PERF_SAMPLE_STACK_USER; selection.event_attr.exclude_callchain_user = 1; - selection.event_attr.sample_regs_user = - GetSupportedRegMask(GetMachineArch()); + selection.event_attr.sample_regs_user = GetSupportedRegMask(GetMachineArch()); selection.event_attr.sample_stack_user = dump_stack_size; } } @@ -541,8 +531,7 @@ bool EventSelectionSet::SetTracepointFilter(const std::string& filter) { static bool CheckIfCpusOnline(const std::vector<int>& cpus) { std::vector<int> online_cpus = GetOnlineCpus(); for (const auto& cpu : cpus) { - if (std::find(online_cpus.begin(), online_cpus.end(), cpu) == - online_cpus.end()) { + if (std::find(online_cpus.begin(), online_cpus.end(), cpu) == online_cpus.end()) { LOG(ERROR) << "cpu " << cpu << " is not online."; return false; } @@ -550,8 +539,7 @@ static bool CheckIfCpusOnline(const std::vector<int>& cpus) { return true; } -bool EventSelectionSet::OpenEventFilesOnGroup(EventSelectionGroup& group, - pid_t tid, int cpu, +bool EventSelectionSet::OpenEventFilesOnGroup(EventSelectionGroup& group, pid_t tid, int cpu, std::string* failed_event_type) { std::vector<std::unique_ptr<EventFd>> event_fds; // Given a tid and cpu, events on the same group should be all opened @@ -561,8 +549,8 @@ bool EventSelectionSet::OpenEventFilesOnGroup(EventSelectionGroup& group, std::unique_ptr<EventFd> event_fd = EventFd::OpenEventFile( selection.event_attr, tid, cpu, group_fd, selection.event_type_modifier.name, false); if (!event_fd) { - *failed_event_type = selection.event_type_modifier.name; - return false; + *failed_event_type = selection.event_type_modifier.name; + return false; } LOG(VERBOSE) << "OpenEventFile for " << event_fd->Name(); event_fds.push_back(std::move(event_fd)); @@ -729,10 +717,9 @@ bool EventSelectionSet::ReadCounters(std::vector<CountersInfo>* counters) { bool EventSelectionSet::MmapEventFiles(size_t min_mmap_pages, size_t max_mmap_pages, size_t aux_buffer_size, size_t record_buffer_size, bool allow_cutting_samples, bool exclude_perf) { - record_read_thread_.reset( - new simpleperf::RecordReadThread(record_buffer_size, groups_[0][0].event_attr, min_mmap_pages, - max_mmap_pages, aux_buffer_size, allow_cutting_samples, - exclude_perf)); + record_read_thread_.reset(new simpleperf::RecordReadThread( + record_buffer_size, groups_[0][0].event_attr, min_mmap_pages, max_mmap_pages, aux_buffer_size, + allow_cutting_samples, exclude_perf)); return true; } diff --git a/simpleperf/event_selection_set.h b/simpleperf/event_selection_set.h index 717c51d5..8366ef43 100644 --- a/simpleperf/event_selection_set.h +++ b/simpleperf/event_selection_set.h @@ -25,13 +25,13 @@ #include <android-base/macros.h> +#include "IOEventLoop.h" +#include "RecordReadThread.h" #include "event_attr.h" #include "event_fd.h" #include "event_type.h" -#include "IOEventLoop.h" #include "perf_event.h" #include "record.h" -#include "RecordReadThread.h" namespace simpleperf { @@ -127,9 +127,7 @@ class EventSelectionSet { bool NeedKernelSymbol() const; void SetRecordNotExecutableMaps(bool record); bool RecordNotExecutableMaps() const; - void SetAddrFilters(std::vector<AddrFilter>&& filters) { - addr_filters_ = std::move(filters); - } + void SetAddrFilters(std::vector<AddrFilter>&& filters) { addr_filters_ = std::move(filters); } bool SetTracepointFilter(const std::string& filter); template <typename Collection = std::vector<pid_t>> @@ -151,13 +149,9 @@ class EventSelectionSet { threads_.clear(); } - bool HasMonitoredTarget() const { - return !processes_.empty() || !threads_.empty(); - } + bool HasMonitoredTarget() const { return !processes_.empty() || !threads_.empty(); } - IOEventLoop* GetIOEventLoop() { - return loop_.get(); - } + IOEventLoop* GetIOEventLoop() { return loop_.get(); } // If cpus = {}, monitor on all cpus, with a perf event file for each cpu. // If cpus = {-1}, monitor on all cpus, with a perf event file shared by all cpus. @@ -171,13 +165,11 @@ class EventSelectionSet { bool FinishReadMmapEventData(); void CloseEventFiles(); - const simpleperf::RecordStat& GetRecordStat() { - return record_read_thread_->GetStat(); - } + const simpleperf::RecordStat& GetRecordStat() { return record_read_thread_->GetStat(); } // Stop profiling if all monitored processes/threads don't exist. - bool StopWhenNoMoreTargets(double check_interval_in_sec = - DEFAULT_PERIOD_TO_CHECK_MONITORED_TARGETS_IN_SEC); + bool StopWhenNoMoreTargets( + double check_interval_in_sec = DEFAULT_PERIOD_TO_CHECK_MONITORED_TARGETS_IN_SEC); bool SetEnableEvents(bool enable); diff --git a/simpleperf/event_type.cpp b/simpleperf/event_type.cpp index 2472d619..135e69da 100644 --- a/simpleperf/event_type.cpp +++ b/simpleperf/event_type.cpp @@ -28,8 +28,8 @@ #include <android-base/stringprintf.h> #include <android-base/strings.h> -#include "environment.h" #include "ETMRecorder.h" +#include "environment.h" #include "event_attr.h" #include "utils.h" @@ -37,8 +37,7 @@ namespace simpleperf { struct EventFormat { EventFormat(const std::string& name, const std::string& attr, int shift) - : name(name), attr(attr), shift(shift) { - } + : name(name), attr(attr), shift(shift) {} std::string name; std::string attr; @@ -46,7 +45,7 @@ struct EventFormat { }; #define EVENT_TYPE_TABLE_ENTRY(name, type, config, description, limited_arch) \ - {name, type, config, description, limited_arch}, + {name, type, config, description, limited_arch}, static const std::set<EventType> builtin_event_types = { #include "event_type_table.h" @@ -148,9 +147,7 @@ class TracepointSystemFinder : public EventTypeFinder { return &*res.first; } - void RemoveType(const std::string& name) { - types_.erase(EventType(name, 0, 0, "", "")); - } + void RemoveType(const std::string& name) { types_.erase(EventType(name, 0, 0, "", "")); } std::string ToString() { std::string result; @@ -397,7 +394,7 @@ bool EventTypeManager::WriteTracepointsToFile(const std::string& filepath) { return true; } -bool EventTypeManager::ForEachType(const std::function<bool (const EventType&)>& callback) { +bool EventTypeManager::ForEachType(const std::function<bool(const EventType&)>& callback) { if (scoped_finder_) { for (const auto& type : scoped_finder_->GetTypes()) { if (!callback(type)) { @@ -452,8 +449,7 @@ void EventTypeManager::SetScopedFinder(std::unique_ptr<EventTypeFinder>&& finder std::vector<int> EventType::GetPmuCpumask() { std::vector<int> empty_result; - if (!IsPmuEvent()) - return empty_result; + if (!IsPmuEvent()) return empty_result; std::string pmu = name.substr(0, name.find('/')); std::string cpumask_path = "/sys/bus/event_source/devices/" + pmu + "/cpumask"; @@ -474,8 +470,8 @@ std::string ScopedEventTypes::BuildString(const std::vector<const EventType*>& e if (!result.empty()) { result.push_back('\n'); } - result += android::base::StringPrintf("%s,%u,%" PRIu64, type->name.c_str(), type->type, - type->config); + result += + android::base::StringPrintf("%s,%u,%" PRIu64, type->name.c_str(), type->type, type->config); } return result; } diff --git a/simpleperf/event_type.h b/simpleperf/event_type.h index 933b1c32..d2cd0c15 100644 --- a/simpleperf/event_type.h +++ b/simpleperf/event_type.h @@ -34,25 +34,22 @@ inline const std::string kETMEventName = "cs-etm"; // the event type is supported by the kernel. struct EventType { - EventType(const std::string& name, uint32_t type, uint64_t config, - const std::string& description, const std::string& limited_arch) - : name(name), type(type), config(config), description(description), - limited_arch(limited_arch) { - } + EventType(const std::string& name, uint32_t type, uint64_t config, const std::string& description, + const std::string& limited_arch) + : name(name), + type(type), + config(config), + description(description), + limited_arch(limited_arch) {} - EventType() : type(0), config(0) { - } + EventType() : type(0), config(0) {} bool operator<(const EventType& other) const { return strcasecmp(name.c_str(), other.name.c_str()) < 0; } - bool IsPmuEvent() const { - return name.find('/') != std::string::npos; - } - bool IsEtmEvent() const { - return name == kETMEventName; - } + bool IsPmuEvent() const { return name.find('/') != std::string::npos; } + bool IsEtmEvent() const { return name == kETMEventName; } std::vector<int> GetPmuCpumask(); @@ -89,8 +86,7 @@ struct EventTypeAndModifier { exclude_hv(false), exclude_host(false), exclude_guest(false), - precise_ip(0) { - } + precise_ip(0) {} }; enum class EventFinderType; @@ -107,7 +103,7 @@ class EventTypeManager { bool WriteTracepointsToFile(const std::string& filepath); // Iterate through all event types, and stop when callback returns false. - bool ForEachType(const std::function<bool (const EventType&)>& callback); + bool ForEachType(const std::function<bool(const EventType&)>& callback); const EventType* FindType(const std::string& name); const EventType* AddRawType(const std::string& name); void RemoveProbeType(const std::string& name); diff --git a/simpleperf/event_type_table.h b/simpleperf/event_type_table.h index d2335adc..d209f0b7 100644 --- a/simpleperf/event_type_table.h +++ b/simpleperf/event_type_table.h @@ -2,216 +2,495 @@ EVENT_TYPE_TABLE_ENTRY("cpu-cycles", PERF_TYPE_HARDWARE, PERF_COUNT_HW_CPU_CYCLES, "", "") EVENT_TYPE_TABLE_ENTRY("instructions", PERF_TYPE_HARDWARE, PERF_COUNT_HW_INSTRUCTIONS, "", "") -EVENT_TYPE_TABLE_ENTRY("cache-references", PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_REFERENCES, "", "") +EVENT_TYPE_TABLE_ENTRY("cache-references", PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_REFERENCES, "", + "") EVENT_TYPE_TABLE_ENTRY("cache-misses", PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_MISSES, "", "") -EVENT_TYPE_TABLE_ENTRY("branch-instructions", PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_INSTRUCTIONS, "", "") +EVENT_TYPE_TABLE_ENTRY("branch-instructions", PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_INSTRUCTIONS, + "", "") EVENT_TYPE_TABLE_ENTRY("branch-misses", PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_MISSES, "", "") EVENT_TYPE_TABLE_ENTRY("bus-cycles", PERF_TYPE_HARDWARE, PERF_COUNT_HW_BUS_CYCLES, "", "") -EVENT_TYPE_TABLE_ENTRY("stalled-cycles-frontend", PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND, "", "") -EVENT_TYPE_TABLE_ENTRY("stalled-cycles-backend", PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_BACKEND, "", "") +EVENT_TYPE_TABLE_ENTRY("stalled-cycles-frontend", PERF_TYPE_HARDWARE, + PERF_COUNT_HW_STALLED_CYCLES_FRONTEND, "", "") +EVENT_TYPE_TABLE_ENTRY("stalled-cycles-backend", PERF_TYPE_HARDWARE, + PERF_COUNT_HW_STALLED_CYCLES_BACKEND, "", "") EVENT_TYPE_TABLE_ENTRY("cpu-clock", PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_CLOCK, "", "") EVENT_TYPE_TABLE_ENTRY("task-clock", PERF_TYPE_SOFTWARE, PERF_COUNT_SW_TASK_CLOCK, "", "") EVENT_TYPE_TABLE_ENTRY("page-faults", PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS, "", "") -EVENT_TYPE_TABLE_ENTRY("context-switches", PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CONTEXT_SWITCHES, "", "") +EVENT_TYPE_TABLE_ENTRY("context-switches", PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CONTEXT_SWITCHES, "", + "") EVENT_TYPE_TABLE_ENTRY("cpu-migrations", PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_MIGRATIONS, "", "") EVENT_TYPE_TABLE_ENTRY("minor-faults", PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS_MIN, "", "") EVENT_TYPE_TABLE_ENTRY("major-faults", PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS_MAJ, "", "") -EVENT_TYPE_TABLE_ENTRY("alignment-faults", PERF_TYPE_SOFTWARE, PERF_COUNT_SW_ALIGNMENT_FAULTS, "", "") -EVENT_TYPE_TABLE_ENTRY("emulation-faults", PERF_TYPE_SOFTWARE, PERF_COUNT_SW_EMULATION_FAULTS, "", "") +EVENT_TYPE_TABLE_ENTRY("alignment-faults", PERF_TYPE_SOFTWARE, PERF_COUNT_SW_ALIGNMENT_FAULTS, "", + "") +EVENT_TYPE_TABLE_ENTRY("emulation-faults", PERF_TYPE_SOFTWARE, PERF_COUNT_SW_EMULATION_FAULTS, "", + "") -EVENT_TYPE_TABLE_ENTRY("L1-dcache-loads", PERF_TYPE_HW_CACHE, ((PERF_COUNT_HW_CACHE_L1D) | (PERF_COUNT_HW_CACHE_OP_READ << 8) | (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)), "", "") -EVENT_TYPE_TABLE_ENTRY("L1-dcache-load-misses", PERF_TYPE_HW_CACHE, ((PERF_COUNT_HW_CACHE_L1D) | (PERF_COUNT_HW_CACHE_OP_READ << 8) | (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)), "", "") -EVENT_TYPE_TABLE_ENTRY("L1-dcache-stores", PERF_TYPE_HW_CACHE, ((PERF_COUNT_HW_CACHE_L1D) | (PERF_COUNT_HW_CACHE_OP_WRITE << 8) | (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)), "", "") -EVENT_TYPE_TABLE_ENTRY("L1-dcache-store-misses", PERF_TYPE_HW_CACHE, ((PERF_COUNT_HW_CACHE_L1D) | (PERF_COUNT_HW_CACHE_OP_WRITE << 8) | (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)), "", "") -EVENT_TYPE_TABLE_ENTRY("L1-dcache-prefetches", PERF_TYPE_HW_CACHE, ((PERF_COUNT_HW_CACHE_L1D) | (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)), "", "") -EVENT_TYPE_TABLE_ENTRY("L1-dcache-prefetch-misses", PERF_TYPE_HW_CACHE, ((PERF_COUNT_HW_CACHE_L1D) | (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)), "", "") -EVENT_TYPE_TABLE_ENTRY("L1-icache-loads", PERF_TYPE_HW_CACHE, ((PERF_COUNT_HW_CACHE_L1I) | (PERF_COUNT_HW_CACHE_OP_READ << 8) | (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)), "", "") -EVENT_TYPE_TABLE_ENTRY("L1-icache-load-misses", PERF_TYPE_HW_CACHE, ((PERF_COUNT_HW_CACHE_L1I) | (PERF_COUNT_HW_CACHE_OP_READ << 8) | (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)), "", "") -EVENT_TYPE_TABLE_ENTRY("L1-icache-stores", PERF_TYPE_HW_CACHE, ((PERF_COUNT_HW_CACHE_L1I) | (PERF_COUNT_HW_CACHE_OP_WRITE << 8) | (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)), "", "") -EVENT_TYPE_TABLE_ENTRY("L1-icache-store-misses", PERF_TYPE_HW_CACHE, ((PERF_COUNT_HW_CACHE_L1I) | (PERF_COUNT_HW_CACHE_OP_WRITE << 8) | (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)), "", "") -EVENT_TYPE_TABLE_ENTRY("L1-icache-prefetches", PERF_TYPE_HW_CACHE, ((PERF_COUNT_HW_CACHE_L1I) | (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)), "", "") -EVENT_TYPE_TABLE_ENTRY("L1-icache-prefetch-misses", PERF_TYPE_HW_CACHE, ((PERF_COUNT_HW_CACHE_L1I) | (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)), "", "") -EVENT_TYPE_TABLE_ENTRY("LLC-loads", PERF_TYPE_HW_CACHE, ((PERF_COUNT_HW_CACHE_LL) | (PERF_COUNT_HW_CACHE_OP_READ << 8) | (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)), "", "") -EVENT_TYPE_TABLE_ENTRY("LLC-load-misses", PERF_TYPE_HW_CACHE, ((PERF_COUNT_HW_CACHE_LL) | (PERF_COUNT_HW_CACHE_OP_READ << 8) | (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)), "", "") -EVENT_TYPE_TABLE_ENTRY("LLC-stores", PERF_TYPE_HW_CACHE, ((PERF_COUNT_HW_CACHE_LL) | (PERF_COUNT_HW_CACHE_OP_WRITE << 8) | (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)), "", "") -EVENT_TYPE_TABLE_ENTRY("LLC-store-misses", PERF_TYPE_HW_CACHE, ((PERF_COUNT_HW_CACHE_LL) | (PERF_COUNT_HW_CACHE_OP_WRITE << 8) | (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)), "", "") -EVENT_TYPE_TABLE_ENTRY("LLC-prefetches", PERF_TYPE_HW_CACHE, ((PERF_COUNT_HW_CACHE_LL) | (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)), "", "") -EVENT_TYPE_TABLE_ENTRY("LLC-prefetch-misses", PERF_TYPE_HW_CACHE, ((PERF_COUNT_HW_CACHE_LL) | (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)), "", "") -EVENT_TYPE_TABLE_ENTRY("dTLB-loads", PERF_TYPE_HW_CACHE, ((PERF_COUNT_HW_CACHE_DTLB) | (PERF_COUNT_HW_CACHE_OP_READ << 8) | (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)), "", "") -EVENT_TYPE_TABLE_ENTRY("dTLB-load-misses", PERF_TYPE_HW_CACHE, ((PERF_COUNT_HW_CACHE_DTLB) | (PERF_COUNT_HW_CACHE_OP_READ << 8) | (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)), "", "") -EVENT_TYPE_TABLE_ENTRY("dTLB-stores", PERF_TYPE_HW_CACHE, ((PERF_COUNT_HW_CACHE_DTLB) | (PERF_COUNT_HW_CACHE_OP_WRITE << 8) | (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)), "", "") -EVENT_TYPE_TABLE_ENTRY("dTLB-store-misses", PERF_TYPE_HW_CACHE, ((PERF_COUNT_HW_CACHE_DTLB) | (PERF_COUNT_HW_CACHE_OP_WRITE << 8) | (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)), "", "") -EVENT_TYPE_TABLE_ENTRY("dTLB-prefetches", PERF_TYPE_HW_CACHE, ((PERF_COUNT_HW_CACHE_DTLB) | (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)), "", "") -EVENT_TYPE_TABLE_ENTRY("dTLB-prefetch-misses", PERF_TYPE_HW_CACHE, ((PERF_COUNT_HW_CACHE_DTLB) | (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)), "", "") -EVENT_TYPE_TABLE_ENTRY("iTLB-loads", PERF_TYPE_HW_CACHE, ((PERF_COUNT_HW_CACHE_ITLB) | (PERF_COUNT_HW_CACHE_OP_READ << 8) | (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)), "", "") -EVENT_TYPE_TABLE_ENTRY("iTLB-load-misses", PERF_TYPE_HW_CACHE, ((PERF_COUNT_HW_CACHE_ITLB) | (PERF_COUNT_HW_CACHE_OP_READ << 8) | (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)), "", "") -EVENT_TYPE_TABLE_ENTRY("iTLB-stores", PERF_TYPE_HW_CACHE, ((PERF_COUNT_HW_CACHE_ITLB) | (PERF_COUNT_HW_CACHE_OP_WRITE << 8) | (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)), "", "") -EVENT_TYPE_TABLE_ENTRY("iTLB-store-misses", PERF_TYPE_HW_CACHE, ((PERF_COUNT_HW_CACHE_ITLB) | (PERF_COUNT_HW_CACHE_OP_WRITE << 8) | (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)), "", "") -EVENT_TYPE_TABLE_ENTRY("iTLB-prefetches", PERF_TYPE_HW_CACHE, ((PERF_COUNT_HW_CACHE_ITLB) | (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)), "", "") -EVENT_TYPE_TABLE_ENTRY("iTLB-prefetch-misses", PERF_TYPE_HW_CACHE, ((PERF_COUNT_HW_CACHE_ITLB) | (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)), "", "") -EVENT_TYPE_TABLE_ENTRY("branch-loads", PERF_TYPE_HW_CACHE, ((PERF_COUNT_HW_CACHE_BPU) | (PERF_COUNT_HW_CACHE_OP_READ << 8) | (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)), "", "") -EVENT_TYPE_TABLE_ENTRY("branch-load-misses", PERF_TYPE_HW_CACHE, ((PERF_COUNT_HW_CACHE_BPU) | (PERF_COUNT_HW_CACHE_OP_READ << 8) | (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)), "", "") -EVENT_TYPE_TABLE_ENTRY("branch-stores", PERF_TYPE_HW_CACHE, ((PERF_COUNT_HW_CACHE_BPU) | (PERF_COUNT_HW_CACHE_OP_WRITE << 8) | (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)), "", "") -EVENT_TYPE_TABLE_ENTRY("branch-store-misses", PERF_TYPE_HW_CACHE, ((PERF_COUNT_HW_CACHE_BPU) | (PERF_COUNT_HW_CACHE_OP_WRITE << 8) | (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)), "", "") -EVENT_TYPE_TABLE_ENTRY("branch-prefetches", PERF_TYPE_HW_CACHE, ((PERF_COUNT_HW_CACHE_BPU) | (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)), "", "") -EVENT_TYPE_TABLE_ENTRY("branch-prefetch-misses", PERF_TYPE_HW_CACHE, ((PERF_COUNT_HW_CACHE_BPU) | (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)), "", "") -EVENT_TYPE_TABLE_ENTRY("node-loads", PERF_TYPE_HW_CACHE, ((PERF_COUNT_HW_CACHE_NODE) | (PERF_COUNT_HW_CACHE_OP_READ << 8) | (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)), "", "") -EVENT_TYPE_TABLE_ENTRY("node-load-misses", PERF_TYPE_HW_CACHE, ((PERF_COUNT_HW_CACHE_NODE) | (PERF_COUNT_HW_CACHE_OP_READ << 8) | (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)), "", "") -EVENT_TYPE_TABLE_ENTRY("node-stores", PERF_TYPE_HW_CACHE, ((PERF_COUNT_HW_CACHE_NODE) | (PERF_COUNT_HW_CACHE_OP_WRITE << 8) | (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)), "", "") -EVENT_TYPE_TABLE_ENTRY("node-store-misses", PERF_TYPE_HW_CACHE, ((PERF_COUNT_HW_CACHE_NODE) | (PERF_COUNT_HW_CACHE_OP_WRITE << 8) | (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)), "", "") -EVENT_TYPE_TABLE_ENTRY("node-prefetches", PERF_TYPE_HW_CACHE, ((PERF_COUNT_HW_CACHE_NODE) | (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)), "", "") -EVENT_TYPE_TABLE_ENTRY("node-prefetch-misses", PERF_TYPE_HW_CACHE, ((PERF_COUNT_HW_CACHE_NODE) | (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)), "", "") +EVENT_TYPE_TABLE_ENTRY("L1-dcache-loads", PERF_TYPE_HW_CACHE, + ((PERF_COUNT_HW_CACHE_L1D) | (PERF_COUNT_HW_CACHE_OP_READ << 8) | + (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)), + "", "") +EVENT_TYPE_TABLE_ENTRY("L1-dcache-load-misses", PERF_TYPE_HW_CACHE, + ((PERF_COUNT_HW_CACHE_L1D) | (PERF_COUNT_HW_CACHE_OP_READ << 8) | + (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)), + "", "") +EVENT_TYPE_TABLE_ENTRY("L1-dcache-stores", PERF_TYPE_HW_CACHE, + ((PERF_COUNT_HW_CACHE_L1D) | (PERF_COUNT_HW_CACHE_OP_WRITE << 8) | + (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)), + "", "") +EVENT_TYPE_TABLE_ENTRY("L1-dcache-store-misses", PERF_TYPE_HW_CACHE, + ((PERF_COUNT_HW_CACHE_L1D) | (PERF_COUNT_HW_CACHE_OP_WRITE << 8) | + (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)), + "", "") +EVENT_TYPE_TABLE_ENTRY("L1-dcache-prefetches", PERF_TYPE_HW_CACHE, + ((PERF_COUNT_HW_CACHE_L1D) | (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | + (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)), + "", "") +EVENT_TYPE_TABLE_ENTRY("L1-dcache-prefetch-misses", PERF_TYPE_HW_CACHE, + ((PERF_COUNT_HW_CACHE_L1D) | (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | + (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)), + "", "") +EVENT_TYPE_TABLE_ENTRY("L1-icache-loads", PERF_TYPE_HW_CACHE, + ((PERF_COUNT_HW_CACHE_L1I) | (PERF_COUNT_HW_CACHE_OP_READ << 8) | + (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)), + "", "") +EVENT_TYPE_TABLE_ENTRY("L1-icache-load-misses", PERF_TYPE_HW_CACHE, + ((PERF_COUNT_HW_CACHE_L1I) | (PERF_COUNT_HW_CACHE_OP_READ << 8) | + (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)), + "", "") +EVENT_TYPE_TABLE_ENTRY("L1-icache-stores", PERF_TYPE_HW_CACHE, + ((PERF_COUNT_HW_CACHE_L1I) | (PERF_COUNT_HW_CACHE_OP_WRITE << 8) | + (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)), + "", "") +EVENT_TYPE_TABLE_ENTRY("L1-icache-store-misses", PERF_TYPE_HW_CACHE, + ((PERF_COUNT_HW_CACHE_L1I) | (PERF_COUNT_HW_CACHE_OP_WRITE << 8) | + (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)), + "", "") +EVENT_TYPE_TABLE_ENTRY("L1-icache-prefetches", PERF_TYPE_HW_CACHE, + ((PERF_COUNT_HW_CACHE_L1I) | (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | + (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)), + "", "") +EVENT_TYPE_TABLE_ENTRY("L1-icache-prefetch-misses", PERF_TYPE_HW_CACHE, + ((PERF_COUNT_HW_CACHE_L1I) | (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | + (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)), + "", "") +EVENT_TYPE_TABLE_ENTRY("LLC-loads", PERF_TYPE_HW_CACHE, + ((PERF_COUNT_HW_CACHE_LL) | (PERF_COUNT_HW_CACHE_OP_READ << 8) | + (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)), + "", "") +EVENT_TYPE_TABLE_ENTRY("LLC-load-misses", PERF_TYPE_HW_CACHE, + ((PERF_COUNT_HW_CACHE_LL) | (PERF_COUNT_HW_CACHE_OP_READ << 8) | + (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)), + "", "") +EVENT_TYPE_TABLE_ENTRY("LLC-stores", PERF_TYPE_HW_CACHE, + ((PERF_COUNT_HW_CACHE_LL) | (PERF_COUNT_HW_CACHE_OP_WRITE << 8) | + (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)), + "", "") +EVENT_TYPE_TABLE_ENTRY("LLC-store-misses", PERF_TYPE_HW_CACHE, + ((PERF_COUNT_HW_CACHE_LL) | (PERF_COUNT_HW_CACHE_OP_WRITE << 8) | + (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)), + "", "") +EVENT_TYPE_TABLE_ENTRY("LLC-prefetches", PERF_TYPE_HW_CACHE, + ((PERF_COUNT_HW_CACHE_LL) | (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | + (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)), + "", "") +EVENT_TYPE_TABLE_ENTRY("LLC-prefetch-misses", PERF_TYPE_HW_CACHE, + ((PERF_COUNT_HW_CACHE_LL) | (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | + (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)), + "", "") +EVENT_TYPE_TABLE_ENTRY("dTLB-loads", PERF_TYPE_HW_CACHE, + ((PERF_COUNT_HW_CACHE_DTLB) | (PERF_COUNT_HW_CACHE_OP_READ << 8) | + (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)), + "", "") +EVENT_TYPE_TABLE_ENTRY("dTLB-load-misses", PERF_TYPE_HW_CACHE, + ((PERF_COUNT_HW_CACHE_DTLB) | (PERF_COUNT_HW_CACHE_OP_READ << 8) | + (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)), + "", "") +EVENT_TYPE_TABLE_ENTRY("dTLB-stores", PERF_TYPE_HW_CACHE, + ((PERF_COUNT_HW_CACHE_DTLB) | (PERF_COUNT_HW_CACHE_OP_WRITE << 8) | + (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)), + "", "") +EVENT_TYPE_TABLE_ENTRY("dTLB-store-misses", PERF_TYPE_HW_CACHE, + ((PERF_COUNT_HW_CACHE_DTLB) | (PERF_COUNT_HW_CACHE_OP_WRITE << 8) | + (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)), + "", "") +EVENT_TYPE_TABLE_ENTRY("dTLB-prefetches", PERF_TYPE_HW_CACHE, + ((PERF_COUNT_HW_CACHE_DTLB) | (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | + (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)), + "", "") +EVENT_TYPE_TABLE_ENTRY("dTLB-prefetch-misses", PERF_TYPE_HW_CACHE, + ((PERF_COUNT_HW_CACHE_DTLB) | (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | + (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)), + "", "") +EVENT_TYPE_TABLE_ENTRY("iTLB-loads", PERF_TYPE_HW_CACHE, + ((PERF_COUNT_HW_CACHE_ITLB) | (PERF_COUNT_HW_CACHE_OP_READ << 8) | + (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)), + "", "") +EVENT_TYPE_TABLE_ENTRY("iTLB-load-misses", PERF_TYPE_HW_CACHE, + ((PERF_COUNT_HW_CACHE_ITLB) | (PERF_COUNT_HW_CACHE_OP_READ << 8) | + (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)), + "", "") +EVENT_TYPE_TABLE_ENTRY("iTLB-stores", PERF_TYPE_HW_CACHE, + ((PERF_COUNT_HW_CACHE_ITLB) | (PERF_COUNT_HW_CACHE_OP_WRITE << 8) | + (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)), + "", "") +EVENT_TYPE_TABLE_ENTRY("iTLB-store-misses", PERF_TYPE_HW_CACHE, + ((PERF_COUNT_HW_CACHE_ITLB) | (PERF_COUNT_HW_CACHE_OP_WRITE << 8) | + (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)), + "", "") +EVENT_TYPE_TABLE_ENTRY("iTLB-prefetches", PERF_TYPE_HW_CACHE, + ((PERF_COUNT_HW_CACHE_ITLB) | (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | + (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)), + "", "") +EVENT_TYPE_TABLE_ENTRY("iTLB-prefetch-misses", PERF_TYPE_HW_CACHE, + ((PERF_COUNT_HW_CACHE_ITLB) | (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | + (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)), + "", "") +EVENT_TYPE_TABLE_ENTRY("branch-loads", PERF_TYPE_HW_CACHE, + ((PERF_COUNT_HW_CACHE_BPU) | (PERF_COUNT_HW_CACHE_OP_READ << 8) | + (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)), + "", "") +EVENT_TYPE_TABLE_ENTRY("branch-load-misses", PERF_TYPE_HW_CACHE, + ((PERF_COUNT_HW_CACHE_BPU) | (PERF_COUNT_HW_CACHE_OP_READ << 8) | + (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)), + "", "") +EVENT_TYPE_TABLE_ENTRY("branch-stores", PERF_TYPE_HW_CACHE, + ((PERF_COUNT_HW_CACHE_BPU) | (PERF_COUNT_HW_CACHE_OP_WRITE << 8) | + (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)), + "", "") +EVENT_TYPE_TABLE_ENTRY("branch-store-misses", PERF_TYPE_HW_CACHE, + ((PERF_COUNT_HW_CACHE_BPU) | (PERF_COUNT_HW_CACHE_OP_WRITE << 8) | + (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)), + "", "") +EVENT_TYPE_TABLE_ENTRY("branch-prefetches", PERF_TYPE_HW_CACHE, + ((PERF_COUNT_HW_CACHE_BPU) | (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | + (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)), + "", "") +EVENT_TYPE_TABLE_ENTRY("branch-prefetch-misses", PERF_TYPE_HW_CACHE, + ((PERF_COUNT_HW_CACHE_BPU) | (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | + (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)), + "", "") +EVENT_TYPE_TABLE_ENTRY("node-loads", PERF_TYPE_HW_CACHE, + ((PERF_COUNT_HW_CACHE_NODE) | (PERF_COUNT_HW_CACHE_OP_READ << 8) | + (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)), + "", "") +EVENT_TYPE_TABLE_ENTRY("node-load-misses", PERF_TYPE_HW_CACHE, + ((PERF_COUNT_HW_CACHE_NODE) | (PERF_COUNT_HW_CACHE_OP_READ << 8) | + (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)), + "", "") +EVENT_TYPE_TABLE_ENTRY("node-stores", PERF_TYPE_HW_CACHE, + ((PERF_COUNT_HW_CACHE_NODE) | (PERF_COUNT_HW_CACHE_OP_WRITE << 8) | + (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)), + "", "") +EVENT_TYPE_TABLE_ENTRY("node-store-misses", PERF_TYPE_HW_CACHE, + ((PERF_COUNT_HW_CACHE_NODE) | (PERF_COUNT_HW_CACHE_OP_WRITE << 8) | + (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)), + "", "") +EVENT_TYPE_TABLE_ENTRY("node-prefetches", PERF_TYPE_HW_CACHE, + ((PERF_COUNT_HW_CACHE_NODE) | (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | + (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)), + "", "") +EVENT_TYPE_TABLE_ENTRY("node-prefetch-misses", PERF_TYPE_HW_CACHE, + ((PERF_COUNT_HW_CACHE_NODE) | (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | + (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)), + "", "") -EVENT_TYPE_TABLE_ENTRY("raw-sw-incr", PERF_TYPE_RAW, 0x0, "Instruction architecturally executed, Condition code check pass, software increment", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l1i-cache-refill", PERF_TYPE_RAW, 0x1, "Level 1 instruction cache refill", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l1i-tlb-refill", PERF_TYPE_RAW, 0x2, "Attributable Level 1 instruction TLB refill", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l1d-cache-refill", PERF_TYPE_RAW, 0x3, "Level 1 data cache refill", "arm") +EVENT_TYPE_TABLE_ENTRY( + "raw-sw-incr", PERF_TYPE_RAW, 0x0, + "Instruction architecturally executed, Condition code check pass, software increment", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l1i-cache-refill", PERF_TYPE_RAW, 0x1, + "Level 1 instruction cache refill", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l1i-tlb-refill", PERF_TYPE_RAW, 0x2, + "Attributable Level 1 instruction TLB refill", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l1d-cache-refill", PERF_TYPE_RAW, 0x3, "Level 1 data cache refill", + "arm") EVENT_TYPE_TABLE_ENTRY("raw-l1d-cache", PERF_TYPE_RAW, 0x4, "Level 1 data cache access", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l1d-tlb-refill", PERF_TYPE_RAW, 0x5, "Attributable Level 1 data TLB refill", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-ld-retired", PERF_TYPE_RAW, 0x6, "Instruction architecturally executed, Condition code check pass, load", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-st-retired", PERF_TYPE_RAW, 0x7, "Instruction architecturally executed, Condition code check pass, store", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-inst-retired", PERF_TYPE_RAW, 0x8, "Instruction architecturally executed", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l1d-tlb-refill", PERF_TYPE_RAW, 0x5, + "Attributable Level 1 data TLB refill", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-ld-retired", PERF_TYPE_RAW, 0x6, + "Instruction architecturally executed, Condition code check pass, load", + "arm") +EVENT_TYPE_TABLE_ENTRY("raw-st-retired", PERF_TYPE_RAW, 0x7, + "Instruction architecturally executed, Condition code check pass, store", + "arm") +EVENT_TYPE_TABLE_ENTRY("raw-inst-retired", PERF_TYPE_RAW, 0x8, + "Instruction architecturally executed", "arm") EVENT_TYPE_TABLE_ENTRY("raw-exc-taken", PERF_TYPE_RAW, 0x9, "Exception taken", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-exc-return", PERF_TYPE_RAW, 0xa, "Instruction architecturally executed, Condition code check pass, exception return", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-cid-write-retired", PERF_TYPE_RAW, 0xb, "Instruction architecturally executed, Condition code check pass, write to CONTEXTIDR", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-pc-write-retired", PERF_TYPE_RAW, 0xc, "Instruction architecturally executed, Condition code check pass, software change of the PC", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-br-immed-retired", PERF_TYPE_RAW, 0xd, "Instruction architecturally executed, immediate branch", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-br-return-retired", PERF_TYPE_RAW, 0xe, "Instruction architecturally executed, Condition code check pass, procedure return", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-unaligned-ldst-retired", PERF_TYPE_RAW, 0xf, "Instruction architecturally executed, Condition code check pass, unaligned load or store", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-br-mis-pred", PERF_TYPE_RAW, 0x10, "Mispredicted or not predicted branch Speculatively executed", "arm") +EVENT_TYPE_TABLE_ENTRY( + "raw-exc-return", PERF_TYPE_RAW, 0xa, + "Instruction architecturally executed, Condition code check pass, exception return", "arm") +EVENT_TYPE_TABLE_ENTRY( + "raw-cid-write-retired", PERF_TYPE_RAW, 0xb, + "Instruction architecturally executed, Condition code check pass, write to CONTEXTIDR", "arm") +EVENT_TYPE_TABLE_ENTRY( + "raw-pc-write-retired", PERF_TYPE_RAW, 0xc, + "Instruction architecturally executed, Condition code check pass, software change of the PC", + "arm") +EVENT_TYPE_TABLE_ENTRY("raw-br-immed-retired", PERF_TYPE_RAW, 0xd, + "Instruction architecturally executed, immediate branch", "arm") +EVENT_TYPE_TABLE_ENTRY( + "raw-br-return-retired", PERF_TYPE_RAW, 0xe, + "Instruction architecturally executed, Condition code check pass, procedure return", "arm") +EVENT_TYPE_TABLE_ENTRY( + "raw-unaligned-ldst-retired", PERF_TYPE_RAW, 0xf, + "Instruction architecturally executed, Condition code check pass, unaligned load or store", + "arm") +EVENT_TYPE_TABLE_ENTRY("raw-br-mis-pred", PERF_TYPE_RAW, 0x10, + "Mispredicted or not predicted branch Speculatively executed", "arm") EVENT_TYPE_TABLE_ENTRY("raw-cpu-cycles", PERF_TYPE_RAW, 0x11, "Cycle", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-br-pred", PERF_TYPE_RAW, 0x12, "Predictable branch Speculatively executed", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-br-pred", PERF_TYPE_RAW, 0x12, + "Predictable branch Speculatively executed", "arm") EVENT_TYPE_TABLE_ENTRY("raw-mem-access", PERF_TYPE_RAW, 0x13, "Data memory access", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l1i-cache", PERF_TYPE_RAW, 0x14, "Attributable Level 1 instruction cache access", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l1d-cache-wb", PERF_TYPE_RAW, 0x15, "Attributable Level 1 data cache write-back", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l1i-cache", PERF_TYPE_RAW, 0x14, + "Attributable Level 1 instruction cache access", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l1d-cache-wb", PERF_TYPE_RAW, 0x15, + "Attributable Level 1 data cache write-back", "arm") EVENT_TYPE_TABLE_ENTRY("raw-l2d-cache", PERF_TYPE_RAW, 0x16, "Level 2 data cache access", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l2d-cache-refill", PERF_TYPE_RAW, 0x17, "Level 2 data cache refill", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l2d-cache-wb", PERF_TYPE_RAW, 0x18, "Attributable Level 2 data cache write-back", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l2d-cache-refill", PERF_TYPE_RAW, 0x17, "Level 2 data cache refill", + "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l2d-cache-wb", PERF_TYPE_RAW, 0x18, + "Attributable Level 2 data cache write-back", "arm") EVENT_TYPE_TABLE_ENTRY("raw-bus-access", PERF_TYPE_RAW, 0x19, "Bus access", "arm") EVENT_TYPE_TABLE_ENTRY("raw-memory-error", PERF_TYPE_RAW, 0x1a, "Local memory error", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-inst-spec", PERF_TYPE_RAW, 0x1b, "Operation Speculatively executed", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-ttbr-write-retired", PERF_TYPE_RAW, 0x1c, "Instruction architecturally executed, Condition code check pass, write to TTBR", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-inst-spec", PERF_TYPE_RAW, 0x1b, "Operation Speculatively executed", + "arm") +EVENT_TYPE_TABLE_ENTRY( + "raw-ttbr-write-retired", PERF_TYPE_RAW, 0x1c, + "Instruction architecturally executed, Condition code check pass, write to TTBR", "arm") EVENT_TYPE_TABLE_ENTRY("raw-bus-cycles", PERF_TYPE_RAW, 0x1d, "Bus cycle", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-chain", PERF_TYPE_RAW, 0x1e, "For odd-numbered counters, increments the count by one for each overflow of the preceding even-numbered counter. For even-numbered counters, there is no increment.", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l1d-cache-allocate", PERF_TYPE_RAW, 0x1f, "Attributable Level 1 data cache allocation without refill", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l2d-cache-allocate", PERF_TYPE_RAW, 0x20, "Attributable Level 2 data cache allocation without refill", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-br-retired", PERF_TYPE_RAW, 0x21, "Instruction architecturally executed, branch", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-br-mis-pred-retired", PERF_TYPE_RAW, 0x22, "Instruction architecturally executed, mispredicted branch", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-stall-frontend", PERF_TYPE_RAW, 0x23, "No operation issued due to the frontend", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-stall-backend", PERF_TYPE_RAW, 0x24, "No operation issued due to backend", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l1d-tlb", PERF_TYPE_RAW, 0x25, "Attributable Level 1 data or unified TLB access", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l1i-tlb", PERF_TYPE_RAW, 0x26, "Attributable Level 1 instruction TLB access", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l2i-cache", PERF_TYPE_RAW, 0x27, "Attributable Level 2 instruction cache access", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l2i-cache-refill", PERF_TYPE_RAW, 0x28, "Attributable Level 2 instruction cache refill", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l3d-cache-allocate", PERF_TYPE_RAW, 0x29, "Attributable Level 3 data or unified cache allocation without refill", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l3d-cache-refill", PERF_TYPE_RAW, 0x2a, "Attributable Level 3 data cache refill", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l3d-cache", PERF_TYPE_RAW, 0x2b, "Attributable Level 3 data cache access", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l3d-cache-wb", PERF_TYPE_RAW, 0x2c, "Attributable Level 3 data or unified cache write-back", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l2d-tlb-refill", PERF_TYPE_RAW, 0x2d, "Attributable Level 2 data or unified TLB refill", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l2i-tlb-refill", PERF_TYPE_RAW, 0x2e, "Attributable Level 2 instruction TLB refill", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l2d-tlb", PERF_TYPE_RAW, 0x2f, "Attributable Level 2 data or unified TLB access", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l2i-tlb", PERF_TYPE_RAW, 0x30, "Attributable Level 2 instruction TLB access", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-remote-access", PERF_TYPE_RAW, 0x31, "Attributable access to another socket in a multi-socket system", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-ll-cache", PERF_TYPE_RAW, 0x32, "Attributable Last Level data cache access", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-ll-cache-miss", PERF_TYPE_RAW, 0x33, "Attributable Last level data or unified cache miss", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-dtlb-walk", PERF_TYPE_RAW, 0x34, "Attributable data or unified TLB access with at least one translation table walk", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-itlb-walk", PERF_TYPE_RAW, 0x35, "Attributable instruction TLB access with at least one translation table walk", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-ll-cache-rd", PERF_TYPE_RAW, 0x36, "Attributable Last Level cache memory read", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-ll-cache-miss-rd", PERF_TYPE_RAW, 0x37, "Attributable Last Level cache memory read miss", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-remote-access-rd", PERF_TYPE_RAW, 0x38, "Attributable memory read access to another socket in a multi-socket system", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l1d-cache-lmiss-rd", PERF_TYPE_RAW, 0x39, "Level 1 data cache long-latency read miss", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-op-retired", PERF_TYPE_RAW, 0x3a, "Micro-operation architecturally executed", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-op-spec", PERF_TYPE_RAW, 0x3b, "Micro-operation Speculatively executed", "arm") +EVENT_TYPE_TABLE_ENTRY( + "raw-chain", PERF_TYPE_RAW, 0x1e, + "For odd-numbered counters, increments the count by one for each overflow of the preceding " + "even-numbered counter. For even-numbered counters, there is no increment.", + "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l1d-cache-allocate", PERF_TYPE_RAW, 0x1f, + "Attributable Level 1 data cache allocation without refill", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l2d-cache-allocate", PERF_TYPE_RAW, 0x20, + "Attributable Level 2 data cache allocation without refill", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-br-retired", PERF_TYPE_RAW, 0x21, + "Instruction architecturally executed, branch", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-br-mis-pred-retired", PERF_TYPE_RAW, 0x22, + "Instruction architecturally executed, mispredicted branch", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-stall-frontend", PERF_TYPE_RAW, 0x23, + "No operation issued due to the frontend", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-stall-backend", PERF_TYPE_RAW, 0x24, + "No operation issued due to backend", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l1d-tlb", PERF_TYPE_RAW, 0x25, + "Attributable Level 1 data or unified TLB access", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l1i-tlb", PERF_TYPE_RAW, 0x26, + "Attributable Level 1 instruction TLB access", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l2i-cache", PERF_TYPE_RAW, 0x27, + "Attributable Level 2 instruction cache access", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l2i-cache-refill", PERF_TYPE_RAW, 0x28, + "Attributable Level 2 instruction cache refill", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l3d-cache-allocate", PERF_TYPE_RAW, 0x29, + "Attributable Level 3 data or unified cache allocation without refill", + "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l3d-cache-refill", PERF_TYPE_RAW, 0x2a, + "Attributable Level 3 data cache refill", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l3d-cache", PERF_TYPE_RAW, 0x2b, + "Attributable Level 3 data cache access", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l3d-cache-wb", PERF_TYPE_RAW, 0x2c, + "Attributable Level 3 data or unified cache write-back", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l2d-tlb-refill", PERF_TYPE_RAW, 0x2d, + "Attributable Level 2 data or unified TLB refill", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l2i-tlb-refill", PERF_TYPE_RAW, 0x2e, + "Attributable Level 2 instruction TLB refill", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l2d-tlb", PERF_TYPE_RAW, 0x2f, + "Attributable Level 2 data or unified TLB access", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l2i-tlb", PERF_TYPE_RAW, 0x30, + "Attributable Level 2 instruction TLB access", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-remote-access", PERF_TYPE_RAW, 0x31, + "Attributable access to another socket in a multi-socket system", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-ll-cache", PERF_TYPE_RAW, 0x32, + "Attributable Last Level data cache access", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-ll-cache-miss", PERF_TYPE_RAW, 0x33, + "Attributable Last level data or unified cache miss", "arm") +EVENT_TYPE_TABLE_ENTRY( + "raw-dtlb-walk", PERF_TYPE_RAW, 0x34, + "Attributable data or unified TLB access with at least one translation table walk", "arm") +EVENT_TYPE_TABLE_ENTRY( + "raw-itlb-walk", PERF_TYPE_RAW, 0x35, + "Attributable instruction TLB access with at least one translation table walk", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-ll-cache-rd", PERF_TYPE_RAW, 0x36, + "Attributable Last Level cache memory read", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-ll-cache-miss-rd", PERF_TYPE_RAW, 0x37, + "Attributable Last Level cache memory read miss", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-remote-access-rd", PERF_TYPE_RAW, 0x38, + "Attributable memory read access to another socket in a multi-socket system", + "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l1d-cache-lmiss-rd", PERF_TYPE_RAW, 0x39, + "Level 1 data cache long-latency read miss", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-op-retired", PERF_TYPE_RAW, 0x3a, + "Micro-operation architecturally executed", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-op-spec", PERF_TYPE_RAW, 0x3b, "Micro-operation Speculatively executed", + "arm") EVENT_TYPE_TABLE_ENTRY("raw-stall", PERF_TYPE_RAW, 0x3c, "No operation sent for execution", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-stall-slot-backend", PERF_TYPE_RAW, 0x3d, "No operation sent for execution on a Slot due to the backend", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-stall-slot-frontend", PERF_TYPE_RAW, 0x3e, "No operation send for execution on a Slot due to the frontend", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-stall-slot", PERF_TYPE_RAW, 0x3f, "No operation sent for execution on a Slot", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-stall-slot-backend", PERF_TYPE_RAW, 0x3d, + "No operation sent for execution on a Slot due to the backend", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-stall-slot-frontend", PERF_TYPE_RAW, 0x3e, + "No operation send for execution on a Slot due to the frontend", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-stall-slot", PERF_TYPE_RAW, 0x3f, + "No operation sent for execution on a Slot", "arm") EVENT_TYPE_TABLE_ENTRY("raw-l1d-cache-rd", PERF_TYPE_RAW, 0x40, "Level 1 data cache read", "arm") EVENT_TYPE_TABLE_ENTRY("raw-sample-pop", PERF_TYPE_RAW, 0x4000, "Sample Population", "arm") EVENT_TYPE_TABLE_ENTRY("raw-sample-feed", PERF_TYPE_RAW, 0x4001, "Sample Taken", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-sample-filtrate", PERF_TYPE_RAW, 0x4002, "Sample Taken and not removed by filtering", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-sample-collision", PERF_TYPE_RAW, 0x4003, "Sample collided with previous sample", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-sample-filtrate", PERF_TYPE_RAW, 0x4002, + "Sample Taken and not removed by filtering", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-sample-collision", PERF_TYPE_RAW, 0x4003, + "Sample collided with previous sample", "arm") EVENT_TYPE_TABLE_ENTRY("raw-cnt-cycles", PERF_TYPE_RAW, 0x4004, "Constant frequency cycles", "arm") EVENT_TYPE_TABLE_ENTRY("raw-stall-backend-mem", PERF_TYPE_RAW, 0x4005, "Memory stall cycles", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l1i-cache-lmiss", PERF_TYPE_RAW, 0x4006, "Level 1 instruction cache long-latency miss", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l2d-cache-lmiss-rd", PERF_TYPE_RAW, 0x4009, "Level 2 data cache long-latency read miss", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l2i-cache-lmiss", PERF_TYPE_RAW, 0x400a, "Level 2 instruction cache long-latency miss", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l3d-cache-lmiss-rd", PERF_TYPE_RAW, 0x400b, "Level 3 data cache long-latency read miss", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-sve-inst-retired", PERF_TYPE_RAW, 0x8002, "SVE Instructions architecturally executed", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-sve-inst-spec", PERF_TYPE_RAW, 0x8006, "SVE Instructions speculatively executed", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l1d-cache-wr", PERF_TYPE_RAW, 0x41, "Attributable Level 1 data cache access, write", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l1d-cache-refill-rd", PERF_TYPE_RAW, 0x42, "Attributable Level 1 data cache refill, read", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l1d-cache-refill-wr", PERF_TYPE_RAW, 0x43, "Attributable Level 1 data cache refill, write", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l1d-cache-refill-inner", PERF_TYPE_RAW, 0x44, "Attributable Level 1 data cache refill, inner", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l1d-cache-refill-outer", PERF_TYPE_RAW, 0x45, "Attributable Level 1 data cache refill, outer", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l1d-cache-wb-victim", PERF_TYPE_RAW, 0x46, "Attributable Level 1 data cache Write-Back, victim", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l1d-cache-wb-clean", PERF_TYPE_RAW, 0x47, "Level 1 data cache Write-Back, cleaning and coherency", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l1d-cache-inval", PERF_TYPE_RAW, 0x48, "Attributable Level 1 data cache invalidate", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l1d-tlb-refill-rd", PERF_TYPE_RAW, 0x4c, "Attributable Level 1 data TLB refill, read", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l1d-tlb-refill-wr", PERF_TYPE_RAW, 0x4d, "Attributable Level 1 data TLB refill, write", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l1d-tlb-rd", PERF_TYPE_RAW, 0x4e, "Attributable Level 1 data or unified TLB access, read", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l1d-tlb-wr", PERF_TYPE_RAW, 0x4f, "Attributable Level 1 data or unified TLB access, write", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l2d-cache-rd", PERF_TYPE_RAW, 0x50, "Attributable Level 2 data cache access, read", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l2d-cache-wr", PERF_TYPE_RAW, 0x51, "Attributable Level 2 data cache access, write", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l2d-cache-refill-rd", PERF_TYPE_RAW, 0x52, "Attributable Level 2 data cache refill, read", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l2d-cache-refill-wr", PERF_TYPE_RAW, 0x53, "Attributable Level 2 data cache refill, write", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l2d-cache-wb-victim", PERF_TYPE_RAW, 0x56, "Attributable Level 2 data cache Write-Back, victim", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l2d-cache-wb-clean", PERF_TYPE_RAW, 0x57, "Level 2 data cache Write-Back, cleaning and coherency", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l2d-cache-inval", PERF_TYPE_RAW, 0x58, "Attributable Level 2 data cache invalidate", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l2d-tlb-refill-rd", PERF_TYPE_RAW, 0x5c, "Attributable Level 2 data or unified TLB refill, read", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l2d-tlb-refill-wr", PERF_TYPE_RAW, 0x5d, "Attributable Level 2 data or unified TLB refill, write", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l2d-tlb-rd", PERF_TYPE_RAW, 0x5e, "Attributable Level 2 data or unified TLB access, read", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l2d-tlb-wr", PERF_TYPE_RAW, 0x5f, "Attributable Level 2 data or unified TLB access, write", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l1i-cache-lmiss", PERF_TYPE_RAW, 0x4006, + "Level 1 instruction cache long-latency miss", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l2d-cache-lmiss-rd", PERF_TYPE_RAW, 0x4009, + "Level 2 data cache long-latency read miss", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l2i-cache-lmiss", PERF_TYPE_RAW, 0x400a, + "Level 2 instruction cache long-latency miss", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l3d-cache-lmiss-rd", PERF_TYPE_RAW, 0x400b, + "Level 3 data cache long-latency read miss", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-sve-inst-retired", PERF_TYPE_RAW, 0x8002, + "SVE Instructions architecturally executed", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-sve-inst-spec", PERF_TYPE_RAW, 0x8006, + "SVE Instructions speculatively executed", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l1d-cache-wr", PERF_TYPE_RAW, 0x41, + "Attributable Level 1 data cache access, write", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l1d-cache-refill-rd", PERF_TYPE_RAW, 0x42, + "Attributable Level 1 data cache refill, read", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l1d-cache-refill-wr", PERF_TYPE_RAW, 0x43, + "Attributable Level 1 data cache refill, write", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l1d-cache-refill-inner", PERF_TYPE_RAW, 0x44, + "Attributable Level 1 data cache refill, inner", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l1d-cache-refill-outer", PERF_TYPE_RAW, 0x45, + "Attributable Level 1 data cache refill, outer", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l1d-cache-wb-victim", PERF_TYPE_RAW, 0x46, + "Attributable Level 1 data cache Write-Back, victim", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l1d-cache-wb-clean", PERF_TYPE_RAW, 0x47, + "Level 1 data cache Write-Back, cleaning and coherency", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l1d-cache-inval", PERF_TYPE_RAW, 0x48, + "Attributable Level 1 data cache invalidate", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l1d-tlb-refill-rd", PERF_TYPE_RAW, 0x4c, + "Attributable Level 1 data TLB refill, read", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l1d-tlb-refill-wr", PERF_TYPE_RAW, 0x4d, + "Attributable Level 1 data TLB refill, write", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l1d-tlb-rd", PERF_TYPE_RAW, 0x4e, + "Attributable Level 1 data or unified TLB access, read", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l1d-tlb-wr", PERF_TYPE_RAW, 0x4f, + "Attributable Level 1 data or unified TLB access, write", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l2d-cache-rd", PERF_TYPE_RAW, 0x50, + "Attributable Level 2 data cache access, read", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l2d-cache-wr", PERF_TYPE_RAW, 0x51, + "Attributable Level 2 data cache access, write", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l2d-cache-refill-rd", PERF_TYPE_RAW, 0x52, + "Attributable Level 2 data cache refill, read", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l2d-cache-refill-wr", PERF_TYPE_RAW, 0x53, + "Attributable Level 2 data cache refill, write", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l2d-cache-wb-victim", PERF_TYPE_RAW, 0x56, + "Attributable Level 2 data cache Write-Back, victim", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l2d-cache-wb-clean", PERF_TYPE_RAW, 0x57, + "Level 2 data cache Write-Back, cleaning and coherency", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l2d-cache-inval", PERF_TYPE_RAW, 0x58, + "Attributable Level 2 data cache invalidate", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l2d-tlb-refill-rd", PERF_TYPE_RAW, 0x5c, + "Attributable Level 2 data or unified TLB refill, read", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l2d-tlb-refill-wr", PERF_TYPE_RAW, 0x5d, + "Attributable Level 2 data or unified TLB refill, write", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l2d-tlb-rd", PERF_TYPE_RAW, 0x5e, + "Attributable Level 2 data or unified TLB access, read", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l2d-tlb-wr", PERF_TYPE_RAW, 0x5f, + "Attributable Level 2 data or unified TLB access, write", "arm") EVENT_TYPE_TABLE_ENTRY("raw-bus-access-rd", PERF_TYPE_RAW, 0x60, "Bus access, read", "arm") EVENT_TYPE_TABLE_ENTRY("raw-bus-access-wr", PERF_TYPE_RAW, 0x61, "Bus access, write", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-bus-access-shared", PERF_TYPE_RAW, 0x62, "Bus access, Normal, Cacheable, Shareable", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-bus-access-not-shared", PERF_TYPE_RAW, 0x63, "Bus access, not Normal, Cacheable, Shareable", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-bus-access-shared", PERF_TYPE_RAW, 0x62, + "Bus access, Normal, Cacheable, Shareable", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-bus-access-not-shared", PERF_TYPE_RAW, 0x63, + "Bus access, not Normal, Cacheable, Shareable", "arm") EVENT_TYPE_TABLE_ENTRY("raw-bus-access-normal", PERF_TYPE_RAW, 0x64, "Bus access, normal", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-bus-access-periph", PERF_TYPE_RAW, 0x65, "Bus access, peripheral", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-bus-access-periph", PERF_TYPE_RAW, 0x65, "Bus access, peripheral", + "arm") EVENT_TYPE_TABLE_ENTRY("raw-mem-access-rd", PERF_TYPE_RAW, 0x66, "Data memory access, read", "arm") EVENT_TYPE_TABLE_ENTRY("raw-mem-access-wr", PERF_TYPE_RAW, 0x67, "Data memory access, write", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-unaligned-ld-spec", PERF_TYPE_RAW, 0x68, "Unaligned access, read", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-unaligned-st-spec", PERF_TYPE_RAW, 0x69, "Unaligned access, write", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-unaligned-ld-spec", PERF_TYPE_RAW, 0x68, "Unaligned access, read", + "arm") +EVENT_TYPE_TABLE_ENTRY("raw-unaligned-st-spec", PERF_TYPE_RAW, 0x69, "Unaligned access, write", + "arm") EVENT_TYPE_TABLE_ENTRY("raw-unaligned-ldst-spec", PERF_TYPE_RAW, 0x6a, "Unaligned access", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-ldrex-spec", PERF_TYPE_RAW, 0x6c, "Exclusive operation speculatively executed, LDREX or LDX", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-strex-pass-spec", PERF_TYPE_RAW, 0x6d, "Exclusive operation speculatively executed, STREX or STX pass", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-strex-fail-spec", PERF_TYPE_RAW, 0x6e, "Exclusive operation speculatively executed, STREX or STX fail", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-strex-spec", PERF_TYPE_RAW, 0x6f, "Exclusive operation speculatively executed, STREX or STX", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-ld-spec", PERF_TYPE_RAW, 0x70, "Operation speculatively executed, load", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-st-spec", PERF_TYPE_RAW, 0x71, "Operation speculatively executed, store", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-ldst-spec", PERF_TYPE_RAW, 0x72, "Operation speculatively executed, load or store", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-dp-spec", PERF_TYPE_RAW, 0x73, "Operation speculatively executed, integer data processing", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-ase-spec", PERF_TYPE_RAW, 0x74, "Operation speculatively executed, Advanced SIMD instruction", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-vfp-spec", PERF_TYPE_RAW, 0x75, "Operation speculatively executed, floating-point instruction", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-pc-write-spec", PERF_TYPE_RAW, 0x76, "Operation speculatively executed, software change of the PC", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-crypto-spec", PERF_TYPE_RAW, 0x77, "Operation speculatively executed, Cryptographic instruction", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-br-immed-spec", PERF_TYPE_RAW, 0x78, "Branch speculatively executed, immediate branch", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-br-return-spec", PERF_TYPE_RAW, 0x79, "Branch speculatively executed, procedure return", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-br-indirect-spec", PERF_TYPE_RAW, 0x7a, "Branch speculatively executed, indirect branch", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-isb-spec", PERF_TYPE_RAW, 0x7c, "Barrier speculatively executed, ISB", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-dsb-spec", PERF_TYPE_RAW, 0x7d, "Barrier speculatively executed, DSB", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-dmb-spec", PERF_TYPE_RAW, 0x7e, "Barrier speculatively executed, DMB", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-exc-undef", PERF_TYPE_RAW, 0x81, "Exception taken, Other synchronous", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-exc-svc", PERF_TYPE_RAW, 0x82, "Exception taken, Supervisor Call", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-exc-pabort", PERF_TYPE_RAW, 0x83, "Exception taken, Instruction Abort", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-exc-dabort", PERF_TYPE_RAW, 0x84, "Exception taken, Data Abort and SError", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-ldrex-spec", PERF_TYPE_RAW, 0x6c, + "Exclusive operation speculatively executed, LDREX or LDX", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-strex-pass-spec", PERF_TYPE_RAW, 0x6d, + "Exclusive operation speculatively executed, STREX or STX pass", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-strex-fail-spec", PERF_TYPE_RAW, 0x6e, + "Exclusive operation speculatively executed, STREX or STX fail", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-strex-spec", PERF_TYPE_RAW, 0x6f, + "Exclusive operation speculatively executed, STREX or STX", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-ld-spec", PERF_TYPE_RAW, 0x70, "Operation speculatively executed, load", + "arm") +EVENT_TYPE_TABLE_ENTRY("raw-st-spec", PERF_TYPE_RAW, 0x71, + "Operation speculatively executed, store", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-ldst-spec", PERF_TYPE_RAW, 0x72, + "Operation speculatively executed, load or store", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-dp-spec", PERF_TYPE_RAW, 0x73, + "Operation speculatively executed, integer data processing", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-ase-spec", PERF_TYPE_RAW, 0x74, + "Operation speculatively executed, Advanced SIMD instruction", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-vfp-spec", PERF_TYPE_RAW, 0x75, + "Operation speculatively executed, floating-point instruction", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-pc-write-spec", PERF_TYPE_RAW, 0x76, + "Operation speculatively executed, software change of the PC", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-crypto-spec", PERF_TYPE_RAW, 0x77, + "Operation speculatively executed, Cryptographic instruction", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-br-immed-spec", PERF_TYPE_RAW, 0x78, + "Branch speculatively executed, immediate branch", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-br-return-spec", PERF_TYPE_RAW, 0x79, + "Branch speculatively executed, procedure return", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-br-indirect-spec", PERF_TYPE_RAW, 0x7a, + "Branch speculatively executed, indirect branch", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-isb-spec", PERF_TYPE_RAW, 0x7c, "Barrier speculatively executed, ISB", + "arm") +EVENT_TYPE_TABLE_ENTRY("raw-dsb-spec", PERF_TYPE_RAW, 0x7d, "Barrier speculatively executed, DSB", + "arm") +EVENT_TYPE_TABLE_ENTRY("raw-dmb-spec", PERF_TYPE_RAW, 0x7e, "Barrier speculatively executed, DMB", + "arm") +EVENT_TYPE_TABLE_ENTRY("raw-exc-undef", PERF_TYPE_RAW, 0x81, "Exception taken, Other synchronous", + "arm") +EVENT_TYPE_TABLE_ENTRY("raw-exc-svc", PERF_TYPE_RAW, 0x82, "Exception taken, Supervisor Call", + "arm") +EVENT_TYPE_TABLE_ENTRY("raw-exc-pabort", PERF_TYPE_RAW, 0x83, "Exception taken, Instruction Abort", + "arm") +EVENT_TYPE_TABLE_ENTRY("raw-exc-dabort", PERF_TYPE_RAW, 0x84, + "Exception taken, Data Abort and SError", "arm") EVENT_TYPE_TABLE_ENTRY("raw-exc-irq", PERF_TYPE_RAW, 0x86, "Exception taken, IRQ", "arm") EVENT_TYPE_TABLE_ENTRY("raw-exc-fiq", PERF_TYPE_RAW, 0x87, "Exception taken, FIQ", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-exc-smc", PERF_TYPE_RAW, 0x88, "Exception taken, Secure Monitor Call", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-exc-hvc", PERF_TYPE_RAW, 0x8a, "Exception taken, Hypervisor Call", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-exc-trap-pabort", PERF_TYPE_RAW, 0x8b, "Exception taken, Instruction Abort not Taken locallyb", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-exc-trap-dabort", PERF_TYPE_RAW, 0x8c, "Exception taken, Data Abort or SError not Taken locallyb", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-exc-trap-other", PERF_TYPE_RAW, 0x8d, "Exception taken, Other traps not Taken locallyb", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-exc-trap-irq", PERF_TYPE_RAW, 0x8e, "Exception taken, IRQ not Taken locallyb", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-exc-trap-fiq", PERF_TYPE_RAW, 0x8f, "Exception taken, FIQ not Taken locallyb", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-rc-ld-spec", PERF_TYPE_RAW, 0x90, "Release consistency operation speculatively executed, Load-Acquire", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-rc-st-spec", PERF_TYPE_RAW, 0x91, "Release consistency operation speculatively executed, Store-Release", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l3d-cache-rd", PERF_TYPE_RAW, 0xa0, "Attributable Level 3 data or unified cache access, read", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l3d-cache-wr", PERF_TYPE_RAW, 0xa1, "Attributable Level 3 data or unified cache access, write", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l3d-cache-refill-rd", PERF_TYPE_RAW, 0xa2, "Attributable Level 3 data or unified cache refill, read", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l3d-cache-refill-wr", PERF_TYPE_RAW, 0xa3, "Attributable Level 3 data or unified cache refill, write", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l3d-cache-wb-victim", PERF_TYPE_RAW, 0xa6, "Attributable Level 3 data or unified cache Write-Back, victim", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l3d-cache-wb-clean", PERF_TYPE_RAW, 0xa7, "Attributable Level 3 data or unified cache Write-Back, cache clean", "arm") -EVENT_TYPE_TABLE_ENTRY("raw-l3d-cache-inval", PERF_TYPE_RAW, 0xa8, "Attributable Level 3 data or unified cache access, invalidate", "arm") - +EVENT_TYPE_TABLE_ENTRY("raw-exc-smc", PERF_TYPE_RAW, 0x88, "Exception taken, Secure Monitor Call", + "arm") +EVENT_TYPE_TABLE_ENTRY("raw-exc-hvc", PERF_TYPE_RAW, 0x8a, "Exception taken, Hypervisor Call", + "arm") +EVENT_TYPE_TABLE_ENTRY("raw-exc-trap-pabort", PERF_TYPE_RAW, 0x8b, + "Exception taken, Instruction Abort not Taken locallyb", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-exc-trap-dabort", PERF_TYPE_RAW, 0x8c, + "Exception taken, Data Abort or SError not Taken locallyb", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-exc-trap-other", PERF_TYPE_RAW, 0x8d, + "Exception taken, Other traps not Taken locallyb", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-exc-trap-irq", PERF_TYPE_RAW, 0x8e, + "Exception taken, IRQ not Taken locallyb", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-exc-trap-fiq", PERF_TYPE_RAW, 0x8f, + "Exception taken, FIQ not Taken locallyb", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-rc-ld-spec", PERF_TYPE_RAW, 0x90, + "Release consistency operation speculatively executed, Load-Acquire", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-rc-st-spec", PERF_TYPE_RAW, 0x91, + "Release consistency operation speculatively executed, Store-Release", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l3d-cache-rd", PERF_TYPE_RAW, 0xa0, + "Attributable Level 3 data or unified cache access, read", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l3d-cache-wr", PERF_TYPE_RAW, 0xa1, + "Attributable Level 3 data or unified cache access, write", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l3d-cache-refill-rd", PERF_TYPE_RAW, 0xa2, + "Attributable Level 3 data or unified cache refill, read", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l3d-cache-refill-wr", PERF_TYPE_RAW, 0xa3, + "Attributable Level 3 data or unified cache refill, write", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l3d-cache-wb-victim", PERF_TYPE_RAW, 0xa6, + "Attributable Level 3 data or unified cache Write-Back, victim", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l3d-cache-wb-clean", PERF_TYPE_RAW, 0xa7, + "Attributable Level 3 data or unified cache Write-Back, cache clean", "arm") +EVENT_TYPE_TABLE_ENTRY("raw-l3d-cache-inval", PERF_TYPE_RAW, 0xa8, + "Attributable Level 3 data or unified cache access, invalidate", "arm") diff --git a/simpleperf/get_test_data.h b/simpleperf/get_test_data.h index d9e0d988..fc3c84c2 100644 --- a/simpleperf/get_test_data.h +++ b/simpleperf/get_test_data.h @@ -35,7 +35,8 @@ static const std::string PERF_DATA = "perf.data"; // perf_with_multiple_pids_and_tids.data is generated by sampling on two processes, each // process running two threads. -static const std::string PERF_DATA_WITH_MULTIPLE_PIDS_AND_TIDS = "perf_with_multiple_pids_and_tids.data"; +static const std::string PERF_DATA_WITH_MULTIPLE_PIDS_AND_TIDS = + "perf_with_multiple_pids_and_tids.data"; // perf_g_fp.data is generated by sampling on one process running elf using --call-graph fp option. static const std::string CALLGRAPH_FP_PERF_DATA = "perf_g_fp.data"; @@ -47,7 +48,6 @@ static const std::string PERF_DATA_WITH_MINI_DEBUG_INFO = "perf_with_mini_debug_ static BuildId elf_file_build_id("0b12a384a9f4a3f3659b7171ca615dbec3a81f71"); - // To generate apk supporting execution on shared libraries in apk: // 1. Add android:extractNativeLibs=false in AndroidManifest.xml. // 2. Use `zip -0` to store native libraries in apk without compression. @@ -84,9 +84,10 @@ static const std::string PERF_DATA_WITH_SYMBOLS = "perf_with_symbols.data"; static const std::string PERF_DATA_WITH_SYMBOLS_FOR_NONZERO_MINVADDR_DSO = "perf_with_symbols_for_nonzero_minvaddr_dso.data"; -// perf_kmem_slab_callgraph.data is generated by `simpleperf kmem record --slab --call-graph fp -f 100 sleep 0.0001`. -static const std::string PERF_DATA_WITH_KMEM_SLAB_CALLGRAPH_RECORD = "perf_with_kmem_slab_callgraph.data"; - +// perf_kmem_slab_callgraph.data is generated by `simpleperf kmem record --slab --call-graph fp -f +// 100 sleep 0.0001`. +static const std::string PERF_DATA_WITH_KMEM_SLAB_CALLGRAPH_RECORD = + "perf_with_kmem_slab_callgraph.data"; // perf_for_build_id_check.data is generated by recording a process running // testdata/data/correct_symfs_for_build_id_check/elf_for_build_id_check. @@ -94,7 +95,8 @@ static const std::string PERF_DATA_FOR_BUILD_ID_CHECK = "perf_for_build_id_check static const std::string CORRECT_SYMFS_FOR_BUILD_ID_CHECK = "data/correct_symfs_for_build_id_check"; static const std::string WRONG_SYMFS_FOR_BUILD_ID_CHECK = "data/wrong_symfs_for_build_id_check"; -static const std::string SYMFS_FOR_NO_SYMBOL_TABLE_WARNING = "data/symfs_for_no_symbol_table_warning"; +static const std::string SYMFS_FOR_NO_SYMBOL_TABLE_WARNING = + "data/symfs_for_no_symbol_table_warning"; static const std::string SYMFS_FOR_READ_ELF_FILE_WARNING = "data/symfs_for_read_elf_file_warning"; static BuildId CHECK_ELF_FILE_BUILD_ID("91b1c10fdd9fe2221dfec525497637f2229bfdbb"); @@ -103,7 +105,8 @@ static BuildId CHECK_ELF_FILE_BUILD_ID("91b1c10fdd9fe2221dfec525497637f2229bfdbb static const std::string PERF_DATA_GENERATED_BY_LINUX_PERF = "generated_by_linux_perf.data"; // generated by `simpleperf record -g ls`. -static const std::string PERF_DATA_MAX_STACK_AND_PERCENT_LIMIT = "perf_test_max_stack_and_percent_limit.data"; +static const std::string PERF_DATA_MAX_STACK_AND_PERCENT_LIMIT = + "perf_test_max_stack_and_percent_limit.data"; // generated by `dd if=/dev/zero of=invalid_perf.data bs=1024 count=1`. static const std::string INVALID_PERF_DATA = "invalid_perf.data"; @@ -111,7 +114,8 @@ static const std::string INVALID_PERF_DATA = "invalid_perf.data"; // generated by recording an app. static const std::string PERF_DATA_WITH_WRONG_IP_IN_CALLCHAIN = "wrong_ip_callchain_perf.data"; -// generated by `simpleperf record --trace-offcpu --duration 2 -g ./simpleperf_runtest_run_and_sleep64`. +// generated by `simpleperf record --trace-offcpu --duration 2 -g +// ./simpleperf_runtest_run_and_sleep64`. static const std::string PERF_DATA_WITH_TRACE_OFFCPU = "perf_with_trace_offcpu.data"; // generated by `simpleperf record -g --log debug sleep 1`. @@ -129,13 +133,16 @@ static const std::string PERF_DATA_WITH_BIG_TRACE_DATA = "perf_with_big_trace_da // generated by `simpleperf record --app com.google.sample.tunnel --duration 1`. static const std::string PERF_DATA_WITH_APP_PACKAGE_NAME = "perf_with_app_package_name.data"; -static const std::string PERF_DATA_WITH_KERNEL_SYMBOLS_AVAILABLE_TRUE = "perf_with_kernel_symbols_available_true.data"; +static const std::string PERF_DATA_WITH_KERNEL_SYMBOLS_AVAILABLE_TRUE = + "perf_with_kernel_symbols_available_true.data"; -static const std::string PERF_DATA_WITH_KERNEL_SYMBOLS_AVAILABLE_FALSE = "perf_with_kernel_symbols_available_false.data"; +static const std::string PERF_DATA_WITH_KERNEL_SYMBOLS_AVAILABLE_FALSE = + "perf_with_kernel_symbols_available_false.data"; static const std::string PERF_DATA_WITH_INTERPRETER_FRAMES = "perf_with_interpreter_frames.data"; -static const std::string PERF_DATA_WITH_IP_ZERO_IN_CALLCHAIN = "perf_with_ip_zero_in_callchain.data"; +static const std::string PERF_DATA_WITH_IP_ZERO_IN_CALLCHAIN = + "perf_with_ip_zero_in_callchain.data"; // generated by `simpleperf record -e cs-etm:u ./etm_test_loop` static const std::string PERF_DATA_ETM_TEST_LOOP = "etm/perf.data"; diff --git a/simpleperf/include/simpleperf_profcollect.h b/simpleperf/include/simpleperf_profcollect.h index 507eddf2..4b825f66 100644 --- a/simpleperf/include/simpleperf_profcollect.h +++ b/simpleperf/include/simpleperf_profcollect.h @@ -23,10 +23,8 @@ namespace simpleperf { namespace etm { bool HasSupport(); -bool Record(const std::filesystem::path& output, - const std::chrono::duration<float>& duration); -bool Inject(const std::filesystem::path& traceInput, - const std::filesystem::path& output, +bool Record(const std::filesystem::path& output, const std::chrono::duration<float>& duration); +bool Inject(const std::filesystem::path& traceInput, const std::filesystem::path& output, const std::string& binaryFilter); } // namespace etm diff --git a/simpleperf/nonlinux_support/nonlinux_support.cpp b/simpleperf/nonlinux_support/nonlinux_support.cpp index b813109b..65c82d3b 100644 --- a/simpleperf/nonlinux_support/nonlinux_support.cpp +++ b/simpleperf/nonlinux_support/nonlinux_support.cpp @@ -17,9 +17,9 @@ // Add fake functions to build successfully on darwin. #include <android-base/logging.h> -#include "read_dex_file.h" -#include "environment.h" #include "OfflineUnwinder.h" +#include "environment.h" +#include "read_dex_file.h" bool GetKernelBuildId(BuildId*) { return false; diff --git a/simpleperf/perf_regs.cpp b/simpleperf/perf_regs.cpp index c238f075..3abf591d 100644 --- a/simpleperf/perf_regs.cpp +++ b/simpleperf/perf_regs.cpp @@ -18,10 +18,10 @@ #include <string.h> -#include <unordered_map> #include <android-base/logging.h> #include <android-base/stringprintf.h> #include <android-base/strings.h> +#include <unordered_map> #include "perf_event.h" @@ -83,7 +83,7 @@ uint64_t GetSupportedRegMask(ArchType arch) { switch (arch) { case ARCH_X86_32: return ((1ULL << PERF_REG_X86_32_MAX) - 1) & ~(1ULL << PERF_REG_X86_DS) & - ~(1ULL << PERF_REG_X86_ES) & ~(1ULL << PERF_REG_X86_FS) & ~(1ULL << PERF_REG_X86_GS); + ~(1ULL << PERF_REG_X86_ES) & ~(1ULL << PERF_REG_X86_FS) & ~(1ULL << PERF_REG_X86_GS); case ARCH_X86_64: return (((1ULL << PERF_REG_X86_64_MAX) - 1) & ~(1ULL << PERF_REG_X86_DS) & ~(1ULL << PERF_REG_X86_ES) & ~(1ULL << PERF_REG_X86_FS) & ~(1ULL << PERF_REG_X86_GS)); @@ -112,7 +112,9 @@ static std::unordered_map<size_t, std::string> arm_reg_map = { }; static std::unordered_map<size_t, std::string> arm64_reg_map = { - {PERF_REG_ARM64_LR, "lr"}, {PERF_REG_ARM64_SP, "sp"}, {PERF_REG_ARM64_PC, "pc"}, + {PERF_REG_ARM64_LR, "lr"}, + {PERF_REG_ARM64_SP, "sp"}, + {PERF_REG_ARM64_PC, "pc"}, }; std::string GetRegName(size_t regno, ArchType arch) { @@ -151,8 +153,7 @@ std::string GetRegName(size_t regno, ArchType arch) { } } -RegSet::RegSet(int abi, uint64_t valid_mask, const uint64_t* valid_regs) - : valid_mask(valid_mask) { +RegSet::RegSet(int abi, uint64_t valid_mask, const uint64_t* valid_regs) : valid_mask(valid_mask) { arch = (abi == PERF_SAMPLE_REGS_ABI_32) ? ScopedCurrentArch::GetCurrentArch32() : ScopedCurrentArch::GetCurrentArch(); memset(data, 0, sizeof(data)); diff --git a/simpleperf/perf_regs.h b/simpleperf/perf_regs.h index 86a12d0c..8ebbf04d 100644 --- a/simpleperf/perf_regs.h +++ b/simpleperf/perf_regs.h @@ -18,13 +18,13 @@ #define SIMPLE_PERF_PERF_REGS_H_ #if defined(USE_BIONIC_UAPI_HEADERS) -#include <uapi/asm-x86/asm/perf_regs.h> #include <uapi/asm-arm/asm/perf_regs.h> +#include <uapi/asm-x86/asm/perf_regs.h> #define perf_event_arm_regs perf_event_arm64_regs #include <uapi/asm-arm64/asm/perf_regs.h> #else -#include <asm-x86/asm/perf_regs.h> #include <asm-arm/asm/perf_regs.h> +#include <asm-x86/asm/perf_regs.h> #define perf_event_arm_regs perf_event_arm64_regs #include <asm-arm64/asm/perf_regs.h> #endif @@ -73,12 +73,8 @@ class ScopedCurrentArch { current_arch = saved_arch; current_arch32 = GetArchForAbi(saved_arch, PERF_SAMPLE_REGS_ABI_32); } - static ArchType GetCurrentArch() { - return current_arch; - } - static ArchType GetCurrentArch32() { - return current_arch32; - } + static ArchType GetCurrentArch() { return current_arch; } + static ArchType GetCurrentArch32() { return current_arch32; } private: ArchType saved_arch; diff --git a/simpleperf/profcollect.cpp b/simpleperf/profcollect.cpp index 6df3c4dc..2d2ed9a6 100644 --- a/simpleperf/profcollect.cpp +++ b/simpleperf/profcollect.cpp @@ -16,8 +16,8 @@ #include <include/simpleperf_profcollect.h> -#include "command.h" #include "ETMRecorder.h" +#include "command.h" #include "event_attr.h" #include "event_fd.h" #include "event_type.h" @@ -36,8 +36,7 @@ bool HasSupport() { return IsEventAttrSupported(CreateDefaultPerfEventAttr(*type), type->name); } -bool Record(const std::filesystem::path& output, - const std::chrono::duration<float>& duration) { +bool Record(const std::filesystem::path& output, const std::chrono::duration<float>& duration) { auto recordCmd = CreateCommandInstance("record"); std::vector<std::string> args; args.push_back("-a"); @@ -47,8 +46,7 @@ bool Record(const std::filesystem::path& output, return recordCmd->Run(args); } -bool Inject(const std::filesystem::path& traceInput, - const std::filesystem::path& output, +bool Inject(const std::filesystem::path& traceInput, const std::filesystem::path& output, const std::string& binaryFilter) { auto injectCmd = CreateCommandInstance("inject"); std::vector<std::string> args; diff --git a/simpleperf/read_apk.cpp b/simpleperf/read_apk.cpp index 651a2412..aeb2caf7 100644 --- a/simpleperf/read_apk.cpp +++ b/simpleperf/read_apk.cpp @@ -81,8 +81,7 @@ std::unique_ptr<EmbeddedElf> ApkInspector::FindElfInApkByOffsetWithoutCache( ZipEntry found_entry; std::string found_entry_name; bool result = ahelper->IterateEntries([&](ZipEntry& entry, const std::string& name) { - if (entry.method == kCompressStored && - file_offset >= static_cast<uint64_t>(entry.offset) && + if (entry.method == kCompressStored && file_offset >= static_cast<uint64_t>(entry.offset) && file_offset < static_cast<uint64_t>(entry.offset) + entry.uncompressed_length) { found = true; found_entry = entry; @@ -100,9 +99,8 @@ std::unique_ptr<EmbeddedElf> ApkInspector::FindElfInApkByOffsetWithoutCache( // Omit files that are not ELF files. return nullptr; } - return std::unique_ptr<EmbeddedElf>(new EmbeddedElf(apk_path, found_entry_name, - found_entry.offset, - found_entry.uncompressed_length)); + return std::unique_ptr<EmbeddedElf>(new EmbeddedElf( + apk_path, found_entry_name, found_entry.offset, found_entry.uncompressed_length)); } std::unique_ptr<EmbeddedElf> ApkInspector::FindElfInApkByNameWithoutCache( @@ -118,11 +116,12 @@ std::unique_ptr<EmbeddedElf> ApkInspector::FindElfInApkByNameWithoutCache( if (zentry.method != kCompressStored || zentry.compressed_length != zentry.uncompressed_length) { return nullptr; } - return std::unique_ptr<EmbeddedElf>(new EmbeddedElf(apk_path, entry_name, zentry.offset, - zentry.uncompressed_length)); + return std::unique_ptr<EmbeddedElf>( + new EmbeddedElf(apk_path, entry_name, zentry.offset, zentry.uncompressed_length)); } -// Refer file in apk in compliance with http://developer.android.com/reference/java/net/JarURLConnection.html. +// Refer file in apk in compliance with +// http://developer.android.com/reference/java/net/JarURLConnection.html. std::string GetUrlInApk(const std::string& apk_path, const std::string& elf_filename) { return apk_path + "!/" + elf_filename; } diff --git a/simpleperf/read_apk.h b/simpleperf/read_apk.h index c37366b9..2296288c 100644 --- a/simpleperf/read_apk.h +++ b/simpleperf/read_apk.h @@ -29,28 +29,20 @@ // Container for info an on ELF file embedded into an APK file class EmbeddedElf { public: - EmbeddedElf() - : entry_offset_(0) - , entry_size_(0) - { - } - - EmbeddedElf(const std::string& filepath, - const std::string& entry_name, - uint64_t entry_offset, + EmbeddedElf() : entry_offset_(0), entry_size_(0) {} + + EmbeddedElf(const std::string& filepath, const std::string& entry_name, uint64_t entry_offset, size_t entry_size) - : filepath_(filepath) - , entry_name_(entry_name) - , entry_offset_(entry_offset) - , entry_size_(entry_size) - { - } + : filepath_(filepath), + entry_name_(entry_name), + entry_offset_(entry_offset), + entry_size_(entry_size) {} // Path to APK file - const std::string &filepath() const { return filepath_; } + const std::string& filepath() const { return filepath_; } // Entry name within zip archive - const std::string &entry_name() const { return entry_name_; } + const std::string& entry_name() const { return entry_name_; } // Offset of zip entry from start of containing APK file uint64_t entry_offset() const { return entry_offset_; } @@ -59,10 +51,10 @@ class EmbeddedElf { uint32_t entry_size() const { return entry_size_; } private: - std::string filepath_; // containing APK path - std::string entry_name_; // name of entry in zip index of embedded elf file - uint64_t entry_offset_; // offset of ELF from start of containing APK file - uint32_t entry_size_; // size of ELF file in zip + std::string filepath_; // containing APK path + std::string entry_name_; // name of entry in zip index of embedded elf file + uint64_t entry_offset_; // offset of ELF from start of containing APK file + uint32_t entry_size_; // size of ELF file in zip }; // APK inspector helper class @@ -75,8 +67,8 @@ class ApkInspector { private: static std::unique_ptr<EmbeddedElf> FindElfInApkByOffsetWithoutCache(const std::string& apk_path, uint64_t file_offset); - static std::unique_ptr<EmbeddedElf> FindElfInApkByNameWithoutCache( - const std::string& apk_path, const std::string& entry_name); + static std::unique_ptr<EmbeddedElf> FindElfInApkByNameWithoutCache(const std::string& apk_path, + const std::string& entry_name); struct ApkNode { // Map from entry_offset to EmbeddedElf. diff --git a/simpleperf/read_apk_test.cpp b/simpleperf/read_apk_test.cpp index d9665ac6..80b58cd7 100644 --- a/simpleperf/read_apk_test.cpp +++ b/simpleperf/read_apk_test.cpp @@ -26,8 +26,8 @@ TEST(read_apk, FindElfInApkByOffset) { ASSERT_TRUE(inspector.FindElfInApkByOffset(GetTestData(APK_FILE), 0) == nullptr); // Test if we can read the EmbeddedElf using an offset inside its [offset, offset+size] range // in the apk file. - EmbeddedElf* ee = inspector.FindElfInApkByOffset(GetTestData(APK_FILE), - NATIVELIB_OFFSET_IN_APK + NATIVELIB_SIZE_IN_APK / 2); + EmbeddedElf* ee = inspector.FindElfInApkByOffset( + GetTestData(APK_FILE), NATIVELIB_OFFSET_IN_APK + NATIVELIB_SIZE_IN_APK / 2); ASSERT_TRUE(ee != nullptr); ASSERT_EQ(NATIVELIB_IN_APK, ee->entry_name()); ASSERT_EQ(NATIVELIB_OFFSET_IN_APK, ee->entry_offset()); @@ -46,27 +46,35 @@ TEST(read_apk, FindElfInApkByName) { TEST(read_apk, ParseExtractedInMemoryPath) { std::string zip_path; std::string entry_name; - ASSERT_TRUE(ParseExtractedInMemoryPath("[anon:dalvik-classes.dex extracted in memory from " + ASSERT_TRUE(ParseExtractedInMemoryPath( + "[anon:dalvik-classes.dex extracted in memory from " "/data/app/com.example.simpleperf.simpleperfexamplepurejava-HZK6bPs3Z9SDT3a-tqmasA==/" - "base.apk]", &zip_path, &entry_name)); - ASSERT_EQ(zip_path, "/data/app/com.example.simpleperf.simpleperfexamplepurejava" + "base.apk]", + &zip_path, &entry_name)); + ASSERT_EQ(zip_path, + "/data/app/com.example.simpleperf.simpleperfexamplepurejava" "-HZK6bPs3Z9SDT3a-tqmasA==/base.apk"); ASSERT_EQ(entry_name, "classes.dex"); - ASSERT_FALSE(ParseExtractedInMemoryPath("[anon:dalvik-thread local mark stack]", - &zip_path, &entry_name)); - ASSERT_TRUE(ParseExtractedInMemoryPath("/dev/ashmem/dalvik-classes.dex extracted in memory from " + ASSERT_FALSE( + ParseExtractedInMemoryPath("[anon:dalvik-thread local mark stack]", &zip_path, &entry_name)); + ASSERT_TRUE(ParseExtractedInMemoryPath( + "/dev/ashmem/dalvik-classes.dex extracted in memory from " "/data/app/com.example.simpleperf.simpleperfexamplepurejava-HZK6bPs3Z9SDT3a-tqmasA==/base.apk" - " (deleted)", &zip_path, &entry_name)); - ASSERT_EQ(zip_path, "/data/app/com.example.simpleperf.simpleperfexamplepurejava" + " (deleted)", + &zip_path, &entry_name)); + ASSERT_EQ(zip_path, + "/data/app/com.example.simpleperf.simpleperfexamplepurejava" "-HZK6bPs3Z9SDT3a-tqmasA==/base.apk"); ASSERT_EQ(entry_name, "classes.dex"); ASSERT_FALSE(ParseExtractedInMemoryPath("/dev/ashmem/dalvik-thread local mark stack (deleted)", &zip_path, &entry_name)); // Parse multidex file. - ASSERT_TRUE(ParseExtractedInMemoryPath("/dev/ashmem/dalvik-classes2.dex extracted in memory from " + ASSERT_TRUE(ParseExtractedInMemoryPath( + "/dev/ashmem/dalvik-classes2.dex extracted in memory from " "/data/app/getxml.test.com.testgetxml-knxI11ZXLT-OVBs9X9bSkw==/base.apk!classes2.dex " - "(deleted)", &zip_path, &entry_name)); + "(deleted)", + &zip_path, &entry_name)); ASSERT_EQ(zip_path, "/data/app/getxml.test.com.testgetxml-knxI11ZXLT-OVBs9X9bSkw==/base.apk"); ASSERT_EQ(entry_name, "classes2.dex"); } diff --git a/simpleperf/read_dex_file.cpp b/simpleperf/read_dex_file.cpp index c9eed8fb..5644f7fc 100644 --- a/simpleperf/read_dex_file.cpp +++ b/simpleperf/read_dex_file.cpp @@ -83,16 +83,16 @@ bool ReadSymbolsFromDexFile(const std::string& file_path, if (fd == -1) { return false; } - return ReadSymbols( - dex_file_offsets, symbols, [&](uint64_t offset) -> std::unique_ptr<art_api::dex::DexFile> { - std::string error_msg; - std::unique_ptr<art_api::dex::DexFile> dex_file = - art_api::dex::DexFile::OpenFromFd(fd, offset, file_path, &error_msg); - if (dex_file == nullptr) { - LOG(WARNING) << "Failed to read dex file symbols from '" << file_path - << "': " << error_msg; - return nullptr; - } - return dex_file; - }); + return ReadSymbols(dex_file_offsets, symbols, + [&](uint64_t offset) -> std::unique_ptr<art_api::dex::DexFile> { + std::string error_msg; + std::unique_ptr<art_api::dex::DexFile> dex_file = + art_api::dex::DexFile::OpenFromFd(fd, offset, file_path, &error_msg); + if (dex_file == nullptr) { + LOG(WARNING) << "Failed to read dex file symbols from '" << file_path + << "': " << error_msg; + return nullptr; + } + return dex_file; + }); } diff --git a/simpleperf/read_elf.cpp b/simpleperf/read_elf.cpp index b4a7d122..1e1ec619 100644 --- a/simpleperf/read_elf.cpp +++ b/simpleperf/read_elf.cpp @@ -191,13 +191,12 @@ bool IsArmMappingSymbol(const char* name) { // Mapping symbols in arm, which are described in "ELF for ARM Architecture" and // "ELF for ARM 64-bit Architecture". The regular expression to match mapping symbol // is ^\$(a|d|t|x)(\..*)?$ - return name[0] == '$' && strchr("adtx", name[1]) != nullptr && (name[2] == '\0' || name[2] == '.'); + return name[0] == '$' && strchr("adtx", name[1]) != nullptr && + (name[2] == '\0' || name[2] == '.'); } -void ReadSymbolTable(llvm::object::symbol_iterator sym_begin, - llvm::object::symbol_iterator sym_end, - const std::function<void(const ElfFileSymbol&)>& callback, - bool is_arm, +void ReadSymbolTable(llvm::object::symbol_iterator sym_begin, llvm::object::symbol_iterator sym_end, + const std::function<void(const ElfFileSymbol&)>& callback, bool is_arm, const llvm::object::section_iterator& section_end) { for (; sym_begin != sym_end; ++sym_begin) { ElfFileSymbol symbol; @@ -288,8 +287,8 @@ void AddSymbolForPltSection(const llvm::object::ELFObjectFile<ELFT>* elf, } template <class ELFT> -void CheckSymbolSections(const llvm::object::ELFObjectFile<ELFT>* elf, - bool* has_symtab, bool* has_dynsym) { +void CheckSymbolSections(const llvm::object::ELFObjectFile<ELFT>* elf, bool* has_symtab, + bool* has_dynsym) { *has_symtab = false; *has_dynsym = false; for (auto it = elf->section_begin(); it != elf->section_end(); ++it) { @@ -318,13 +317,9 @@ class ElfFileImpl<llvm::object::ELFObjectFile<ELFT>> : public ElfFile { ElfFileImpl(BinaryWrapper&& wrapper, const llvm::object::ELFObjectFile<ELFT>* elf_obj) : wrapper_(std::move(wrapper)), elf_obj_(elf_obj), elf_(elf_obj->getELFFile()) {} - bool Is64Bit() override { - return elf_->getHeader()->getFileClass() == llvm::ELF::ELFCLASS64; - } + bool Is64Bit() override { return elf_->getHeader()->getFileClass() == llvm::ELF::ELFCLASS64; } - llvm::MemoryBuffer* GetMemoryBuffer() override { - return wrapper_.buffer.get(); - } + llvm::MemoryBuffer* GetMemoryBuffer() override { return wrapper_.buffer.get(); } std::vector<ElfSegment> GetProgramHeader() override { auto program_headers = elf_->program_headers(); @@ -539,21 +534,20 @@ std::unique_ptr<ElfFile> ElfFile::Open(const char* data, size_t size, ElfStatus* } // namespace simpleperf - // LLVM libraries uses ncurses library, but that isn't needed by simpleperf. // So support a naive implementation to avoid depending on ncurses. -__attribute__((weak)) extern "C" int setupterm(char *, int, int *) { +__attribute__((weak)) extern "C" int setupterm(char*, int, int*) { return -1; } -__attribute__((weak)) extern "C" struct term *set_curterm(struct term *) { +__attribute__((weak)) extern "C" struct term* set_curterm(struct term*) { return nullptr; } -__attribute__((weak)) extern "C" int del_curterm(struct term *) { +__attribute__((weak)) extern "C" int del_curterm(struct term*) { return -1; } -__attribute__((weak)) extern "C" int tigetnum(char *) { +__attribute__((weak)) extern "C" int tigetnum(char*) { return -1; } diff --git a/simpleperf/read_elf.h b/simpleperf/read_elf.h index d649ce98..ed2aad2e 100644 --- a/simpleperf/read_elf.h +++ b/simpleperf/read_elf.h @@ -52,8 +52,7 @@ struct ElfFileSymbol { bool is_in_text_section; std::string name; - ElfFileSymbol() : vaddr(0), len(0), is_func(false), is_label(false), is_in_text_section(false) { - } + ElfFileSymbol() : vaddr(0), len(0), is_func(false), is_label(false), is_in_text_section(false) {} }; namespace llvm { diff --git a/simpleperf/read_symbol_map.cpp b/simpleperf/read_symbol_map.cpp index b80602da..f40fc2e0 100644 --- a/simpleperf/read_symbol_map.cpp +++ b/simpleperf/read_symbol_map.cpp @@ -92,7 +92,7 @@ void ReadSymbol(std::string_view content, std::vector<Symbol>* symbols) { std::vector<Symbol> ReadSymbolMapFromString(const std::string& content) { std::vector<Symbol> symbols; - for (size_t begin = 0; ; ) { + for (size_t begin = 0;;) { size_t end = content.find_first_of("\n\r", begin); if (end == content.npos) { diff --git a/simpleperf/read_symbol_map_test.cpp b/simpleperf/read_symbol_map_test.cpp index e6db3081..1f668719 100644 --- a/simpleperf/read_symbol_map_test.cpp +++ b/simpleperf/read_symbol_map_test.cpp @@ -28,16 +28,17 @@ namespace simpleperf { namespace { TEST(read_symbol_map, smoke) { - std::string content("\n" // skip - " 0x2000 0x20 two \n" - "0x4000\n" // skip - " 0x40 four\n" // skip - "0x1000 0x10 one\n" - " \n" // skip - "0x5000 0x50five\n" // skip - " skip this line\n" // skip - "0x6000 0x60 six six\n" // skip - "0x3000 48 three \n"); + std::string content( + "\n" // skip + " 0x2000 0x20 two \n" + "0x4000\n" // skip + " 0x40 four\n" // skip + "0x1000 0x10 one\n" + " \n" // skip + "0x5000 0x50five\n" // skip + " skip this line\n" // skip + "0x6000 0x60 six six\n" // skip + "0x3000 48 three \n"); auto symbols = ReadSymbolMapFromString(content); diff --git a/simpleperf/record.cpp b/simpleperf/record.cpp index 3ce99acc..c4fe0ae2 100644 --- a/simpleperf/record.cpp +++ b/simpleperf/record.cpp @@ -23,8 +23,8 @@ #include <android-base/logging.h> #include <android-base/stringprintf.h> -#include "dso.h" #include "OfflineUnwinder.h" +#include "dso.h" #include "perf_regs.h" #include "tracing.h" #include "utils.h" @@ -69,7 +69,9 @@ void MoveToBinaryFormat(const RecordHeader& data, char*& p) { data.MoveToBinaryFormat(p); } -SampleId::SampleId() { memset(this, 0, sizeof(SampleId)); } +SampleId::SampleId() { + memset(this, 0, sizeof(SampleId)); +} // Return sample_id size in binary format. size_t SampleId::CreateContent(const perf_event_attr& attr, uint64_t event_id) { @@ -80,8 +82,7 @@ size_t SampleId::CreateContent(const perf_event_attr& attr, uint64_t event_id) { return Size(); } -void SampleId::ReadFromBinaryFormat(const perf_event_attr& attr, const char* p, - const char* end) { +void SampleId::ReadFromBinaryFormat(const perf_event_attr& attr, const char* p, const char* end) { sample_id_all = attr.sample_id_all; sample_type = attr.sample_type; if (sample_id_all) { @@ -133,8 +134,7 @@ void SampleId::WriteToBinaryFormat(char*& p) const { void SampleId::Dump(size_t indent) const { if (sample_id_all) { if (sample_type & PERF_SAMPLE_TID) { - PrintIndented(indent, "sample_id: pid %u, tid %u\n", tid_data.pid, - tid_data.tid); + PrintIndented(indent, "sample_id: pid %u, tid %u\n", tid_data.pid, tid_data.tid); } if (sample_type & PERF_SAMPLE_TIME) { PrintIndented(indent, "sample_id: time %" PRId64 "\n", time_data.time); @@ -143,12 +143,10 @@ void SampleId::Dump(size_t indent) const { PrintIndented(indent, "sample_id: id %" PRId64 "\n", id_data.id); } if (sample_type & PERF_SAMPLE_STREAM_ID) { - PrintIndented(indent, "sample_id: stream_id %" PRId64 "\n", - stream_id_data.stream_id); + PrintIndented(indent, "sample_id: stream_id %" PRId64 "\n", stream_id_data.stream_id); } if (sample_type & PERF_SAMPLE_CPU) { - PrintIndented(indent, "sample_id: cpu %u, res %u\n", cpu_data.cpu, - cpu_data.res); + PrintIndented(indent, "sample_id: cpu %u, res %u\n", cpu_data.cpu, cpu_data.res); } } } @@ -194,9 +192,15 @@ void Record::Dump(size_t indent) const { sample_id.Dump(indent + 1); } -uint64_t Record::Timestamp() const { return sample_id.time_data.time; } -uint32_t Record::Cpu() const { return sample_id.cpu_data.cpu; } -uint64_t Record::Id() const { return sample_id.id_data.id; } +uint64_t Record::Timestamp() const { + return sample_id.time_data.time; +} +uint32_t Record::Cpu() const { + return sample_id.cpu_data.cpu; +} +uint64_t Record::Id() const { + return sample_id.id_data.id; +} void Record::UpdateBinary(char* new_binary) { if (own_binary_) { @@ -217,12 +221,10 @@ MmapRecord::MmapRecord(const perf_event_attr& attr, char* p) : Record(p) { sample_id.ReadFromBinaryFormat(attr, p, end); } -MmapRecord::MmapRecord(const perf_event_attr& attr, bool in_kernel, - uint32_t pid, uint32_t tid, uint64_t addr, uint64_t len, - uint64_t pgoff, const std::string& filename, +MmapRecord::MmapRecord(const perf_event_attr& attr, bool in_kernel, uint32_t pid, uint32_t tid, + uint64_t addr, uint64_t len, uint64_t pgoff, const std::string& filename, uint64_t event_id, uint64_t time) { - SetTypeAndMisc(PERF_RECORD_MMAP, - in_kernel ? PERF_RECORD_MISC_KERNEL : PERF_RECORD_MISC_USER); + SetTypeAndMisc(PERF_RECORD_MMAP, in_kernel ? PERF_RECORD_MISC_KERNEL : PERF_RECORD_MISC_USER); sample_id.CreateContent(attr, event_id); sample_id.time_data.time = time; MmapRecordDataType data; @@ -234,10 +236,8 @@ MmapRecord::MmapRecord(const perf_event_attr& attr, bool in_kernel, SetDataAndFilename(data, filename); } -void MmapRecord::SetDataAndFilename(const MmapRecordDataType& data, - const std::string& filename) { - SetSize(header_size() + sizeof(data) + Align(filename.size() + 1, 8) + - sample_id.Size()); +void MmapRecord::SetDataAndFilename(const MmapRecordDataType& data, const std::string& filename) { + SetSize(header_size() + sizeof(data) + Align(filename.size() + 1, 8) + sample_id.Size()); char* new_binary = new char[size()]; char* p = new_binary; MoveToBinaryFormat(header, p); @@ -251,11 +251,9 @@ void MmapRecord::SetDataAndFilename(const MmapRecordDataType& data, } void MmapRecord::DumpData(size_t indent) const { - PrintIndented(indent, - "pid %u, tid %u, addr 0x%" PRIx64 ", len 0x%" PRIx64 "\n", - data->pid, data->tid, data->addr, data->len); - PrintIndented(indent, "pgoff 0x%" PRIx64 ", filename %s\n", data->pgoff, - filename); + PrintIndented(indent, "pid %u, tid %u, addr 0x%" PRIx64 ", len 0x%" PRIx64 "\n", data->pid, + data->tid, data->addr, data->len); + PrintIndented(indent, "pgoff 0x%" PRIx64 ", filename %s\n", data->pgoff, filename); } Mmap2Record::Mmap2Record(const perf_event_attr& attr, char* p) : Record(p) { @@ -285,10 +283,8 @@ Mmap2Record::Mmap2Record(const perf_event_attr& attr, bool in_kernel, uint32_t p SetDataAndFilename(data, filename); } -void Mmap2Record::SetDataAndFilename(const Mmap2RecordDataType& data, - const std::string& filename) { - SetSize(header_size() + sizeof(data) + Align(filename.size() + 1, 8) + - sample_id.Size()); +void Mmap2Record::SetDataAndFilename(const Mmap2RecordDataType& data, const std::string& filename) { + SetSize(header_size() + sizeof(data) + Align(filename.size() + 1, 8) + sample_id.Size()); char* new_binary = new char[size()]; char* p = new_binary; MoveToBinaryFormat(header, p); @@ -302,15 +298,12 @@ void Mmap2Record::SetDataAndFilename(const Mmap2RecordDataType& data, } void Mmap2Record::DumpData(size_t indent) const { - PrintIndented(indent, - "pid %u, tid %u, addr 0x%" PRIx64 ", len 0x%" PRIx64 "\n", - data->pid, data->tid, data->addr, data->len); - PrintIndented(indent, "pgoff 0x%" PRIx64 ", maj %u, min %u, ino %" PRId64 - ", ino_generation %" PRIu64 "\n", - data->pgoff, data->maj, data->min, data->ino, - data->ino_generation); - PrintIndented(indent, "prot %u, flags %u, filename %s\n", data->prot, - data->flags, filename); + PrintIndented(indent, "pid %u, tid %u, addr 0x%" PRIx64 ", len 0x%" PRIx64 "\n", data->pid, + data->tid, data->addr, data->len); + PrintIndented( + indent, "pgoff 0x%" PRIx64 ", maj %u, min %u, ino %" PRId64 ", ino_generation %" PRIu64 "\n", + data->pgoff, data->maj, data->min, data->ino, data->ino_generation); + PrintIndented(indent, "prot %u, flags %u, filename %s\n", data->prot, data->flags, filename); } CommRecord::CommRecord(const perf_event_attr& attr, char* p) : Record(p) { @@ -332,8 +325,7 @@ CommRecord::CommRecord(const perf_event_attr& attr, uint32_t pid, uint32_t tid, data.tid = tid; size_t sample_id_size = sample_id.CreateContent(attr, event_id); sample_id.time_data.time = time; - SetSize(header_size() + sizeof(data) + Align(comm.size() + 1, 8) + - sample_id_size); + SetSize(header_size() + sizeof(data) + Align(comm.size() + 1, 8) + sample_id_size); char* new_binary = new char[size()]; char* p = new_binary; MoveToBinaryFormat(header, p); @@ -370,12 +362,10 @@ void CommRecord::SetCommandName(const std::string& name) { } void CommRecord::DumpData(size_t indent) const { - PrintIndented(indent, "pid %u, tid %u, comm %s\n", data->pid, data->tid, - comm); + PrintIndented(indent, "pid %u, tid %u, comm %s\n", data->pid, data->tid, comm); } -ExitOrForkRecord::ExitOrForkRecord(const perf_event_attr& attr, char* p) - : Record(p) { +ExitOrForkRecord::ExitOrForkRecord(const perf_event_attr& attr, char* p) : Record(p) { const char* end = p + size(); p += header_size(); data = reinterpret_cast<const ExitOrForkRecordDataType*>(p); @@ -385,12 +375,12 @@ ExitOrForkRecord::ExitOrForkRecord(const perf_event_attr& attr, char* p) } void ExitOrForkRecord::DumpData(size_t indent) const { - PrintIndented(indent, "pid %u, ppid %u, tid %u, ptid %u\n", data->pid, - data->ppid, data->tid, data->ptid); + PrintIndented(indent, "pid %u, ppid %u, tid %u, ptid %u\n", data->pid, data->ppid, data->tid, + data->ptid); } -ForkRecord::ForkRecord(const perf_event_attr& attr, uint32_t pid, uint32_t tid, - uint32_t ppid, uint32_t ptid, uint64_t event_id) { +ForkRecord::ForkRecord(const perf_event_attr& attr, uint32_t pid, uint32_t tid, uint32_t ppid, + uint32_t ptid, uint64_t event_id) { SetTypeAndMisc(PERF_RECORD_FORK, 0); ExitOrForkRecordDataType data; data.pid = pid; @@ -500,17 +490,16 @@ SampleRecord::SampleRecord(const perf_event_attr& attr, char* p) : Record(p) { } } -SampleRecord::SampleRecord(const perf_event_attr& attr, uint64_t id, - uint64_t ip, uint32_t pid, uint32_t tid, - uint64_t time, uint32_t cpu, uint64_t period, +SampleRecord::SampleRecord(const perf_event_attr& attr, uint64_t id, uint64_t ip, uint32_t pid, + uint32_t tid, uint64_t time, uint32_t cpu, uint64_t period, const std::vector<uint64_t>& ips, const std::vector<char>& stack, uint64_t dyn_stack_size) { SetTypeAndMisc(PERF_RECORD_SAMPLE, PERF_RECORD_MISC_USER); sample_type = attr.sample_type; - CHECK_EQ(0u, sample_type & ~(PERF_SAMPLE_IP | PERF_SAMPLE_TID - | PERF_SAMPLE_TIME | PERF_SAMPLE_ID | PERF_SAMPLE_CPU - | PERF_SAMPLE_PERIOD | PERF_SAMPLE_CALLCHAIN | PERF_SAMPLE_REGS_USER - | PERF_SAMPLE_STACK_USER)); + CHECK_EQ(0u, + sample_type & ~(PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_TIME | PERF_SAMPLE_ID | + PERF_SAMPLE_CPU | PERF_SAMPLE_PERIOD | PERF_SAMPLE_CALLCHAIN | + PERF_SAMPLE_REGS_USER | PERF_SAMPLE_STACK_USER)); ip_data.ip = ip; tid_data.pid = pid; tid_data.tid = tid; @@ -601,8 +590,8 @@ SampleRecord::SampleRecord(const perf_event_attr& attr, uint64_t id, void SampleRecord::ReplaceRegAndStackWithCallChain(const std::vector<uint64_t>& ips) { uint32_t size_added_in_callchain = sizeof(uint64_t) * (ips.size() + 1); - uint32_t size_reduced_in_reg_stack = regs_user_data.reg_nr * sizeof(uint64_t) + - stack_user_data.size + sizeof(uint64_t); + uint32_t size_reduced_in_reg_stack = + regs_user_data.reg_nr * sizeof(uint64_t) + stack_user_data.size + sizeof(uint64_t); uint32_t new_size = size() + size_added_in_callchain - size_reduced_in_reg_stack; BuildBinaryWithNewCallChain(new_size, ips); } @@ -662,8 +651,8 @@ void SampleRecord::UpdateUserCallChain(const std::vector<uint64_t>& user_ips) { // Callchain isn't changed. return; } - size_t new_size = size() + (kernel_ip_count + 1 + user_ips.size() - callchain_data.ip_nr) * - sizeof(uint64_t); + size_t new_size = + size() + (kernel_ip_count + 1 + user_ips.size() - callchain_data.ip_nr) * sizeof(uint64_t); callchain_data.ip_nr = kernel_ip_count; BuildBinaryWithNewCallChain(new_size, user_ips); } @@ -716,7 +705,7 @@ void SampleRecord::BuildBinaryWithNewCallChain(uint32_t new_size, callchain_data.ip_nr += 1 + ips.size(); *--p64 = callchain_data.ip_nr; CHECK_EQ(callchain_pos, static_cast<size_t>(reinterpret_cast<char*>(p64) - new_binary)) - << "record time " << time_data.time; + << "record time " << time_data.time; if (new_binary != binary_) { UpdateBinary(new_binary); } @@ -763,12 +752,10 @@ void SampleRecord::DumpData(size_t indent) const { } } if (sample_type & PERF_SAMPLE_BRANCH_STACK) { - PrintIndented(indent, "branch_stack nr=%" PRIu64 "\n", - branch_stack_data.stack_nr); + PrintIndented(indent, "branch_stack nr=%" PRIu64 "\n", branch_stack_data.stack_nr); for (uint64_t i = 0; i < branch_stack_data.stack_nr; ++i) { auto& item = branch_stack_data.stack[i]; - PrintIndented(indent + 1, "from 0x%" PRIx64 ", to 0x%" PRIx64 - ", flags 0x%" PRIx64 "\n", + PrintIndented(indent + 1, "from 0x%" PRIx64 ", to 0x%" PRIx64 ", flags 0x%" PRIx64 "\n", item.from, item.to, item.flags); } } @@ -776,16 +763,15 @@ void SampleRecord::DumpData(size_t indent) const { PrintIndented(indent, "user regs: abi=%" PRId64 "\n", regs_user_data.abi); for (size_t i = 0, pos = 0; i < 64; ++i) { if ((regs_user_data.reg_mask >> i) & 1) { - PrintIndented( - indent + 1, "reg (%s) 0x%016" PRIx64 "\n", - GetRegName(i, ScopedCurrentArch::GetCurrentArch()).c_str(), - regs_user_data.regs[pos++]); + PrintIndented(indent + 1, "reg (%s) 0x%016" PRIx64 "\n", + GetRegName(i, ScopedCurrentArch::GetCurrentArch()).c_str(), + regs_user_data.regs[pos++]); } } } if (sample_type & PERF_SAMPLE_STACK_USER) { - PrintIndented(indent, "user stack: size %zu dyn_size %" PRIu64 "\n", - stack_user_data.size, stack_user_data.dyn_size); + PrintIndented(indent, "user stack: size %zu dyn_size %" PRIu64 "\n", stack_user_data.size, + stack_user_data.dyn_size); const uint64_t* p = reinterpret_cast<const uint64_t*>(stack_user_data.data); const uint64_t* end = p + (stack_user_data.size / sizeof(uint64_t)); while (p < end) { @@ -799,16 +785,22 @@ void SampleRecord::DumpData(size_t indent) const { } } -uint64_t SampleRecord::Timestamp() const { return time_data.time; } -uint32_t SampleRecord::Cpu() const { return cpu_data.cpu; } -uint64_t SampleRecord::Id() const { return id_data.id; } +uint64_t SampleRecord::Timestamp() const { + return time_data.time; +} +uint32_t SampleRecord::Cpu() const { + return cpu_data.cpu; +} +uint64_t SampleRecord::Id() const { + return id_data.id; +} void SampleRecord::AdjustCallChainGeneratedByKernel() { // The kernel stores return addrs in the callchain, but we want the addrs of call instructions // along the callchain. uint64_t* ips = callchain_data.ips; - uint64_t context = header.misc == PERF_RECORD_MISC_KERNEL ? PERF_CONTEXT_KERNEL - : PERF_CONTEXT_USER; + uint64_t context = + header.misc == PERF_RECORD_MISC_KERNEL ? PERF_CONTEXT_KERNEL : PERF_CONTEXT_USER; bool first_frame = true; for (size_t i = 0; i < callchain_data.ip_nr; ++i) { if (ips[i] < PERF_CONTEXT_MAX) { @@ -821,7 +813,7 @@ void SampleRecord::AdjustCallChainGeneratedByKernel() { } else { // Here we want to change the return addr to the addr of the previous instruction. We // don't need to find the exact start addr of the previous instruction. A location in - // [start_addr_of_call_inst, start_addr_of_next_inst) is enough. + // [start_addr_of_call_inst, start_addr_of_next_inst) is enough. #if defined(__arm__) || defined(__aarch64__) // If we are built for arm/aarch64, this may be a callchain of thumb code. For thumb code, // the real instruction addr is (ip & ~1), and ip - 2 can used to hit the address range @@ -910,12 +902,10 @@ void BuildIdRecord::DumpData(size_t indent) const { BuildIdRecord::BuildIdRecord(bool in_kernel, pid_t pid, const BuildId& build_id, const std::string& filename) { - SetTypeAndMisc(PERF_RECORD_BUILD_ID, - in_kernel ? PERF_RECORD_MISC_KERNEL : PERF_RECORD_MISC_USER); + SetTypeAndMisc(PERF_RECORD_BUILD_ID, in_kernel ? PERF_RECORD_MISC_KERNEL : PERF_RECORD_MISC_USER); this->pid = pid; this->build_id = build_id; - SetSize(header_size() + sizeof(pid) + Align(build_id.Size(), 8) + - Align(filename.size() + 1, 64)); + SetSize(header_size() + sizeof(pid) + Align(build_id.Size(), 8) + Align(filename.size() + 1, 64)); char* new_binary = new char[size()]; char* p = new_binary; MoveToBinaryFormat(header, p); @@ -1021,8 +1011,7 @@ KernelSymbolRecord::KernelSymbolRecord(char* p) : Record(p) { } void KernelSymbolRecord::DumpData(size_t indent) const { - PrintIndented(indent, "kallsyms: %s\n", - std::string(kallsyms, kallsyms + kallsyms_size).c_str()); + PrintIndented(indent, "kallsyms: %s\n", std::string(kallsyms, kallsyms + kallsyms_size).c_str()); } KernelSymbolRecord::KernelSymbolRecord(const std::string& kallsyms) { @@ -1049,8 +1038,8 @@ DsoRecord::DsoRecord(char* p) : Record(p) { CHECK_EQ(p, end); } -DsoRecord::DsoRecord(uint64_t dso_type, uint64_t dso_id, - const std::string& dso_name, uint64_t min_vaddr) { +DsoRecord::DsoRecord(uint64_t dso_type, uint64_t dso_id, const std::string& dso_name, + uint64_t min_vaddr) { SetTypeAndMisc(SIMPLE_PERF_RECORD_DSO, 0); this->dso_type = dso_type; this->dso_id = dso_id; @@ -1086,8 +1075,7 @@ SymbolRecord::SymbolRecord(char* p) : Record(p) { CHECK_EQ(p, end); } -SymbolRecord::SymbolRecord(uint64_t addr, uint64_t len, const std::string& name, - uint64_t dso_id) { +SymbolRecord::SymbolRecord(uint64_t addr, uint64_t len, const std::string& name, uint64_t dso_id) { SetTypeAndMisc(SIMPLE_PERF_RECORD_SYMBOL, 0); this->addr = addr; this->len = len; @@ -1163,10 +1151,8 @@ EventIdRecord::EventIdRecord(const std::vector<uint64_t>& data) { void EventIdRecord::DumpData(size_t indent) const { PrintIndented(indent, "count: %" PRIu64 "\n", count); for (size_t i = 0; i < count; ++i) { - PrintIndented(indent, "attr_id[%" PRIu64 "]: %" PRIu64 "\n", i, - data[i].attr_id); - PrintIndented(indent, "event_id[%" PRIu64 "]: %" PRIu64 "\n", i, - data[i].event_id); + PrintIndented(indent, "attr_id[%" PRIu64 "]: %" PRIu64 "\n", i, data[i].attr_id); + PrintIndented(indent, "event_id[%" PRIu64 "]: %" PRIu64 "\n", i, data[i].event_id); } } @@ -1214,10 +1200,18 @@ CallChainRecord::CallChainRecord(pid_t pid, pid_t tid, CallChainJoiner::ChainTyp void CallChainRecord::DumpData(size_t indent) const { const char* type_name = ""; switch (chain_type) { - case CallChainJoiner::ORIGINAL_OFFLINE: type_name = "ORIGINAL_OFFLINE"; break; - case CallChainJoiner::ORIGINAL_REMOTE: type_name = "ORIGINAL_REMOTE"; break; - case CallChainJoiner::JOINED_OFFLINE: type_name = "JOINED_OFFLINE"; break; - case CallChainJoiner::JOINED_REMOTE: type_name = "JOINED_REMOTE"; break; + case CallChainJoiner::ORIGINAL_OFFLINE: + type_name = "ORIGINAL_OFFLINE"; + break; + case CallChainJoiner::ORIGINAL_REMOTE: + type_name = "ORIGINAL_REMOTE"; + break; + case CallChainJoiner::JOINED_OFFLINE: + type_name = "JOINED_OFFLINE"; + break; + case CallChainJoiner::JOINED_REMOTE: + type_name = "JOINED_REMOTE"; + break; } PrintIndented(indent, "pid %u\n", pid); PrintIndented(indent, "tid %u\n", tid); @@ -1337,8 +1331,8 @@ std::unique_ptr<Record> ReadRecordFromBuffer(const perf_event_attr& attr, uint32 } } -std::unique_ptr<Record> ReadRecordFromOwnedBuffer(const perf_event_attr& attr, - uint32_t type, char* p) { +std::unique_ptr<Record> ReadRecordFromOwnedBuffer(const perf_event_attr& attr, uint32_t type, + char* p) { std::unique_ptr<Record> record = ReadRecordFromBuffer(attr, type, p); if (record != nullptr) { record->OwnBinary(); @@ -1348,8 +1342,8 @@ std::unique_ptr<Record> ReadRecordFromOwnedBuffer(const perf_event_attr& attr, return record; } -std::vector<std::unique_ptr<Record>> ReadRecordsFromBuffer( - const perf_event_attr& attr, char* buf, size_t buf_size) { +std::vector<std::unique_ptr<Record>> ReadRecordsFromBuffer(const perf_event_attr& attr, char* buf, + size_t buf_size) { std::vector<std::unique_ptr<Record>> result; char* p = buf; char* end = buf + buf_size; diff --git a/simpleperf/record.h b/simpleperf/record.h index 163d5208..fbeec0d3 100644 --- a/simpleperf/record.h +++ b/simpleperf/record.h @@ -27,9 +27,9 @@ #include <android-base/logging.h> -#include "build_id.h" #include "CallChainJoiner.h" #include "OfflineUnwinder.h" +#include "build_id.h" #include "perf_event.h" enum user_record_type { @@ -66,9 +66,8 @@ struct simpleperf_record_header { uint16_t size0; }; -static_assert( - sizeof(simpleperf_record_header) == sizeof(perf_event_header), - "simpleperf_record_header should have the same size as perf_event_header"); +static_assert(sizeof(simpleperf_record_header) == sizeof(perf_event_header), + "simpleperf_record_header should have the same size as perf_event_header"); struct PerfSampleIpType { uint64_t ip; @@ -184,12 +183,11 @@ struct SampleId { bool sample_id_all; uint64_t sample_type; - PerfSampleTidType tid_data; // Valid if sample_id_all && PERF_SAMPLE_TID. - PerfSampleTimeType time_data; // Valid if sample_id_all && PERF_SAMPLE_TIME. - PerfSampleIdType id_data; // Valid if sample_id_all && PERF_SAMPLE_ID. - PerfSampleStreamIdType - stream_id_data; // Valid if sample_id_all && PERF_SAMPLE_STREAM_ID. - PerfSampleCpuType cpu_data; // Valid if sample_id_all && PERF_SAMPLE_CPU. + PerfSampleTidType tid_data; // Valid if sample_id_all && PERF_SAMPLE_TID. + PerfSampleTimeType time_data; // Valid if sample_id_all && PERF_SAMPLE_TIME. + PerfSampleIdType id_data; // Valid if sample_id_all && PERF_SAMPLE_ID. + PerfSampleStreamIdType stream_id_data; // Valid if sample_id_all && PERF_SAMPLE_STREAM_ID. + PerfSampleCpuType cpu_data; // Valid if sample_id_all && PERF_SAMPLE_CPU. SampleId(); @@ -197,8 +195,7 @@ struct SampleId { size_t CreateContent(const perf_event_attr& attr, uint64_t event_id); // Parse sample_id from binary format in the buffer pointed by p. - void ReadFromBinaryFormat(const perf_event_attr& attr, const char* p, - const char* end); + void ReadFromBinaryFormat(const perf_event_attr& attr, const char* p, const char* end); // Write the binary format of sample_id to the buffer pointed by p. void WriteToBinaryFormat(char*& p) const; @@ -238,8 +235,7 @@ struct Record { static uint32_t header_size() { return sizeof(perf_event_header); } bool InKernel() const { - return (header.misc & PERF_RECORD_MISC_CPUMODE_MASK) == - PERF_RECORD_MISC_KERNEL; + return (header.misc & PERF_RECORD_MISC_CPUMODE_MASK) == PERF_RECORD_MISC_KERNEL; } void SetTypeAndMisc(uint32_t type, uint16_t misc) { @@ -280,12 +276,11 @@ struct MmapRecord : public Record { MmapRecord(const perf_event_attr& attr, char* p); - MmapRecord(const perf_event_attr& attr, bool in_kernel, uint32_t pid, - uint32_t tid, uint64_t addr, uint64_t len, uint64_t pgoff, - const std::string& filename, uint64_t event_id, uint64_t time = 0); + MmapRecord(const perf_event_attr& attr, bool in_kernel, uint32_t pid, uint32_t tid, uint64_t addr, + uint64_t len, uint64_t pgoff, const std::string& filename, uint64_t event_id, + uint64_t time = 0); - void SetDataAndFilename(const MmapRecordDataType& data, - const std::string& filename); + void SetDataAndFilename(const MmapRecordDataType& data, const std::string& filename); protected: void DumpData(size_t indent) const override; @@ -311,8 +306,7 @@ struct Mmap2Record : public Record { uint64_t addr, uint64_t len, uint64_t pgoff, uint32_t prot, const std::string& filename, uint64_t event_id, uint64_t time = 0); - void SetDataAndFilename(const Mmap2RecordDataType& data, - const std::string& filename); + void SetDataAndFilename(const Mmap2RecordDataType& data, const std::string& filename); protected: void DumpData(size_t indent) const override; @@ -327,8 +321,8 @@ struct CommRecord : public Record { CommRecord(const perf_event_attr& attr, char* p); - CommRecord(const perf_event_attr& attr, uint32_t pid, uint32_t tid, - const std::string& comm, uint64_t event_id, uint64_t time); + CommRecord(const perf_event_attr& attr, uint32_t pid, uint32_t tid, const std::string& comm, + uint64_t event_id, uint64_t time); void SetCommandName(const std::string& name); @@ -353,16 +347,14 @@ struct ExitOrForkRecord : public Record { }; struct ExitRecord : public ExitOrForkRecord { - ExitRecord(const perf_event_attr& attr, char* p) - : ExitOrForkRecord(attr, p) {} + ExitRecord(const perf_event_attr& attr, char* p) : ExitOrForkRecord(attr, p) {} }; struct ForkRecord : public ExitOrForkRecord { - ForkRecord(const perf_event_attr& attr, char* p) - : ExitOrForkRecord(attr, p) {} + ForkRecord(const perf_event_attr& attr, char* p) : ExitOrForkRecord(attr, p) {} - ForkRecord(const perf_event_attr& attr, uint32_t pid, uint32_t tid, - uint32_t ppid, uint32_t ptid, uint64_t event_id); + ForkRecord(const perf_event_attr& attr, uint32_t pid, uint32_t tid, uint32_t ppid, uint32_t ptid, + uint64_t event_id); }; struct LostRecord : public Record { @@ -388,17 +380,15 @@ struct SampleRecord : public Record { PerfSampleCpuType cpu_data; // Valid if PERF_SAMPLE_CPU. PerfSamplePeriodType period_data; // Valid if PERF_SAMPLE_PERIOD. - PerfSampleCallChainType callchain_data; // Valid if PERF_SAMPLE_CALLCHAIN. - PerfSampleRawType raw_data; // Valid if PERF_SAMPLE_RAW. - PerfSampleBranchStackType - branch_stack_data; // Valid if PERF_SAMPLE_BRANCH_STACK. - PerfSampleRegsUserType regs_user_data; // Valid if PERF_SAMPLE_REGS_USER. - PerfSampleStackUserType stack_user_data; // Valid if PERF_SAMPLE_STACK_USER. + PerfSampleCallChainType callchain_data; // Valid if PERF_SAMPLE_CALLCHAIN. + PerfSampleRawType raw_data; // Valid if PERF_SAMPLE_RAW. + PerfSampleBranchStackType branch_stack_data; // Valid if PERF_SAMPLE_BRANCH_STACK. + PerfSampleRegsUserType regs_user_data; // Valid if PERF_SAMPLE_REGS_USER. + PerfSampleStackUserType stack_user_data; // Valid if PERF_SAMPLE_STACK_USER. SampleRecord(const perf_event_attr& attr, char* p); - SampleRecord(const perf_event_attr& attr, uint64_t id, uint64_t ip, - uint32_t pid, uint32_t tid, uint64_t time, uint32_t cpu, - uint64_t period, const std::vector<uint64_t>& ips, + SampleRecord(const perf_event_attr& attr, uint64_t id, uint64_t ip, uint32_t pid, uint32_t tid, + uint64_t time, uint32_t cpu, uint64_t period, const std::vector<uint64_t>& ips, const std::vector<char>& stack, uint64_t dyn_stack_size); void ReplaceRegAndStackWithCallChain(const std::vector<uint64_t>& ips); @@ -430,7 +420,7 @@ struct AuxRecord : public Record { uint64_t aux_offset; uint64_t aux_size; uint64_t flags; - }* data; + } * data; AuxRecord(const perf_event_attr& attr, char* p); @@ -447,8 +437,7 @@ struct BuildIdRecord : public Record { explicit BuildIdRecord(char* p); - BuildIdRecord(bool in_kernel, pid_t pid, const BuildId& build_id, - const std::string& filename); + BuildIdRecord(bool in_kernel, pid_t pid, const BuildId& build_id, const std::string& filename); protected: void DumpData(size_t indent) const override; @@ -479,7 +468,7 @@ struct AuxTraceInfoRecord : public Record { uint32_t pmu_type; uint64_t snapshot; ETM4Info etm4_info[0]; - }* data; + } * data; explicit AuxTraceInfoRecord(char* p); AuxTraceInfoRecord(const DataType& data, const std::vector<ETM4Info>& etm4_info); @@ -534,8 +523,7 @@ struct DsoRecord : public Record { explicit DsoRecord(char* p); - DsoRecord(uint64_t dso_type, uint64_t dso_id, const std::string& dso_name, - uint64_t min_vaddr); + DsoRecord(uint64_t dso_type, uint64_t dso_id, const std::string& dso_name, uint64_t min_vaddr); protected: void DumpData(size_t indent) const override; @@ -549,8 +537,7 @@ struct SymbolRecord : public Record { explicit SymbolRecord(char* p); - SymbolRecord(uint64_t addr, uint64_t len, const std::string& name, - uint64_t dso_id); + SymbolRecord(uint64_t addr, uint64_t len, const std::string& name, uint64_t dso_id); protected: void DumpData(size_t indent) const override; @@ -597,9 +584,7 @@ struct CallChainRecord : public Record { CallChainRecord(pid_t pid, pid_t tid, simpleperf::CallChainJoiner::ChainType type, uint64_t time, const std::vector<uint64_t>& ips, const std::vector<uint64_t>& sps); - uint64_t Timestamp() const override { - return time; - } + uint64_t Timestamp() const override { return time; } protected: void DumpData(size_t indent) const override; @@ -613,9 +598,7 @@ struct UnwindingResultRecord : public Record { UnwindingResultRecord(uint64_t time, const simpleperf::UnwindingResult& unwinding_result); - uint64_t Timestamp() const override { - return time; - } + uint64_t Timestamp() const override { return time; } protected: void DumpData(size_t indent) const override; @@ -637,13 +620,13 @@ struct UnknownRecord : public Record { std::unique_ptr<Record> ReadRecordFromBuffer(const perf_event_attr& attr, uint32_t type, char* p); // Read record from the buffer pointed by [p]. And the record owns the buffer. -std::unique_ptr<Record> ReadRecordFromOwnedBuffer(const perf_event_attr& attr, - uint32_t type, char* p); +std::unique_ptr<Record> ReadRecordFromOwnedBuffer(const perf_event_attr& attr, uint32_t type, + char* p); // Read records from the buffer pointed by [buf]. None of the records own // the buffer. -std::vector<std::unique_ptr<Record>> ReadRecordsFromBuffer( - const perf_event_attr& attr, char* buf, size_t buf_size); +std::vector<std::unique_ptr<Record>> ReadRecordsFromBuffer(const perf_event_attr& attr, char* buf, + size_t buf_size); // Read one record from the buffer pointed by [p]. But the record doesn't // own the buffer. diff --git a/simpleperf/record_equal_test.h b/simpleperf/record_equal_test.h index a939740b..40157edd 100644 --- a/simpleperf/record_equal_test.h +++ b/simpleperf/record_equal_test.h @@ -69,8 +69,8 @@ static void CheckSampleRecordDataEqual(const SampleRecord& r1, const SampleRecor ASSERT_EQ(r1.stack_user_data.size, r2.stack_user_data.size); if (r1.stack_user_data.size > 0) { ASSERT_EQ(r1.stack_user_data.dyn_size, r2.stack_user_data.dyn_size); - ASSERT_EQ(0, memcmp(r1.stack_user_data.data, r2.stack_user_data.data, - r1.stack_user_data.size)); + ASSERT_EQ(0, + memcmp(r1.stack_user_data.data, r2.stack_user_data.data, r1.stack_user_data.size)); } } } @@ -86,9 +86,11 @@ static void CheckRecordEqual(const Record& r1, const Record& r2) { } ASSERT_EQ(0, memcmp(&r1.sample_id, &r2.sample_id, sizeof(r1.sample_id))); if (r1.type() == PERF_RECORD_MMAP) { - CheckMmapRecordDataEqual(static_cast<const MmapRecord&>(r1), static_cast<const MmapRecord&>(r2)); + CheckMmapRecordDataEqual(static_cast<const MmapRecord&>(r1), + static_cast<const MmapRecord&>(r2)); } else if (r1.type() == PERF_RECORD_COMM) { - CheckCommRecordDataEqual(static_cast<const CommRecord&>(r1), static_cast<const CommRecord&>(r2)); + CheckCommRecordDataEqual(static_cast<const CommRecord&>(r1), + static_cast<const CommRecord&>(r2)); } else if (r1.type() == PERF_RECORD_BUILD_ID) { CheckBuildIdRecordDataEqual(static_cast<const BuildIdRecord&>(r1), static_cast<const BuildIdRecord&>(r2)); diff --git a/simpleperf/record_file.h b/simpleperf/record_file.h index 1182b08c..8c73b6ad 100644 --- a/simpleperf/record_file.h +++ b/simpleperf/record_file.h @@ -77,9 +77,7 @@ class RecordFileWriter { bool Read(void* buf, size_t len); bool GetFilePos(uint64_t* file_pos); bool WriteStringWithLength(const std::string& s); - bool WriteFileFeature(const std::string& file_path, - uint32_t file_type, - uint64_t min_vaddr, + bool WriteFileFeature(const std::string& file_path, uint32_t file_type, uint64_t min_vaddr, uint64_t file_offset_of_min_vaddr, const std::vector<const Symbol*>& symbols, const std::vector<uint64_t>* dex_file_offsets); @@ -109,9 +107,7 @@ class RecordFileReader { ~RecordFileReader(); - const PerfFileFormat::FileHeader& FileHeader() const { - return header_; - } + const PerfFileFormat::FileHeader& FileHeader() const { return header_; } std::vector<EventAttrWithId> AttrSection() const { std::vector<EventAttrWithId> result(file_attrs_.size()); diff --git a/simpleperf/record_file_reader.cpp b/simpleperf/record_file_reader.cpp index 87923cb6..4a46da48 100644 --- a/simpleperf/record_file_reader.cpp +++ b/simpleperf/record_file_reader.cpp @@ -70,7 +70,7 @@ int GetFeatureId(const std::string& feature_name) { return -1; } -} // namespace PerfFileFormat +} // namespace PerfFileFormat std::unique_ptr<RecordFileReader> RecordFileReader::CreateInstance(const std::string& filename) { std::string mode = std::string("rb") + CLOSE_ON_EXEC_MODE; @@ -89,9 +89,11 @@ std::unique_ptr<RecordFileReader> RecordFileReader::CreateInstance(const std::st } RecordFileReader::RecordFileReader(const std::string& filename, FILE* fp) - : filename_(filename), record_fp_(fp), event_id_pos_in_sample_records_(0), - event_id_reverse_pos_in_non_sample_records_(0), read_record_size_(0) { -} + : filename_(filename), + record_fp_(fp), + event_id_pos_in_sample_records_(0), + event_id_reverse_pos_in_non_sample_records_(0), + read_record_size_(0) {} RecordFileReader::~RecordFileReader() { if (record_fp_ != nullptr) { @@ -124,7 +126,7 @@ bool RecordFileReader::ReadAttrSection() { size_t attr_count = header_.attrs.size / header_.attr_size; if (header_.attr_size != sizeof(FileAttr)) { LOG(DEBUG) << "attr size (" << header_.attr_size << ") in " << filename_ - << " doesn't match expected size (" << sizeof(FileAttr) << ")"; + << " doesn't match expected size (" << sizeof(FileAttr) << ")"; } if (attr_count == 0) { LOG(ERROR) << "no attr in file " << filename_; @@ -155,7 +157,7 @@ bool RecordFileReader::ReadAttrSection() { attrs.push_back(file_attr.attr); } if (!GetCommonEventIdPositionsForAttrs(attrs, &event_id_pos_in_sample_records_, - &event_id_reverse_pos_in_non_sample_records_)) { + &event_id_reverse_pos_in_non_sample_records_)) { return false; } } @@ -310,7 +312,8 @@ std::unique_ptr<Record> RecordFileReader::ReadRecord() { } else { if (header.size > event_id_reverse_pos_in_non_sample_records_) { has_event_id = true; - event_id = *reinterpret_cast<uint64_t*>(p.get() + header.size - event_id_reverse_pos_in_non_sample_records_); + event_id = *reinterpret_cast<uint64_t*>(p.get() + header.size - + event_id_reverse_pos_in_non_sample_records_); } } if (has_event_id) { @@ -457,10 +460,8 @@ std::vector<uint64_t> RecordFileReader::ReadAuxTraceFeature() { return auxtrace_offset; } -bool RecordFileReader::ReadFileFeature(size_t& read_pos, - std::string* file_path, - uint32_t* file_type, - uint64_t* min_vaddr, +bool RecordFileReader::ReadFileFeature(size_t& read_pos, std::string* file_path, + uint32_t* file_type, uint64_t* min_vaddr, uint64_t* file_offset_of_min_vaddr, std::vector<Symbol>* symbols, std::vector<uint64_t>* dex_file_offsets) { @@ -632,7 +633,7 @@ bool IsPerfDataFile(const std::string& filename) { if (fd.ok()) { PerfFileFormat::FileHeader header; return android::base::ReadFully(fd, &header, sizeof(header)) && - memcmp(header.magic, PERF_MAGIC, sizeof(header.magic)) == 0; + memcmp(header.magic, PERF_MAGIC, sizeof(header.magic)) == 0; } return false; } diff --git a/simpleperf/record_file_test.cpp b/simpleperf/record_file_test.cpp index 114adbbe..29f5a695 100644 --- a/simpleperf/record_file_test.cpp +++ b/simpleperf/record_file_test.cpp @@ -62,8 +62,8 @@ TEST_F(RecordFileTest, smoke) { ASSERT_TRUE(writer->WriteAttrSection(attr_ids_)); // Write data section. - MmapRecord mmap_record(*(attr_ids_[0].attr), true, 1, 1, 0x1000, 0x2000, - 0x3000, "mmap_record_example", attr_ids_[0].ids[0]); + MmapRecord mmap_record(*(attr_ids_[0].attr), true, 1, 1, 0x1000, 0x2000, 0x3000, + "mmap_record_example", attr_ids_[0].ids[0]); ASSERT_TRUE(writer->WriteRecord(mmap_record)); // Write feature section. diff --git a/simpleperf/record_file_writer.cpp b/simpleperf/record_file_writer.cpp index 2d337ffe..1fcab9f6 100644 --- a/simpleperf/record_file_writer.cpp +++ b/simpleperf/record_file_writer.cpp @@ -63,8 +63,7 @@ RecordFileWriter::RecordFileWriter(const std::string& filename, FILE* fp) data_section_offset_(0), data_section_size_(0), feature_section_offset_(0), - feature_count_(0) { -} + feature_count_(0) {} RecordFileWriter::~RecordFileWriter() { if (record_fp_ != nullptr) { @@ -345,22 +344,20 @@ bool RecordFileWriter::WriteFileFeatures(const std::vector<Dso*>& files) { std::sort(dump_symbols.begin(), dump_symbols.end(), Symbol::CompareByAddr); const std::vector<uint64_t>* dex_file_offsets = dso->DexFileOffsets(); - if (!WriteFileFeature(dso->Path(), dso_type, min_vaddr, file_offset_of_min_vaddr, - dump_symbols, dex_file_offsets)) { + if (!WriteFileFeature(dso->Path(), dso_type, min_vaddr, file_offset_of_min_vaddr, dump_symbols, + dex_file_offsets)) { return false; } } return true; } -bool RecordFileWriter::WriteFileFeature(const std::string& file_path, - uint32_t file_type, - uint64_t min_vaddr, - uint64_t file_offset_of_min_vaddr, +bool RecordFileWriter::WriteFileFeature(const std::string& file_path, uint32_t file_type, + uint64_t min_vaddr, uint64_t file_offset_of_min_vaddr, const std::vector<const Symbol*>& symbols, const std::vector<uint64_t>* dex_file_offsets) { - uint32_t size = file_path.size() + 1 + sizeof(uint32_t) * 2 + - sizeof(uint64_t) + symbols.size() * (sizeof(uint64_t) + sizeof(uint32_t)); + uint32_t size = file_path.size() + 1 + sizeof(uint32_t) * 2 + sizeof(uint64_t) + + symbols.size() * (sizeof(uint64_t) + sizeof(uint32_t)); for (const auto& symbol : symbols) { size += strlen(symbol->Name()) + 1; } diff --git a/simpleperf/record_lib_interface.cpp b/simpleperf/record_lib_interface.cpp index bb71d109..b6b892e0 100644 --- a/simpleperf/record_lib_interface.cpp +++ b/simpleperf/record_lib_interface.cpp @@ -179,8 +179,8 @@ bool PerfEventSetForCounting::ReadRawCounters(std::vector<Counter>* counters) { counters->resize(s.size()); for (size_t i = 0; i < s.size(); ++i) { CountersInfo& info = s[i]; - std::string name = info.event_modifier.empty() ? info.event_name : - info.event_name + ":" + info.event_modifier; + std::string name = + info.event_modifier.empty() ? info.event_name : info.event_name + ":" + info.event_modifier; CHECK_EQ(name, event_names_[i]); Counter& sum = (*counters)[i]; sum.event = name; diff --git a/simpleperf/record_lib_test.cpp b/simpleperf/record_lib_test.cpp index 5fdaea44..4c1b7e87 100644 --- a/simpleperf/record_lib_test.cpp +++ b/simpleperf/record_lib_test.cpp @@ -37,8 +37,8 @@ static void DoSomeWork() { } TEST(counter, add_event) { - std::unique_ptr<PerfEventSet> perf(PerfEventSet::CreateInstance( - PerfEventSet::Type::kPerfForCounting)); + std::unique_ptr<PerfEventSet> perf( + PerfEventSet::CreateInstance(PerfEventSet::Type::kPerfForCounting)); ASSERT_TRUE(perf); ASSERT_TRUE(perf->AddEvent("cpu-cycles")); ASSERT_TRUE(perf->AddEvent("cpu-cycles:u")); @@ -63,8 +63,8 @@ TEST(counter, add_event) { TEST(counter, different_targets) { auto test_function = [](std::function<void(PerfEventSet*)> set_target_func) { - std::unique_ptr<PerfEventSet> perf(PerfEventSet::CreateInstance( - PerfEventSet::Type::kPerfForCounting)); + std::unique_ptr<PerfEventSet> perf( + PerfEventSet::CreateInstance(PerfEventSet::Type::kPerfForCounting)); ASSERT_TRUE(perf); ASSERT_TRUE(perf->AddEvent("cpu-cycles")); set_target_func(perf.get()); @@ -81,21 +81,16 @@ TEST(counter, different_targets) { ASSERT_GT(counters[0].time_running_in_ns, 0u); ASSERT_LE(counters[0].time_running_in_ns, counters[0].time_enabled_in_ns); }; - test_function([](PerfEventSet* perf) { - ASSERT_TRUE(perf->MonitorCurrentProcess()); - }); - test_function([](PerfEventSet* perf) { - ASSERT_TRUE(perf->MonitorCurrentThread()); - }); - test_function([](PerfEventSet* perf) { - ASSERT_TRUE(perf->MonitorThreadsInCurrentProcess({getpid()})); - }); + test_function([](PerfEventSet* perf) { ASSERT_TRUE(perf->MonitorCurrentProcess()); }); + test_function([](PerfEventSet* perf) { ASSERT_TRUE(perf->MonitorCurrentThread()); }); + test_function( + [](PerfEventSet* perf) { ASSERT_TRUE(perf->MonitorThreadsInCurrentProcess({getpid()})); }); } TEST(counter, start_stop_multiple_times) { const size_t TEST_COUNT = 10; - std::unique_ptr<PerfEventSet> perf(PerfEventSet::CreateInstance( - PerfEventSet::Type::kPerfForCounting)); + std::unique_ptr<PerfEventSet> perf( + PerfEventSet::CreateInstance(PerfEventSet::Type::kPerfForCounting)); ASSERT_TRUE(perf); ASSERT_TRUE(perf->AddEvent("cpu-cycles")); ASSERT_TRUE(perf->MonitorCurrentProcess()); @@ -122,8 +117,8 @@ TEST(counter, start_stop_multiple_times) { } TEST(counter, no_change_after_stop) { - std::unique_ptr<PerfEventSet> perf(PerfEventSet::CreateInstance( - PerfEventSet::Type::kPerfForCounting)); + std::unique_ptr<PerfEventSet> perf( + PerfEventSet::CreateInstance(PerfEventSet::Type::kPerfForCounting)); ASSERT_TRUE(perf); ASSERT_TRUE(perf->AddEvent("cpu-cycles")); ASSERT_TRUE(perf->MonitorCurrentProcess()); diff --git a/simpleperf/record_test.cpp b/simpleperf/record_test.cpp index 7644ec9e..6d65a980 100644 --- a/simpleperf/record_test.cpp +++ b/simpleperf/record_test.cpp @@ -43,8 +43,7 @@ class RecordTest : public ::testing::Test { }; TEST_F(RecordTest, MmapRecordMatchBinary) { - MmapRecord record(event_attr, true, 1, 2, 0x1000, 0x2000, 0x3000, - "MmapRecord", 0); + MmapRecord record(event_attr, true, 1, 2, 0x1000, 0x2000, 0x3000, "MmapRecord", 0); CheckRecordMatchBinary(record); } @@ -54,9 +53,8 @@ TEST_F(RecordTest, CommRecordMatchBinary) { } TEST_F(RecordTest, SampleRecordMatchBinary) { - event_attr.sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_TIME - | PERF_SAMPLE_ID | PERF_SAMPLE_CPU - | PERF_SAMPLE_PERIOD | PERF_SAMPLE_CALLCHAIN; + event_attr.sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_TIME | PERF_SAMPLE_ID | + PERF_SAMPLE_CPU | PERF_SAMPLE_PERIOD | PERF_SAMPLE_CALLCHAIN; SampleRecord record(event_attr, 1, 2, 3, 4, 5, 6, 7, {8, 9, 10}, {}, 0); CheckRecordMatchBinary(record); } @@ -97,13 +95,13 @@ TEST_F(RecordTest, SampleRecord_exclude_kernel_callchain) { ASSERT_TRUE(r7.ExcludeKernelCallChain()); CheckRecordEqual(r7, SampleRecord(event_attr, 0, 3, 0, 0, 0, 0, 0, {PERF_CONTEXT_USER, PERF_CONTEXT_USER, PERF_CONTEXT_USER, - PERF_CONTEXT_USER, 3, 4}, {}, 0)); + PERF_CONTEXT_USER, 3, 4}, + {}, 0)); } TEST_F(RecordTest, SampleRecord_ReplaceRegAndStackWithCallChain) { event_attr.sample_type |= PERF_SAMPLE_CALLCHAIN | PERF_SAMPLE_REGS_USER | PERF_SAMPLE_STACK_USER; - SampleRecord expected(event_attr, 0, 1, 2, 3, 4, 5, 6, {1, PERF_CONTEXT_USER, 2, 3, 4, 5}, {}, - 0); + SampleRecord expected(event_attr, 0, 1, 2, 3, 4, 5, 6, {1, PERF_CONTEXT_USER, 2, 3, 4, 5}, {}, 0); for (size_t stack_size : {8, 1024}) { SampleRecord r(event_attr, 0, 1, 2, 3, 4, 5, 6, {1}, std::vector<char>(stack_size), 10); r.ReplaceRegAndStackWithCallChain({2, 3, 4, 5}); @@ -129,7 +127,8 @@ TEST_F(RecordTest, SampleRecord_AdjustCallChainGeneratedByKernel) { uint64_t adjustValue = (GetBuildArch() == ARCH_ARM || GetBuildArch() == ARCH_ARM64) ? 2 : 1; SampleRecord expected(event_attr, 0, 1, 2, 3, 4, 5, 6, {1, 5 - adjustValue, PERF_CONTEXT_KERNEL, PERF_CONTEXT_USER, - 6 - adjustValue, PERF_CONTEXT_USER}, {}, 0); + 6 - adjustValue, PERF_CONTEXT_USER}, + {}, 0); expected.header.misc = PERF_RECORD_MISC_KERNEL; CheckRecordEqual(r, expected); } diff --git a/simpleperf/report_lib_interface.cpp b/simpleperf/report_lib_interface.cpp index 8536f969..e182991f 100644 --- a/simpleperf/report_lib_interface.cpp +++ b/simpleperf/report_lib_interface.cpp @@ -17,14 +17,14 @@ #include <memory> #include <utility> -#include <android-base/logging.h> #include <android-base/file.h> +#include <android-base/logging.h> #include <android-base/strings.h> +#include "JITDebugReader.h" #include "dso.h" #include "event_attr.h" #include "event_type.h" -#include "JITDebugReader.h" #include "record_file.h" #include "thread_tree.h" #include "tracing.h" @@ -138,13 +138,11 @@ struct EventInfo { class ReportLib { public: ReportLib() - : log_severity_( - new android::base::ScopedLogSeverity(android::base::INFO)), + : log_severity_(new android::base::ScopedLogSeverity(android::base::INFO)), record_filename_("perf.data"), current_thread_(nullptr), trace_offcpu_(false), - show_art_frames_(false) { - } + show_art_frames_(false) {} bool SetLogSeverity(const char* log_level); @@ -299,8 +297,8 @@ void ReportLib::SetCurrentSample() { current_sample_.in_kernel = r.InKernel(); current_sample_.cpu = r.cpu_data.cpu; if (trace_offcpu_) { - uint64_t next_time = std::max(next_sample_cache_[r.tid_data.tid]->time_data.time, - r.time_data.time + 1); + uint64_t next_time = + std::max(next_sample_cache_[r.tid_data.tid]->time_data.time, r.time_data.time + 1); current_sample_.period = next_time - r.time_data.time; } else { current_sample_.period = r.period_data.period; @@ -312,7 +310,7 @@ void ReportLib::SetCurrentSample() { bool near_java_method = false; auto is_map_for_interpreter = [](const MapEntry* map) { return android::base::EndsWith(map->dso->Path(), "/libart.so") || - android::base::EndsWith(map->dso->Path(), "/libartd.so"); + android::base::EndsWith(map->dso->Path(), "/libartd.so"); }; for (size_t i = 0; i < ips.size(); ++i) { const MapEntry* map = thread_tree_.FindMap(current_thread_, ips[i], i < kernel_ip_count); @@ -323,7 +321,7 @@ void ReportLib::SetCurrentSample() { while (!ip_maps.empty() && is_map_for_interpreter(ip_maps.back().second)) { ip_maps.pop_back(); } - } else if (is_map_for_interpreter(map)){ + } else if (is_map_for_interpreter(map)) { if (near_java_method) { continue; } diff --git a/simpleperf/runtest/comm_change.cpp b/simpleperf/runtest/comm_change.cpp index cdcb2bf4..cba59954 100644 --- a/simpleperf/runtest/comm_change.cpp +++ b/simpleperf/runtest/comm_change.cpp @@ -12,9 +12,9 @@ int main() { // doesn't exit before we attach to it. This scheme also allows simpleperf to control // how long to profile. while (true) { - prctl(PR_SET_NAME, reinterpret_cast<unsigned long>("RUN_COMM1"), 0, 0, 0); // NOLINT + prctl(PR_SET_NAME, reinterpret_cast<unsigned long>("RUN_COMM1"), 0, 0, 0); // NOLINT Function1(); - prctl(PR_SET_NAME, reinterpret_cast<unsigned long>("RUN_COMM2"), 0, 0, 0); // NOLINT + prctl(PR_SET_NAME, reinterpret_cast<unsigned long>("RUN_COMM2"), 0, 0, 0); // NOLINT Function1(); } return 0; diff --git a/simpleperf/sample_tree.h b/simpleperf/sample_tree.h index 64769ffc..3e5936af 100644 --- a/simpleperf/sample_tree.h +++ b/simpleperf/sample_tree.h @@ -19,12 +19,12 @@ #include <unordered_map> -#include "callchain.h" #include "OfflineUnwinder.h" -#include "perf_regs.h" -#include "record.h" #include "SampleComparator.h" #include "SampleDisplayer.h" +#include "callchain.h" +#include "perf_regs.h" +#include "record.h" #include "thread_tree.h" using namespace simpleperf; @@ -66,12 +66,9 @@ class SampleTreeBuilder { virtual ~SampleTreeBuilder() {} - void SetBranchSampleOption(bool use_branch_address) { - use_branch_address_ = use_branch_address; - } + void SetBranchSampleOption(bool use_branch_address) { use_branch_address_ = use_branch_address; } - void SetCallChainSampleOptions(bool accumulate_callchain, - bool build_callchain, + void SetCallChainSampleOptions(bool accumulate_callchain, bool build_callchain, bool use_caller_as_callchain_root) { accumulate_callchain_ = accumulate_callchain; build_callchain_ = build_callchain; @@ -102,15 +99,13 @@ class SampleTreeBuilder { if (accumulate_callchain_) { std::vector<uint64_t> ips; if (r.sample_type & PERF_SAMPLE_CALLCHAIN) { - ips.insert(ips.end(), r.callchain_data.ips, - r.callchain_data.ips + r.callchain_data.ip_nr); + ips.insert(ips.end(), r.callchain_data.ips, r.callchain_data.ips + r.callchain_data.ip_nr); } const ThreadEntry* thread = GetThreadOfSample(sample); // Use stack_user_data.data.size() instead of stack_user_data.dyn_size, to // make up for the missing kernel patch in N9. See b/22612370. if (thread != nullptr && (r.sample_type & PERF_SAMPLE_REGS_USER) && - (r.regs_user_data.reg_mask != 0) && - (r.sample_type & PERF_SAMPLE_STACK_USER) && + (r.regs_user_data.reg_mask != 0) && (r.sample_type & PERF_SAMPLE_STACK_USER) && (r.GetValidStackSize() > 0)) { RegSet regs(r.regs_user_data.abi, r.regs_user_data.reg_mask, r.regs_user_data.regs); std::vector<uint64_t> user_ips; @@ -188,8 +183,7 @@ class SampleTreeBuilder { protected: virtual EntryT* CreateSample(const SampleRecord& r, bool in_kernel, AccumulateInfoT* acc_info) = 0; - virtual EntryT* CreateBranchSample(const SampleRecord& r, - const BranchStackItemType& item) = 0; + virtual EntryT* CreateBranchSample(const SampleRecord& r, const BranchStackItemType& item) = 0; virtual EntryT* CreateCallChainSample(const ThreadEntry* thread, const EntryT* sample, uint64_t ip, bool in_kernel, const std::vector<EntryT*>& callchain, @@ -241,22 +235,19 @@ class SampleTreeBuilder { if (it != sample_set_.end()) { EntryT* sample = *it; // Process only once for recursive function call. - if (std::find(callchain.begin(), callchain.end(), sample) != - callchain.end()) { + if (std::find(callchain.begin(), callchain.end(), sample) != callchain.end()) { return sample; } } return InsertSample(std::move(sample)); } - void InsertCallChainForSample(EntryT* sample, - const std::vector<EntryT*>& callchain, + void InsertCallChainForSample(EntryT* sample, const std::vector<EntryT*>& callchain, const AccumulateInfoT& acc_info) { uint64_t period = GetPeriodForCallChain(acc_info); - sample->callchain.AddCallChain( - callchain, period, [&](const EntryT* s1, const EntryT* s2) { - return sample_comparator_.IsSameSample(s1, s2); - }); + sample->callchain.AddCallChain(callchain, period, [&](const EntryT* s1, const EntryT* s2) { + return sample_comparator_.IsSameSample(s1, s2); + }); } void AddCallChainDuplicateInfo() { @@ -310,8 +301,7 @@ class SampleTreeBuilder { template <typename EntryT> class SampleTreeSorter { public: - explicit SampleTreeSorter(SampleComparator<EntryT> comparator) - : comparator_(comparator) {} + explicit SampleTreeSorter(SampleComparator<EntryT> comparator) : comparator_(comparator) {} virtual ~SampleTreeSorter() {} @@ -322,9 +312,8 @@ class SampleTreeSorter { } } if (!comparator_.empty()) { - std::sort(v.begin(), v.end(), [this](const EntryT* s1, const EntryT* s2) { - return comparator_(s1, s2); - }); + std::sort(v.begin(), v.end(), + [this](const EntryT* s1, const EntryT* s2) { return comparator_(s1, s2); }); } } @@ -338,13 +327,11 @@ class SampleTreeSorter { template <typename EntryT, typename InfoT> class SampleTreeDisplayer { public: - explicit SampleTreeDisplayer(SampleDisplayer<EntryT, InfoT> displayer) - : displayer_(displayer) {} + explicit SampleTreeDisplayer(SampleDisplayer<EntryT, InfoT> displayer) : displayer_(displayer) {} virtual ~SampleTreeDisplayer() {} - void DisplaySamples(FILE* fp, const std::vector<EntryT*>& samples, - const InfoT* info) { + void DisplaySamples(FILE* fp, const std::vector<EntryT*>& samples, const InfoT* info) { displayer_.SetInfo(info); for (const auto& sample : samples) { displayer_.AdjustWidth(sample); diff --git a/simpleperf/sample_tree_test.cpp b/simpleperf/sample_tree_test.cpp index 4123b0e6..56f4a7e7 100644 --- a/simpleperf/sample_tree_test.cpp +++ b/simpleperf/sample_tree_test.cpp @@ -29,9 +29,8 @@ struct SampleEntry { uint64_t map_start_addr; size_t sample_count; - SampleEntry(int pid, int tid, const char* thread_comm, - const std::string& dso_name, uint64_t map_start_addr, - size_t sample_count = 1u) + SampleEntry(int pid, int tid, const char* thread_comm, const std::string& dso_name, + uint64_t map_start_addr, size_t sample_count = 1u) : pid(pid), tid(tid), thread_comm(thread_comm), @@ -64,26 +63,20 @@ class TestSampleTreeBuilder : public SampleTreeBuilder<SampleEntry, int> { void AddSample(int pid, int tid, uint64_t ip, bool in_kernel) { const ThreadEntry* thread = thread_tree_->FindThreadOrNew(pid, tid); const MapEntry* map = thread_tree_->FindMap(thread, ip, in_kernel); - InsertSample(std::unique_ptr<SampleEntry>(new SampleEntry( - pid, tid, thread->comm, map->dso->Path(), map->start_addr))); + InsertSample(std::unique_ptr<SampleEntry>( + new SampleEntry(pid, tid, thread->comm, map->dso->Path(), map->start_addr))); } protected: - SampleEntry* CreateSample(const SampleRecord&, bool, int*) override { - return nullptr; - } - SampleEntry* CreateBranchSample(const SampleRecord&, - const BranchStackItemType&) override { + SampleEntry* CreateSample(const SampleRecord&, bool, int*) override { return nullptr; } + SampleEntry* CreateBranchSample(const SampleRecord&, const BranchStackItemType&) override { return nullptr; }; SampleEntry* CreateCallChainSample(const ThreadEntry*, const SampleEntry*, uint64_t, bool, - const std::vector<SampleEntry*>&, - const int&) override { - return nullptr; - } - const ThreadEntry* GetThreadOfSample(SampleEntry*) override { + const std::vector<SampleEntry*>&, const int&) override { return nullptr; } + const ThreadEntry* GetThreadOfSample(SampleEntry*) override { return nullptr; } uint64_t GetPeriodForCallChain(const int&) override { return 0; } void MergeSample(SampleEntry* sample1, SampleEntry* sample2) override { sample1->sample_count += sample2->sample_count; @@ -93,8 +86,7 @@ class TestSampleTreeBuilder : public SampleTreeBuilder<SampleEntry, int> { ThreadTree* thread_tree_; }; -static void SampleMatchExpectation(const SampleEntry& sample, - const SampleEntry& expected, +static void SampleMatchExpectation(const SampleEntry& sample, const SampleEntry& expected, bool* has_error) { *has_error = true; ASSERT_EQ(expected.pid, sample.pid); @@ -115,7 +107,7 @@ static void CheckSamples(const std::vector<SampleEntry*>& samples, ASSERT_FALSE(has_error) << "Error matching sample at pos " << i; } } -} +} // namespace class SampleTreeTest : public testing::Test { protected: @@ -214,14 +206,14 @@ TEST(sample_tree, overlapped_map) { ThreadTree thread_tree; TestSampleTreeBuilder sample_tree_builder(&thread_tree); thread_tree.SetThreadName(1, 1, "thread1"); - thread_tree.AddThreadMap(1, 1, 1, 10, 0, "map1"); // Add map 1. - sample_tree_builder.AddSample(1, 1, 5, false); // Hit map 1. - thread_tree.AddThreadMap(1, 1, 5, 20, 0, "map2"); // Add map 2. - sample_tree_builder.AddSample(1, 1, 6, false); // Hit map 2. - sample_tree_builder.AddSample(1, 1, 4, false); // Hit map 1. - thread_tree.AddThreadMap(1, 1, 2, 7, 0, "map3"); // Add map 3. - sample_tree_builder.AddSample(1, 1, 7, false); // Hit map 3. - sample_tree_builder.AddSample(1, 1, 10, false); // Hit map 2. + thread_tree.AddThreadMap(1, 1, 1, 10, 0, "map1"); // Add map 1. + sample_tree_builder.AddSample(1, 1, 5, false); // Hit map 1. + thread_tree.AddThreadMap(1, 1, 5, 20, 0, "map2"); // Add map 2. + sample_tree_builder.AddSample(1, 1, 6, false); // Hit map 2. + sample_tree_builder.AddSample(1, 1, 4, false); // Hit map 1. + thread_tree.AddThreadMap(1, 1, 2, 7, 0, "map3"); // Add map 3. + sample_tree_builder.AddSample(1, 1, 7, false); // Hit map 3. + sample_tree_builder.AddSample(1, 1, 10, false); // Hit map 2. std::vector<SampleEntry> expected_samples = { SampleEntry(1, 1, "thread1", "map1", 1, 2), diff --git a/simpleperf/simpleperf_app_runner/simpleperf_app_runner.cpp b/simpleperf/simpleperf_app_runner/simpleperf_app_runner.cpp index d002346e..20329d0d 100644 --- a/simpleperf/simpleperf_app_runner/simpleperf_app_runner.cpp +++ b/simpleperf/simpleperf_app_runner/simpleperf_app_runner.cpp @@ -36,8 +36,8 @@ #include <selinux/android.h> #include "../cmd_api_impl.h" -#include "../cmd_stat_impl.h" #include "../cmd_record_impl.h" +#include "../cmd_stat_impl.h" using android::base::ParseInt; using android::base::ParseUint; diff --git a/simpleperf/test_util.h b/simpleperf/test_util.h index 4d174056..8c4a41c3 100644 --- a/simpleperf/test_util.h +++ b/simpleperf/test_util.h @@ -36,73 +36,73 @@ void CheckElfFileSymbols(const std::map<std::string, ElfFileSymbol>& symbols); bool IsRoot(); -#define TEST_IN_ROOT(TestStatement) \ - do { \ - if (IsRoot()) { \ - TestStatement; \ - } else { \ - GTEST_LOG_(INFO) << "Didn't test \"" << #TestStatement << "\" requires root privileges"; \ - } \ +#define TEST_IN_ROOT(TestStatement) \ + do { \ + if (IsRoot()) { \ + TestStatement; \ + } else { \ + GTEST_LOG_(INFO) << "Didn't test \"" << #TestStatement << "\" requires root privileges"; \ + } \ } while (0) -#define TEST_REQUIRE_ROOT() \ - do { \ - if (!IsRoot()) { \ +#define TEST_REQUIRE_ROOT() \ + do { \ + if (!IsRoot()) { \ GTEST_LOG_(INFO) << "Skip this test as it needs root privileges."; \ - return; \ - } \ + return; \ + } \ } while (0) #if defined(__ANDROID__) #define TEST_REQUIRE_HOST_ROOT() #else -#define TEST_REQUIRE_HOST_ROOT() TEST_REQUIRE_ROOT() +#define TEST_REQUIRE_HOST_ROOT() TEST_REQUIRE_ROOT() #endif bool IsInNativeAbi(); // Used to skip tests not supposed to run on non-native ABIs. -#define OMIT_TEST_ON_NON_NATIVE_ABIS() \ - do { \ - if (!IsInNativeAbi()) { \ +#define OMIT_TEST_ON_NON_NATIVE_ABIS() \ + do { \ + if (!IsInNativeAbi()) { \ GTEST_LOG_(INFO) << "Skip this test as it only runs on native ABIs."; \ - return; \ - } \ + return; \ + } \ } while (0) bool HasHardwareCounter(); -#define TEST_REQUIRE_HW_COUNTER() \ - do { \ - if (!HasHardwareCounter()) { \ +#define TEST_REQUIRE_HW_COUNTER() \ + do { \ + if (!HasHardwareCounter()) { \ GTEST_LOG_(INFO) << "Skip this test as the machine doesn't have hardware PMU counters."; \ - return; \ - } \ + return; \ + } \ } while (0) bool HasPmuCounter(); -#define TEST_REQUIRE_PMU_COUNTER() \ - do { \ - if (!HasPmuCounter()) { \ +#define TEST_REQUIRE_PMU_COUNTER() \ + do { \ + if (!HasPmuCounter()) { \ GTEST_LOG_(INFO) << "Skip this test as the machine doesn't have low-level PMU counters."; \ - return; \ - } \ + return; \ + } \ } while (0) bool HasTracepointEvents(); -#define TEST_REQUIRE_TRACEPOINT_EVENTS() \ - do { \ - if (!HasTracepointEvents()) { \ +#define TEST_REQUIRE_TRACEPOINT_EVENTS() \ + do { \ + if (!HasTracepointEvents()) { \ GTEST_LOG_(INFO) << "Skip this test as the machine doesn't support tracepoint events."; \ - return; \ - } \ + return; \ + } \ } while (0) #if defined(IN_CTS_TEST) #define TEST_REQUIRE_APPS() #else -#define TEST_REQUIRE_APPS() \ - do { \ +#define TEST_REQUIRE_APPS() \ + do { \ GTEST_LOG_(INFO) << "Skip this test as test apps aren't available."; \ - return; \ + return; \ } while (0) #endif @@ -180,7 +180,7 @@ class AppHelper { #elif defined(__arm__) return "armeabi-v7a"; #else - #error "unrecognized ABI" +#error "unrecognized ABI" #endif } diff --git a/simpleperf/thread_tree.cpp b/simpleperf/thread_tree.cpp index 8f99c465..fe2320c8 100644 --- a/simpleperf/thread_tree.cpp +++ b/simpleperf/thread_tree.cpp @@ -43,8 +43,7 @@ std::string GetSymbolMapDsoName(int pid) { void ThreadTree::SetThreadName(int pid, int tid, const std::string& comm) { ThreadEntry* thread = FindThreadOrNew(pid, tid); if (comm != thread->comm) { - thread_comm_storage_.push_back( - std::unique_ptr<std::string>(new std::string(comm))); + thread_comm_storage_.push_back(std::unique_ptr<std::string>(new std::string(comm))); thread->comm = thread_comm_storage_.back()->c_str(); } } @@ -97,9 +96,10 @@ ThreadEntry* ThreadTree::CreateThread(int pid, int tid) { maps = process->maps; } ThreadEntry* thread = new ThreadEntry{ - pid, tid, - comm, - maps, + pid, + tid, + comm, + maps, }; auto pair = thread_tree_.insert(std::make_pair(tid, std::unique_ptr<ThreadEntry>(thread))); CHECK(pair.second); @@ -132,8 +132,7 @@ void ThreadTree::AddKernelMap(uint64_t start_addr, uint64_t len, uint64_t pgoff, } Dso* ThreadTree::FindKernelDsoOrNew(const std::string& filename) { - if (filename == DEFAULT_KERNEL_MMAP_NAME || - filename == DEFAULT_KERNEL_MMAP_NAME_PERF) { + if (filename == DEFAULT_KERNEL_MMAP_NAME || filename == DEFAULT_KERNEL_MMAP_NAME_PERF) { return kernel_dso_.get(); } auto it = module_dso_tree_.find(filename); @@ -144,8 +143,8 @@ Dso* ThreadTree::FindKernelDsoOrNew(const std::string& filename) { return it->second.get(); } -void ThreadTree::AddThreadMap(int pid, int tid, uint64_t start_addr, uint64_t len, - uint64_t pgoff, const std::string& filename, uint32_t flags) { +void ThreadTree::AddThreadMap(int pid, int tid, uint64_t start_addr, uint64_t len, uint64_t pgoff, + const std::string& filename, uint32_t flags) { ThreadEntry* thread = FindThreadOrNew(pid, tid); Dso* dso = FindUserDsoOrNew(filename, start_addr); InsertMap(*thread->maps, MapEntry(start_addr, len, pgoff, dso, false, flags)); @@ -284,8 +283,8 @@ const MapEntry* ThreadTree::FindMap(const ThreadEntry* thread, uint64_t ip) { return result != nullptr ? result : &unknown_map_; } -const Symbol* ThreadTree::FindSymbol(const MapEntry* map, uint64_t ip, - uint64_t* pvaddr_in_file, Dso** pdso) { +const Symbol* ThreadTree::FindSymbol(const MapEntry* map, uint64_t ip, uint64_t* pvaddr_in_file, + Dso** pdso) { uint64_t vaddr_in_file = 0; const Symbol* symbol = nullptr; Dso* dso = map->dso; @@ -305,9 +304,9 @@ const Symbol* ThreadTree::FindSymbol(const MapEntry* map, uint64_t ip, if (symbol == nullptr) { if (show_ip_for_unknown_symbol_) { - std::string name = android::base::StringPrintf( - "%s%s[+%" PRIx64 "]", (show_mark_for_unknown_symbol_ ? "*" : ""), - dso->FileName().c_str(), vaddr_in_file); + std::string name = android::base::StringPrintf("%s%s[+%" PRIx64 "]", + (show_mark_for_unknown_symbol_ ? "*" : ""), + dso->FileName().c_str(), vaddr_in_file); dso->AddUnknownSymbol(vaddr_in_file, name); symbol = dso->FindSymbol(vaddr_in_file); CHECK(symbol != nullptr); @@ -336,9 +335,8 @@ void ThreadTree::ClearThreadAndMap() { map_storage_.clear(); } -void ThreadTree::AddDsoInfo(const std::string& file_path, uint32_t file_type, - uint64_t min_vaddr, uint64_t file_offset_of_min_vaddr, - std::vector<Symbol>* symbols, +void ThreadTree::AddDsoInfo(const std::string& file_path, uint32_t file_type, uint64_t min_vaddr, + uint64_t file_offset_of_min_vaddr, std::vector<Symbol>* symbols, const std::vector<uint64_t>& dex_file_offsets) { DsoType dso_type = static_cast<DsoType>(file_type); Dso* dso = nullptr; @@ -372,9 +370,8 @@ void ThreadTree::Update(const Record& record) { if (r.InKernel()) { AddKernelMap(r.data->addr, r.data->len, r.data->pgoff, r.filename); } else { - std::string filename = (r.filename == DEFAULT_EXECNAME_FOR_THREAD_MMAP) - ? "[unknown]" - : r.filename; + std::string filename = + (r.filename == DEFAULT_EXECNAME_FOR_THREAD_MMAP) ? "[unknown]" : r.filename; AddThreadMap(r.data->pid, r.data->tid, r.data->addr, r.data->len, r.data->pgoff, filename, r.data->prot); } diff --git a/simpleperf/thread_tree.h b/simpleperf/thread_tree.h index a90c4951..b3be9a37 100644 --- a/simpleperf/thread_tree.h +++ b/simpleperf/thread_tree.h @@ -47,8 +47,8 @@ struct MapEntry { bool in_kernel; uint32_t flags; - MapEntry(uint64_t start_addr, uint64_t len, uint64_t pgoff, - Dso* dso, bool in_kernel, uint32_t flags = 0) + MapEntry(uint64_t start_addr, uint64_t len, uint64_t pgoff, Dso* dso, bool in_kernel, + uint32_t flags = 0) : start_addr(start_addr), len(len), pgoff(pgoff), @@ -59,9 +59,7 @@ struct MapEntry { uint64_t get_end_addr() const { return start_addr + len; } - uint64_t Contains(uint64_t addr) const { - return addr >= start_addr && addr < get_end_addr(); - } + uint64_t Contains(uint64_t addr) const { return addr >= start_addr && addr < get_end_addr(); } uint64_t GetVaddrInFile(uint64_t addr) const { if (Contains(addr)) { @@ -73,7 +71,7 @@ struct MapEntry { struct MapSet { std::map<uint64_t, const MapEntry*> maps; // Map from start_addr to a MapEntry. - uint64_t version = 0u; // incremented each time changing maps + uint64_t version = 0u; // incremented each time changing maps const MapEntry* FindMapByAddr(uint64_t addr) const; }; @@ -81,7 +79,7 @@ struct MapSet { struct ThreadEntry { int pid; int tid; - const char* comm; // It always refers to the latest comm. + const char* comm; // It always refers to the latest comm. std::shared_ptr<MapSet> maps; // maps is shared by threads in the same process. }; @@ -93,11 +91,10 @@ class ThreadTree { ThreadTree() : show_ip_for_unknown_symbol_(false), show_mark_for_unknown_symbol_(false), - unknown_symbol_("unknown", 0, - std::numeric_limits<unsigned long long>::max()) { + unknown_symbol_("unknown", 0, std::numeric_limits<unsigned long long>::max()) { unknown_dso_ = Dso::CreateDso(DSO_UNKNOWN_FILE, "unknown"); - unknown_map_ = MapEntry(0, std::numeric_limits<unsigned long long>::max(), - 0, unknown_dso_.get(), false); + unknown_map_ = + MapEntry(0, std::numeric_limits<unsigned long long>::max(), 0, unknown_dso_.get(), false); kernel_dso_ = Dso::CreateDso(DSO_KERNEL, DEFAULT_KERNEL_MMAP_NAME); // We can't dump comm for pid 0 from /proc, so add it's name here. SetThreadName(0, 0, "swapper"); @@ -108,22 +105,20 @@ class ThreadTree { ThreadEntry* FindThread(int tid); ThreadEntry* FindThreadOrNew(int pid, int tid); void ExitThread(int pid, int tid); - void AddKernelMap(uint64_t start_addr, uint64_t len, uint64_t pgoff, - const std::string& filename); + void AddKernelMap(uint64_t start_addr, uint64_t len, uint64_t pgoff, const std::string& filename); const MapSet& GetKernelMaps() { return kernel_maps_; } - void AddThreadMap(int pid, int tid, uint64_t start_addr, uint64_t len, - uint64_t pgoff, const std::string& filename, uint32_t flags = 0); + void AddThreadMap(int pid, int tid, uint64_t start_addr, uint64_t len, uint64_t pgoff, + const std::string& filename, uint32_t flags = 0); // Add process symbols that do not correspond to any real dso. // For example, these might be symbols generated by a JIT. void AddSymbolsForProcess(int pid, std::vector<Symbol>* symbols); - const MapEntry* FindMap(const ThreadEntry* thread, uint64_t ip, - bool in_kernel); + const MapEntry* FindMap(const ThreadEntry* thread, uint64_t ip, bool in_kernel); // Find map for an ip address when we don't know whether it is in kernel. const MapEntry* FindMap(const ThreadEntry* thread, uint64_t ip); - const Symbol* FindSymbol(const MapEntry* map, uint64_t ip, - uint64_t* pvaddr_in_file, Dso** pdso = nullptr); + const Symbol* FindSymbol(const MapEntry* map, uint64_t ip, uint64_t* pvaddr_in_file, + Dso** pdso = nullptr); const Symbol* FindKernelSymbol(uint64_t ip); bool IsUnknownDso(const Dso* dso) const { return dso == unknown_dso_.get(); } const Symbol* UnknownSymbol() const { return &unknown_symbol_; } @@ -137,9 +132,9 @@ class ThreadTree { // the time to reload dso information. void ClearThreadAndMap(); - void AddDsoInfo(const std::string& file_path, uint32_t file_type, - uint64_t min_vaddr, uint64_t file_offset_of_min_vaddr, - std::vector<Symbol>* symbols, const std::vector<uint64_t>& dex_file_offsets); + void AddDsoInfo(const std::string& file_path, uint32_t file_type, uint64_t min_vaddr, + uint64_t file_offset_of_min_vaddr, std::vector<Symbol>* symbols, + const std::vector<uint64_t>& dex_file_offsets); void AddDexFileOffset(const std::string& file_path, uint64_t dex_file_offset); // Update thread tree with information provided by record. diff --git a/simpleperf/thread_tree_test.cpp b/simpleperf/thread_tree_test.cpp index c75e98c4..cefa3f74 100644 --- a/simpleperf/thread_tree_test.cpp +++ b/simpleperf/thread_tree_test.cpp @@ -130,9 +130,10 @@ TEST_F(ThreadTreeTest, reused_tid_without_thread_exit) { } TEST_F(ThreadTreeTest, add_symbols_for_process) { - std::string symbol_map("0x2000 0x20 two\n" - "0x1000 0x10 one\n" - "0x3000 0x30 three\n"); + std::string symbol_map( + "0x2000 0x20 two\n" + "0x1000 0x10 one\n" + "0x3000 0x30 three\n"); auto symbols = ReadSymbolMapFromString(symbol_map); diff --git a/simpleperf/tracing.cpp b/simpleperf/tracing.cpp index c5a45587..08a63353 100644 --- a/simpleperf/tracing.cpp +++ b/simpleperf/tracing.cpp @@ -49,8 +49,7 @@ void MoveFromBinaryFormat(std::string& data, const char*& p) { namespace simpleperf { -const char TRACING_INFO_MAGIC[10] = {23, 8, 68, 't', 'r', - 'a', 'c', 'i', 'n', 'g'}; +const char TRACING_INFO_MAGIC[10] = {23, 8, 68, 't', 'r', 'a', 'c', 'i', 'n', 'g'}; template <class T> void AppendData(std::vector<char>& data, const T& s) { @@ -79,8 +78,7 @@ static void AppendFile(std::vector<char>& data, const std::string& file, data.insert(data.end(), file.begin(), file.end()); } -static void DetachFile(const char*& p, std::string& file, - uint32_t file_size_bytes = 8) { +static void DetachFile(const char*& p, std::string& file, uint32_t file_size_bytes = 8) { uint64_t file_size = ConvertBytesToValue(p, file_size_bytes); p += file_size_bytes; file.clear(); @@ -88,7 +86,8 @@ static void DetachFile(const char*& p, std::string& file, p += file_size; } -static bool ReadTraceFsFile(const std::string& path, std::string* content, bool report_error = true) { +static bool ReadTraceFsFile(const std::string& path, std::string* content, + bool report_error = true) { const char* tracefs_dir = GetTraceFsDir(); if (tracefs_dir == nullptr) { if (report_error) { @@ -147,7 +146,7 @@ TracingFile::TracingFile() { memcpy(magic, TRACING_INFO_MAGIC, sizeof(TRACING_INFO_MAGIC)); version = "0.5"; endian = 0; - size_of_long = static_cast<int>(sizeof(long)); // NOLINT(google-runtime-int) + size_of_long = static_cast<int>(sizeof(long)); // NOLINT(google-runtime-int) page_size = static_cast<uint32_t>(::GetPageSize()); } @@ -268,13 +267,11 @@ void TracingFile::Dump(size_t indent) const { } for (size_t i = 0; i < event_format_files.size(); ++i) { PrintIndented(indent + 1, "event format file %zu/%zu %s:\n%s\n\n", i + 1, - event_format_files.size(), - event_format_files[i].first.c_str(), + event_format_files.size(), event_format_files[i].first.c_str(), event_format_files[i].second.c_str()); } PrintIndented(indent + 1, "kallsyms:\n%s\n\n", kallsyms_file.c_str()); - PrintIndented(indent + 1, "printk_formats:\n%s\n\n", - printk_formats_file.c_str()); + PrintIndented(indent + 1, "printk_formats:\n%s\n\n", printk_formats_file.c_str()); } enum class FormatParsingState { @@ -365,8 +362,7 @@ TracingFormat ParseTracingFormat(const std::string& data) { return format; } -std::vector<TracingFormat> TracingFile::LoadTracingFormatsFromEventFiles() - const { +std::vector<TracingFormat> TracingFile::LoadTracingFormatsFromEventFiles() const { std::vector<TracingFormat> formats; for (const auto& pair : event_format_files) { TracingFormat format = ParseTracingFormat(pair.second); @@ -381,9 +377,13 @@ Tracing::Tracing(const std::vector<char>& data) { tracing_file_->LoadFromBinary(data); } -Tracing::~Tracing() { delete tracing_file_; } +Tracing::~Tracing() { + delete tracing_file_; +} -void Tracing::Dump(size_t indent) { tracing_file_->Dump(indent); } +void Tracing::Dump(size_t indent) { + tracing_file_->Dump(indent); +} TracingFormat Tracing::GetTracingFormatHavingId(uint64_t trace_event_id) { if (tracing_formats_.empty()) { @@ -404,8 +404,7 @@ std::string Tracing::GetTracingEventNameHavingId(uint64_t trace_event_id) { } for (const auto& format : tracing_formats_) { if (format.id == trace_event_id) { - return android::base::StringPrintf("%s:%s", format.system_name.c_str(), - format.name.c_str()); + return android::base::StringPrintf("%s:%s", format.system_name.c_str(), format.name.c_str()); } } return ""; @@ -415,10 +414,11 @@ const std::string& Tracing::GetKallsyms() const { return tracing_file_->GetKallsymsFile(); } -uint32_t Tracing::GetPageSize() const { return tracing_file_->GetPageSize(); } +uint32_t Tracing::GetPageSize() const { + return tracing_file_->GetPageSize(); +} -bool GetTracingData(const std::vector<const EventType*>& event_types, - std::vector<char>* data) { +bool GetTracingData(const std::vector<const EventType*>& event_types, std::vector<char>* data) { data->clear(); std::vector<TraceType> trace_types; for (const auto& type : event_types) { diff --git a/simpleperf/tracing.h b/simpleperf/tracing.h index 60d99dde..101ac555 100644 --- a/simpleperf/tracing.h +++ b/simpleperf/tracing.h @@ -89,8 +89,7 @@ struct TracingFormat { return field; } } - LOG(FATAL) << "Couldn't find field " << name << "in TracingFormat of " - << this->name; + LOG(FATAL) << "Couldn't find field " << name << "in TracingFormat of " << this->name; return fields[0]; } }; @@ -112,8 +111,7 @@ class Tracing { std::vector<TracingFormat> tracing_formats_; }; -bool GetTracingData(const std::vector<const EventType*>& event_types, - std::vector<char>* data); +bool GetTracingData(const std::vector<const EventType*>& event_types, std::vector<char>* data); // use_quote: whether or not to use quotes in string operands // used_fields: field names used in the filter diff --git a/simpleperf/tracing_test.cpp b/simpleperf/tracing_test.cpp index 698fd446..0ed82763 100644 --- a/simpleperf/tracing_test.cpp +++ b/simpleperf/tracing_test.cpp @@ -59,7 +59,7 @@ TEST(tracing, adjust_tracepoint_filter) { } namespace simpleperf { -std::ostream& operator<<(std::ostream& os, const TracingField& field){ +std::ostream& operator<<(std::ostream& os, const TracingField& field) { os << "field (" << field.name << ", off " << field.offset << ", elem size " << field.elem_size << ", elem_count " << field.elem_count << ", is_signed " << field.is_signed << ", is_dynamic " << field.is_dynamic << ")"; diff --git a/simpleperf/utils.cpp b/simpleperf/utils.cpp index f09bab12..c36e8266 100644 --- a/simpleperf/utils.cpp +++ b/simpleperf/utils.cpp @@ -69,15 +69,14 @@ const char* OneTimeFreeAllocator::AllocateString(std::string_view s) { return result; } - android::base::unique_fd FileHelper::OpenReadOnly(const std::string& filename) { - int fd = TEMP_FAILURE_RETRY(open(filename.c_str(), O_RDONLY | O_BINARY)); - return android::base::unique_fd(fd); + int fd = TEMP_FAILURE_RETRY(open(filename.c_str(), O_RDONLY | O_BINARY)); + return android::base::unique_fd(fd); } android::base::unique_fd FileHelper::OpenWriteOnly(const std::string& filename) { - int fd = TEMP_FAILURE_RETRY(open(filename.c_str(), O_WRONLY | O_BINARY | O_CREAT, 0644)); - return android::base::unique_fd(fd); + int fd = TEMP_FAILURE_RETRY(open(filename.c_str(), O_WRONLY | O_BINARY | O_CREAT, 0644)); + return android::base::unique_fd(fd); } std::unique_ptr<ArchiveHelper> ArchiveHelper::CreateInstance(const std::string& filename) { @@ -89,7 +88,7 @@ std::unique_ptr<ArchiveHelper> ArchiveHelper::CreateInstance(const std::string& // files than zip files in a process map. In order to detect invalid zip files fast, we add a // check of magic number here. Note that OpenArchiveFd() detects invalid zip files in a thorough // way, but it usually needs reading at least 64K file data. - static const char zip_preamble[] = {0x50, 0x4b, 0x03, 0x04 }; + static const char zip_preamble[] = {0x50, 0x4b, 0x03, 0x04}; char buf[4]; if (!android::base::ReadFully(fd, buf, 4) || memcmp(buf, zip_preamble, 4) != 0) { return nullptr; @@ -303,12 +302,9 @@ bool XzDecompress(const std::string& compressed_data, std::string* decompressed_ } static std::map<std::string, android::base::LogSeverity> log_severity_map = { - {"verbose", android::base::VERBOSE}, - {"debug", android::base::DEBUG}, - {"info", android::base::INFO}, - {"warning", android::base::WARNING}, - {"error", android::base::ERROR}, - {"fatal", android::base::FATAL}, + {"verbose", android::base::VERBOSE}, {"debug", android::base::DEBUG}, + {"info", android::base::INFO}, {"warning", android::base::WARNING}, + {"error", android::base::ERROR}, {"fatal", android::base::FATAL}, }; bool GetLogSeverity(const std::string& name, android::base::LogSeverity* severity) { auto it = log_severity_map.find(name); diff --git a/simpleperf/utils.h b/simpleperf/utils.h index 416ea803..2acc9e51 100644 --- a/simpleperf/utils.h +++ b/simpleperf/utils.h @@ -52,12 +52,9 @@ static inline uint64_t Align(uint64_t value, uint64_t alignment) { class OneTimeFreeAllocator { public: explicit OneTimeFreeAllocator(size_t unit_size = 8192u) - : unit_size_(unit_size), cur_(nullptr), end_(nullptr) { - } + : unit_size_(unit_size), cur_(nullptr), end_(nullptr) {} - ~OneTimeFreeAllocator() { - Clear(); - } + ~OneTimeFreeAllocator() { Clear(); } void Clear(); const char* AllocateString(std::string_view s); diff --git a/simpleperf/utils_test.cpp b/simpleperf/utils_test.cpp index b81db317..0cb390d5 100644 --- a/simpleperf/utils_test.cpp +++ b/simpleperf/utils_test.cpp @@ -29,10 +29,8 @@ static bool ModulesMatch(const char* p, const char* q) { return false; } -static bool KernelSymbolsMatch(const KernelSymbol& sym1, - const KernelSymbol& sym2) { - return sym1.addr == sym2.addr && sym1.type == sym2.type && - strcmp(sym1.name, sym2.name) == 0 && +static bool KernelSymbolsMatch(const KernelSymbol& sym1, const KernelSymbol& sym2) { + return sym1.addr == sym2.addr && sym1.type == sym2.type && strcmp(sym1.name, sym2.name) == 0 && ModulesMatch(sym1.module, sym2.module); } @@ -47,21 +45,18 @@ TEST(utils, ProcessKernelSymbols) { expected_symbol.name = "__warned.41698"; expected_symbol.module = "libsas"; ASSERT_TRUE(ProcessKernelSymbols( - data, - std::bind(&KernelSymbolsMatch, std::placeholders::_1, expected_symbol))); + data, std::bind(&KernelSymbolsMatch, std::placeholders::_1, expected_symbol))); expected_symbol.addr = 0xaaaaaaaaaaaaaaaaULL; expected_symbol.type = 'T'; expected_symbol.name = "_text"; expected_symbol.module = nullptr; ASSERT_TRUE(ProcessKernelSymbols( - data, - std::bind(&KernelSymbolsMatch, std::placeholders::_1, expected_symbol))); + data, std::bind(&KernelSymbolsMatch, std::placeholders::_1, expected_symbol))); expected_symbol.name = "non_existent_symbol"; ASSERT_FALSE(ProcessKernelSymbols( - data, - std::bind(&KernelSymbolsMatch, std::placeholders::_1, expected_symbol))); + data, std::bind(&KernelSymbolsMatch, std::placeholders::_1, expected_symbol))); } TEST(utils, ConvertBytesToValue) { diff --git a/simpleperf/workload.cpp b/simpleperf/workload.cpp index 60c9ed15..6fd55108 100644 --- a/simpleperf/workload.cpp +++ b/simpleperf/workload.cpp @@ -26,14 +26,14 @@ #include <android-base/strings.h> std::unique_ptr<Workload> Workload::CreateWorkload(const std::vector<std::string>& args) { - std::unique_ptr<Workload> workload(new Workload(args, std::function<void ()>())); + std::unique_ptr<Workload> workload(new Workload(args, std::function<void()>())); if (workload != nullptr && workload->CreateNewProcess()) { return workload; } return nullptr; } -std::unique_ptr<Workload> Workload::CreateWorkload(const std::function<void ()>& function) { +std::unique_ptr<Workload> Workload::CreateWorkload(const std::function<void()>& function) { std::unique_ptr<Workload> workload(new Workload(std::vector<std::string>(), function)); if (workload != nullptr && workload->CreateNewProcess()) { return workload; @@ -51,16 +51,14 @@ bool Workload::RunCmd(const std::vector<std::string>& args, bool report_error) { return ret == 0; } -Workload::Workload(const std::vector<std::string>& args, const std::function<void ()>& function) +Workload::Workload(const std::vector<std::string>& args, const std::function<void()>& function) : work_state_(NotYetCreateNewProcess), child_proc_args_(args), child_proc_function_(function), work_pid_(-1), start_signal_fd_(-1), exec_child_fd_(-1) { - kill_function_ = [](pid_t pid) { - kill(pid, SIGKILL); - }; + kill_function_ = [](pid_t pid) { kill(pid, SIGKILL); }; } Workload::~Workload() { diff --git a/simpleperf/workload.h b/simpleperf/workload.h index 4ca93a42..cfb5fece 100644 --- a/simpleperf/workload.h +++ b/simpleperf/workload.h @@ -36,28 +36,24 @@ class Workload { public: static std::unique_ptr<Workload> CreateWorkload(const std::vector<std::string>& args); - static std::unique_ptr<Workload> CreateWorkload(const std::function<void ()>& function); + static std::unique_ptr<Workload> CreateWorkload(const std::function<void()>& function); static bool RunCmd(const std::vector<std::string>& args, bool report_error = true); ~Workload(); bool Start(); - bool IsStarted() { - return work_state_ == Started; - } - pid_t GetPid() { - return work_pid_; - } + bool IsStarted() { return work_state_ == Started; } + pid_t GetPid() { return work_pid_; } bool WaitChildProcess(int* exit_code); // Set the function used to kill the workload process in ~Workload(). - void SetKillFunction(const std::function<void (pid_t)>& kill_function) { + void SetKillFunction(const std::function<void(pid_t)>& kill_function) { kill_function_ = kill_function; } private: - explicit Workload(const std::vector<std::string>& args, const std::function<void ()>& function); + explicit Workload(const std::vector<std::string>& args, const std::function<void()>& function); bool CreateNewProcess(); void ChildProcessFn(int start_signal_fd, int exec_child_fd); @@ -66,11 +62,11 @@ class Workload { WorkState work_state_; // The child process either executes child_proc_args or run child_proc_function. std::vector<std::string> child_proc_args_; - std::function<void ()> child_proc_function_; + std::function<void()> child_proc_function_; pid_t work_pid_; int start_signal_fd_; // The parent process writes 1 to start workload in the child process. int exec_child_fd_; // The child process writes 1 to notify that execvp() failed. - std::function<void (pid_t)> kill_function_; + std::function<void(pid_t)> kill_function_; DISALLOW_COPY_AND_ASSIGN(Workload); }; diff --git a/simpleperf/workload_test.cpp b/simpleperf/workload_test.cpp index 98241432..33d1c3e2 100644 --- a/simpleperf/workload_test.cpp +++ b/simpleperf/workload_test.cpp @@ -24,9 +24,7 @@ TEST(workload, success) { IOEventLoop loop; - ASSERT_TRUE(loop.AddSignalEvent(SIGCHLD, [&]() { - return loop.ExitLoop(); - })); + ASSERT_TRUE(loop.AddSignalEvent(SIGCHLD, [&]() { return loop.ExitLoop(); })); auto workload = Workload::CreateWorkload({"sleep", "1"}); ASSERT_TRUE(workload != nullptr); ASSERT_TRUE(workload->GetPid() != 0); @@ -43,9 +41,7 @@ TEST(workload, execvp_failure) { static void run_signaled_workload() { { IOEventLoop loop; - ASSERT_TRUE(loop.AddSignalEvent(SIGCHLD, [&]() { - return loop.ExitLoop(); - })); + ASSERT_TRUE(loop.AddSignalEvent(SIGCHLD, [&]() { return loop.ExitLoop(); })); auto workload = Workload::CreateWorkload({"sleep", "10"}); ASSERT_TRUE(workload != nullptr); ASSERT_TRUE(workload->Start()); @@ -64,9 +60,7 @@ TEST(workload, signaled_warning) { static void run_exit_nonzero_workload() { { IOEventLoop loop; - ASSERT_TRUE(loop.AddSignalEvent(SIGCHLD, [&]() { - return loop.ExitLoop(); - })); + ASSERT_TRUE(loop.AddSignalEvent(SIGCHLD, [&]() { return loop.ExitLoop(); })); auto workload = Workload::CreateWorkload({"ls", "nonexistdir"}); ASSERT_TRUE(workload != nullptr); ASSERT_TRUE(workload->Start()); |