diff --git a/OAT.xml b/OAT.xml
index 288054793e14d0a9254e16a1e9e21d501a8db98f..4045cec621a7ffdb6b40a947df7b9c25a23e21c9 100755
--- a/OAT.xml
+++ b/OAT.xml
@@ -62,6 +62,11 @@ Note:If the text contains special characters, please escape them according to th
+
+
+
+
+
diff --git a/hiperf.gni b/hiperf.gni
index 2f7aac9ebce13d39b6b77b934fe98163d3691283..e578d0c8c88cb4d3e1ab2a7d8abf7bcfc983db96 100644
--- a/hiperf.gni
+++ b/hiperf.gni
@@ -28,7 +28,6 @@ declare_args() {
hiperf_debug = true
hiperf_code_analyze = false
hiperf_use_syspara = true
- have_common_tools = true
}
code_check_flag = [
diff --git a/include/callstack.h b/include/callstack.h
index 8e46cf728403a521051972d68256ec04e777cd80..a99c94a8bd8f7272d3f82a7369b0bddc3eaf0421 100755
--- a/include/callstack.h
+++ b/include/callstack.h
@@ -38,9 +38,9 @@
namespace OHOS {
namespace Developtools {
namespace HiPerf {
-const int MAX_CALL_FRAME_EXPEND_CYCLE = 10;
-const size_t MAX_CALL_FRAME_EXPEND_CACHE_SIZE = 10;
-const size_t MAX_CALL_FRAME_UNWIND_SIZE = 30;
+const int MAX_CALL_FRAME_EXPAND_CYCLE = 10;
+const size_t MAX_CALL_FRAME_EXPAND_CACHE_SIZE = 10;
+const size_t MAX_CALL_FRAME_UNWIND_SIZE = 256;
// if ip is 0 , 1 both not usefule
const uint64_t BAD_IP_ADDRESS = 2;
@@ -55,7 +55,7 @@ public:
bool UnwindCallStack(const VirtualThread &thread, bool abi32, u64 *regs, u64 regsNum,
const u8 *stack, u64 stackSize, std::vector &,
size_t maxStackLevel = MAX_CALL_FRAME_UNWIND_SIZE);
- size_t ExpendCallStack(pid_t tid, std::vector &callFrames, size_t expendLimit = 1u);
+ size_t ExpandCallStack(pid_t tid, std::vector &callFrames, size_t expandLimit = 1u);
private:
uint64_t stackPoint_ = 0;
@@ -66,8 +66,8 @@ private:
u64 stackSize_ = 0;
void LogFrame(const std::string msg, const std::vector &frames);
- size_t ExpendCallStack(std::vector &newCallFrames,
- const std::vector &cachedCallFrames, size_t expendLimit);
+ size_t DoExpandCallStack(std::vector &newCallFrames,
+ const std::vector &cachedCallFrames, size_t expandLimit);
// we have a cache for all thread
std::map>> cachedCallFramesMap_;
diff --git a/include/mem_map_item.h b/include/mem_map_item.h
index f7f541bfd973ba4873038296019f4c9ea55ae770..a942ef19218c7108ac7a5d536e647ee22165065b 100755
--- a/include/mem_map_item.h
+++ b/include/mem_map_item.h
@@ -16,11 +16,14 @@
#ifndef MEMMAPITEM_H
#define MEMMAPITEM_H
+#include
+
#include
#include
-#include
-
+namespace OHOS {
+namespace Developtools {
+namespace HiPerf {
class MemMapItem {
public:
uint64_t begin_ = 0;
@@ -32,10 +35,15 @@ public:
uint64_t minor_ = 0;
ino_t inode = 0;
std::string name_;
+ std::string_view nameHold_;
MemMapItem() {}
MemMapItem(uint64_t begin, uint64_t end, uint64_t offset, const std::string &name)
- : begin_(begin), end_(end), pageoffset_(offset), name_(name)
+ : begin_(begin),
+ end_(end),
+ pageoffset_(offset),
+ name_(name),
+ nameHold_(MemoryHold::Get().HoldStringView(name))
{
}
@@ -87,4 +95,7 @@ public:
return addr >= begin_ and addr < end_;
}
};
-#endif
\ No newline at end of file
+} // namespace HiPerf
+} // namespace Developtools
+} // namespace OHOS
+#endif
diff --git a/include/perf_event_record.h b/include/perf_event_record.h
index 1f7067ff04d9122aa4d1b0fe4061c76fddfef633..09635d7189f02e9d8dd718c6d4afd7efff5c84c8 100755
--- a/include/perf_event_record.h
+++ b/include/perf_event_record.h
@@ -245,7 +245,9 @@ public:
bool GetBinary(std::vector &buf) const override;
virtual void DumpData(int indent = 0) const override;
virtual void DumpLog(const std::string &prefix) const override;
- void ReplaceWithCallStack();
+
+ // originalSize is use for expand callstack
+ void ReplaceWithCallStack(size_t originalSize = 0);
pid_t GetPid() const override;
// only for UT
diff --git a/include/perf_events.h b/include/perf_events.h
index 174b9c1e58b3bd07a137a22ecb772f7298a74700..5d25a42605d4efdc40d5697979c23448c58bf117 100755
--- a/include/perf_events.h
+++ b/include/perf_events.h
@@ -256,6 +256,7 @@ public:
void SetTimeOut(float timeOut);
void SetTimeReport(int);
void SetVerboseReport(bool);
+ bool AddOffCpuEvent();
inline void SetTrackedCommand(const std::vector &trackedCommand)
{
@@ -346,7 +347,6 @@ public:
};
static const std::string GetTypeName(perf_type_id type_id);
- bool CheckPermissions(PerfEventParanoid request = KERNEL_USER_CPU);
bool ParseEventName(const std::string &nameStr, std::string &name, bool &excludeUser,
bool &excludeKernel, bool &isTracePoint);
@@ -399,6 +399,16 @@ private:
bool HaveTargetsExit(const std::chrono::steady_clock::time_point &startTime);
void ExitReadRecordBufThread();
+ enum EventSpaceType {
+ UNKNOW = 0,
+ USER = 1,
+ KERNEL = 2,
+ USER_KERNEL = 3,
+ };
+ uint8_t eventSpaceType_ = EventSpaceType::UNKNOW;
+
+ PerfEventParanoid requestPermission_ = PerfEventParanoid::USER;
+ bool CheckPermissions(PerfEventParanoid request = KERNEL_USER_CPU);
bool CheckOhosPermissions();
static PerfEventParanoid perfEventParanoid_;
diff --git a/include/report_json_file.h b/include/report_json_file.h
index ec8a3ffb4494b07aac168b6af6baa55fd8f4da82..fa566a07c54d5b46dccc815e7fa7806fcc0f74c4 100755
--- a/include/report_json_file.h
+++ b/include/report_json_file.h
@@ -312,7 +312,7 @@ struct ReportConfigItem {
ReportConfigItem(int index, std::string eventName) : index_(index), eventName_(eventName) {}
};
-using functionKey = std::tuple;
+using functionKey = std::tuple;
static constexpr const int keyLibId = 0;
static constexpr const int keyfuncName = 1;
diff --git a/include/subcommand_record.h b/include/subcommand_record.h
index b2185fa92beeff43aa2dd3fe9d24159cda465bd4..ad5b6858e3ecfecfeadbd273a53775bd858c6671 100644
--- a/include/subcommand_record.h
+++ b/include/subcommand_record.h
@@ -23,7 +23,7 @@
#define HIDEBUG_SKIP_MATCH_SYMBOLS 0
#define HIDEBUG_SKIP_LOAD_KERNEL_SYMBOLS 0
#define HIDEBUG_SKIP_SAVE_SYMBOLS 0
-#define USE_COLLECT_SYMBOLIC
+#define USE_COLLECT_SYMBOLIC 1
#include
#include
@@ -122,7 +122,7 @@ public:
" --disable-unwind\n"
" If '-s dwarf' is used, stack will be unwind while recording by default\n"
" use this option to disable unwinding.\n"
- " --disable-callstack-expend\n"
+ " --disable-callstack-expand\n"
" If '-s dwarf' is used, to break the 64k stack limit, callstack is merged by default\n"
" to build more complete call stack. that may not be correct sometimes.\n"
" --clockid \n"
@@ -191,7 +191,7 @@ private:
std::vector selectTids_ = {};
std::vector selectEvents_ = {};
std::vector> selectGroups_ = {};
- std::vector sampleTypes_ = {};
+ std::vector callStackType_ = {};
std::vector vecBranchFilters_ = {};
std::vector trackedCommand_ = {};
@@ -201,9 +201,9 @@ private:
bool CheckSelectCpuPidOption();
bool GetOptionFrequencyAndPeriod(std::vector &args);
- bool dwarfCallchainSample_ = false;
- bool fpCallchainSample_ = false;
- uint32_t dwarfSampleStackSize_ = MAX_SAMPLE_STACK_SIZE;
+ bool isCallStackDwarf_ = false;
+ bool isCallStackFp_ = false;
+ uint32_t callStackDwarfSize_ = MAX_SAMPLE_STACK_SIZE;
uint64_t branchSampleType_ = 0;
uint64_t dataSizeLimit_ = 0;
bool isDataSizeLimitStop_ = false;
@@ -228,22 +228,9 @@ private:
bool WaitFifoReply(int fd);
void CloseClientThread();
- // just a debug test function
- bool AddSelectEvent(std::vector &events, bool groups = false);
-
- enum EventSpaceType {
- NONE = 0,
- USER = 1,
- KERNEL = 2,
- USER_KERNEL = 3,
- };
- uint8_t eventSpaceType_ = EventSpaceType::NONE;
- PerfEventParanoid request_ = PerfEventParanoid::USER;
- bool ParseEventList(std::vector &list);
- bool ParseGroupList(std::vector> &list);
bool PreparePerfEvent();
- bool PrepareSys();
- bool PrepareVR();
+ bool PrepareSysKernel();
+ bool PrepareVirtualRuntime();
size_t recordSamples_ = 0;
size_t recordNoSamples_ = 0;
@@ -277,7 +264,7 @@ private:
bool SetPerfMaxSampleRate();
bool TraceOffCpu();
- bool ParseCallStackOption(const std::vector &vecSampleTypes);
+ bool ParseCallStackOption(const std::vector &callStackType);
bool ParseDataLimitOption(const std::string &str);
bool ParseBranchSampleType(const std::vector &vecBranchSampleTypes);
bool ParseControlCmd(const std::string cmd);
@@ -287,7 +274,7 @@ private:
pid_t GetAppPackagePid(const std::string &appPackge);
VirtualRuntime virtualRuntime_;
-#ifdef USE_COLLECT_SYMBOLIC
+#if USE_COLLECT_SYMBOLIC
std::unordered_set kernelSymbolsHits_;
std::unordered_map> userSymbolsHits_;
void SymbolicHits();
diff --git a/include/subcommand_stat.h b/include/subcommand_stat.h
index 3cd805a7c0dbe82fb1a32580e8f7b23be9d4d82a..f08e72f427d0e561672e3a8ca472f92ad4b9ce3a 100644
--- a/include/subcommand_stat.h
+++ b/include/subcommand_stat.h
@@ -88,7 +88,6 @@ private:
bool verboseReport_ {false};
std::vector trackedCommand_ {};
bool helpOption_ {false};
- PerfEventParanoid request_ = USER;
bool CheckOptionPid(std::vector pids);
static bool FindEventCount(
const std::map> &countEvents,
@@ -113,8 +112,6 @@ private:
bool PrepairEvents();
bool CheckOptions(const std::vector &pids);
bool CheckSelectCpuPidOption();
- bool ParseEventList(std::vector &list);
- bool ParseGroupList(std::vector> &list);
};
bool RegisterSubCommandStat(void);
diff --git a/include/symbols_file.h b/include/symbols_file.h
index bc9fee3625d9786f7cc5339d51e5da46b66af429..3c8f74ad6c935c24f0e17f969d7e0e714f927277 100755
--- a/include/symbols_file.h
+++ b/include/symbols_file.h
@@ -92,7 +92,12 @@ struct Symbol {
// Symbolic use this
Symbol(uint64_t taskVaddr = 0, const std::string &comm = "")
- : taskVaddr_(taskVaddr), comm_(comm) {};
+ : taskVaddr_(taskVaddr), comm_(comm)
+ {
+ };
+
+ // copy
+ Symbol(const Symbol &other) = default;
static bool SameVaddr(const Symbol &a, const Symbol &b)
{
@@ -142,7 +147,8 @@ struct Symbol {
} else {
sstream << comm_ << "@0x" << std::hex << taskVaddr_;
}
- unknow_ = MemoryHold::Get().HoldStringView(sstream.str());
+ std::string hold = sstream.str();
+ unknow_ = MemoryHold::Get().HoldStringView(hold);
}
return unknow_;
}
@@ -170,6 +176,11 @@ struct Symbol {
sstream << demangle_ << "|";
sstream << name_ << "|";
sstream << (matched_ ? "matched" : "");
+ sstream << " unknowname:" << unknow_.size();
+ sstream << " task:" << (comm_.size() > 0 ? comm_ : "");
+ sstream << "@" << taskVaddr_;
+ sstream << " file:" << (module_.size() > 0 ? module_ : "");
+ sstream << "@" << fileVaddr_;
return sstream.str();
};
diff --git a/include/utilities.h b/include/utilities.h
index 04582273218586dd12ec939d8c658944a0f3553e..69fc4b1ddc6a2b15d3ff4a392b41311b7e9f65a1 100755
--- a/include/utilities.h
+++ b/include/utilities.h
@@ -195,7 +195,7 @@ std::string StringPrintf(const char *stringFormat, VA... args)
}
// print it to bytes
- if (snprintf_s(bytes, DEFAULT_STRING_BUF_SIZE, DEFAULT_STRING_BUF_SIZE - 1, stringFormat,
+ if (snprintf_s(bytes, sizeof(bytes), sizeof(bytes) - 1, stringFormat,
args...) < 0) {
return EMPTY_STRING;
}
diff --git a/interfaces/innerkits/native/include/hiperf_client.h b/interfaces/innerkits/native/include/hiperf_client.h
index 9f44c77c19f241b9f57129428f664025bda23f56..569dc5de7174f3d84436bf308cf8d5fa60ac9fa5 100644
--- a/interfaces/innerkits/native/include/hiperf_client.h
+++ b/interfaces/innerkits/native/include/hiperf_client.h
@@ -61,7 +61,7 @@ static const std::string ArgOffCPU = "--offcpu";
static const std::string ArgCallGraph = "--call-stack";
static const std::string ArgDelayUnwind = "--delay-unwind";
static const std::string ArgDisableUnwind = "--disable-unwind";
-static const std::string ArgDisableCallstackMerge = "--disable-callstack-expend";
+static const std::string ArgDisableCallstackMerge = "--disable-callstack-expand";
static const std::string ArgSymbolDir = "--symbol-dir";
static const std::string ArgOutputFilename = "-o";
static const std::string ArgDataLimit = "--data-limit";
diff --git a/ohos.build b/ohos.build
index faec9defe6e482c28c8807692260f4ae99726d43..87868c0f432665d52b560504d68cc310e35010c4 100644
--- a/ohos.build
+++ b/ohos.build
@@ -19,7 +19,7 @@
}
],
"test_list": [
- "//developtools/hiperf/test:hiperf_unittest"
+ "//developtools/hiperf/test:hiperf_test"
]
}
}
diff --git a/proto/build_proto.sh b/proto/build_proto.sh
index c2e2886ea583e499f9f6a451d21221509bf69971..407b54a226b66230f35577b5765bcbd4bc962299 100755
--- a/proto/build_proto.sh
+++ b/proto/build_proto.sh
@@ -27,10 +27,9 @@ protoc_cmdline=$*
echo protoc_cmdline $protoc_cmdline
# search one by bone
-PREBUILD_HOST_AOSP_RUNTIME=$BUILD_TOP/prebuilts/aosp_prebuilt_libs/host_tools/lib64
PREBUILD_HOST_CLANG_RUNTIME=$BUILD_TOP/prebuilts/clang/host/linux-x86/clang-r353983c/lib64
PREBUILD_OHOS_CLANG_RUNTIME=$BUILD_TOP/prebuilts/clang/ohos/linux-x86_64/llvm/lib
-export LD_LIBRARY_PATH=$PREBUILD_HOST_AOSP_RUNTIME:$PREBUILD_HOST_CLANG_RUNTIME:$PREBUILD_OHOS_CLANG_RUNTIME:$LD_LIBRARY_PATH
+export LD_LIBRARY_PATH=$PREBUILD_HOST_CLANG_RUNTIME:$PREBUILD_OHOS_CLANG_RUNTIME:$LD_LIBRARY_PATH
cmd="$protoc_cmdline"
echo $cmd
$cmd
diff --git a/script/report-diff.html b/script/report-diff.html
index 4c04270d409de97fdf29461471c5f61c2dbf8c2d..9e2e40d878e6c9944d8f6b4987021100cbd9cf1f 100755
--- a/script/report-diff.html
+++ b/script/report-diff.html
@@ -2539,7 +2539,7 @@ input{
if (rowElement.querySelector('.tree-icon')) {
rowElement.querySelector('.tree-icon').name = 'plus-square';
}
- rowElement.removeAttribute('expend');
+ rowElement.removeAttribute('expand');
};
const expendNode = (rowElement) => {
let id = rowElement.getAttribute('id');
@@ -2553,9 +2553,9 @@ input{
if (rowElement.querySelector('.tree-icon')) {
rowElement.querySelector('.tree-icon').name = 'minus-square';
}
- rowElement.setAttribute('expend', '');
+ rowElement.setAttribute('expand', '');
}
- if (rowElement.hasAttribute('expend')) {
+ if (rowElement.hasAttribute('expand')) {
foldNode(rowElement);
} else {
expendNode(rowElement);
@@ -2580,7 +2580,7 @@ input{
parentNode.append(rowElement);
rowElement.setAttribute('id', rowData[ids[0]]);
rowElement.setAttribute('pid', rowData[ids[1]]);
- rowElement.setAttribute('expend', '');
+ rowElement.setAttribute('expand', '');
if (rowData.children && rowData.children.length > 0) {
//有子节点的 前面加上 + 图标 表示可以展开节点
diff --git a/script/report.html b/script/report.html
index d1eab2414a36ad047f84b52055e4e557f709c325..2bf535d0cd7483c459d6aafe4194f2b34fe51065 100755
--- a/script/report.html
+++ b/script/report.html
@@ -2901,7 +2901,7 @@ input{
if (rowElement.querySelector('.tree-icon')) {
rowElement.querySelector('.tree-icon').name = 'plus-square';
}
- rowElement.removeAttribute('expend');
+ rowElement.removeAttribute('expand');
};
const expendNode = (rowElement) => {
let id = rowElement.getAttribute('id');
@@ -2915,9 +2915,9 @@ input{
if (rowElement.querySelector('.tree-icon')) {
rowElement.querySelector('.tree-icon').name = 'minus-square';
}
- rowElement.setAttribute('expend', '');
+ rowElement.setAttribute('expand', '');
}
- if (rowElement.hasAttribute('expend')) {
+ if (rowElement.hasAttribute('expand')) {
foldNode(rowElement);
} else {
expendNode(rowElement);
@@ -2942,7 +2942,7 @@ input{
parentNode.append(rowElement);
rowElement.setAttribute('id', rowData[ids[0]]);
rowElement.setAttribute('pid', rowData[ids[1]]);
- rowElement.setAttribute('expend', '');
+ rowElement.setAttribute('expand', '');
if (rowData.children && rowData.children.length > 0) {
//有子节点的 前面加上 + 图标 表示可以展开节点
diff --git a/src/callstack.cpp b/src/callstack.cpp
index d6a8554c0248c4247ca4d75dc82881d88dee104b..572a000a9dc5549bee59d406c0ce2b0f47571c14 100755
--- a/src/callstack.cpp
+++ b/src/callstack.cpp
@@ -510,7 +510,7 @@ void CallStack::LogFrame(const std::string msg, const std::vector &fr
/*
we should have CallStack cache for each thread
-
+end begin
0. A -> B -> C -> E -> F
1. C -> E -> F
2. B -> C
@@ -521,73 +521,90 @@ we should have CallStack cache for each thread
0 is our cache
1 2 3... is from record
-use expendLimit to setup how may frame match is needs
+use expandLimit to setup how may frame match is needs
*/
-size_t CallStack::ExpendCallStack(std::vector &newCallFrames,
- const std::vector &cachedCallFrames,
- size_t expendLimit)
+size_t CallStack::DoExpandCallStack(std::vector &newCallFrames,
+ const std::vector &cachedCallFrames,
+ size_t expandLimit)
{
int maxCycle = 0;
- HLOG_ASSERT(expendLimit != 0u);
- HLOG_ASSERT(newCallFrames.size() >= expendLimit);
- // begin is ip (Bottom), this will change when compare
- auto cachedIt = cachedCallFrames.begin(); // from begin
- // end is caller (Top) , this will not change when compare
- const auto newIt = std::prev(newCallFrames.end());
+ if (expandLimit == 0 or newCallFrames.size() < expandLimit or
+ cachedCallFrames.size() < expandLimit) {
+ HLOGM("expandLimit %zu not match new %zu cache %zu", expandLimit, newCallFrames.size(),
+ cachedCallFrames.size());
+ return 0; // size not enough
+ }
- HLOGDUMMY("find %s + %zu", newIt->ToString().c_str(), expendLimit);
+ // called (Stack Buttom) , this will NOT change when compare
+ // in case1 newIt -> C
+ // in case2 newIt -> B
+ const auto newIt = newCallFrames.end() - expandLimit;
- // first time earch
- cachedIt = find(cachedIt, cachedCallFrames.end(), *newIt);
+ HLOGM("try find new call chain bottom %s for limit %zu", newIt->ToString().c_str(),
+ expandLimit);
+
+ // first frame earch, from called - > caller
+ // for case 2 it should found B
+ ssize_t distances = expandLimit - 1;
+ auto cachedIt = find(cachedCallFrames.begin(), cachedCallFrames.end(), *newIt);
+ if (cachedIt == cachedCallFrames.end()) {
+ HLOGM("not found in first search");
+ }
// cache frame found
- while (std::distance(cachedIt, cachedCallFrames.end()) >=
- std::distance(newIt, newCallFrames.end())) {
- HLOG_ASSERT_MESSAGE(maxCycle++ < MAX_CALL_FRAME_EXPEND_CYCLE, "MAX_UNWIND_CYCLE = %d reach",
- MAX_CALL_FRAME_EXPEND_CYCLE);
+ while (std::distance(cachedIt, cachedCallFrames.end()) >= signed(expandLimit)) {
+ HLOG_ASSERT_MESSAGE(maxCycle++ < MAX_CALL_FRAME_EXPAND_CYCLE, "MAX_UNWIND_CYCLE = %d reach",
+ MAX_CALL_FRAME_EXPAND_CYCLE);
- if (std::equal(newIt, newIt + expendLimit - 1u, cachedIt)) {
- HLOGM("match %s + %zu", newIt->ToString().c_str(), expendLimit);
- cachedIt++;
+ if (std::equal(newIt, newIt + expandLimit, cachedIt)) {
+ HLOGM("match %s + %zu", newIt->ToString().c_str(), expandLimit);
+ cachedIt += expandLimit; // in while we check the boundary safe
if (cachedIt == cachedCallFrames.end()) {
- HLOGM("nothing need copy , the rest of the frame is the same");
+ // same but no more need expand
break;
}
- // expend the frame and make some log ?
+ // expand the frame and make some log ?
LogFrame("newCallStack:", newCallFrames);
LogFrame("cachedCallStack:", cachedCallFrames);
+
newCallFrames.insert(newCallFrames.end(), cachedIt, cachedCallFrames.end());
- HLOGV("merge callstack increse to %zu (+%zu) ", newCallFrames.size(),
- std::distance(cachedIt, cachedCallFrames.end()));
+ auto expands = std::distance(cachedIt, cachedCallFrames.end());
+ HLOGV("merge callstack increse to %zu (+%zd) ", newCallFrames.size(), expands);
// we done the deal
- return std::distance(cachedIt, cachedCallFrames.end());
+ return expands;
} else {
- // quick search again
- cachedIt = find(cachedIt, cachedCallFrames.end(), *newIt);
+ // quick search next same farme again
+ cachedIt++;
+ if (cachedIt != cachedCallFrames.end()) {
+ HLOGM("search next");
+ cachedIt = find(cachedIt, cachedCallFrames.end(), *newIt);
+ }
}
}
- return 0u; // nothing expend
+ HLOGM("cachedIt distance %zd , need %zd", std::distance(cachedCallFrames.begin(), cachedIt),
+ distances);
+ return 0u; // nothing expand
}
-size_t CallStack::ExpendCallStack(pid_t tid, std::vector &callFrames, size_t expendLimit)
+size_t CallStack::ExpandCallStack(pid_t tid, std::vector &callFrames, size_t expandLimit)
{
- size_t expend = 0u;
- if (expendLimit == 0) {
- return expend; // nothing need to do
- } else if (callFrames.size() < expendLimit) {
+ size_t expand = 0u;
+ if (expandLimit == 0) {
+ return expand; // nothing need to do
+ } else if (callFrames.size() < expandLimit) {
HLOGM("new callstack is too small, skip it");
- return expend;
+ return expand;
}
if (!cachedCallFramesMap_.count(tid)) {
- cachedCallFramesMap_[tid].reserve(MAX_CALL_FRAME_EXPEND_CACHE_SIZE);
+ cachedCallFramesMap_[tid].reserve(MAX_CALL_FRAME_EXPAND_CACHE_SIZE);
}
if (callFrames.size() >= 1u) {
// get top (Earliest caller)
HashList> &cachedCallFrames = cachedCallFramesMap_[tid];
- HLOGV("find call stack frames in cahce %zu", cachedCallFrames.size());
+ HLOGV("find call stack frames in cahce size %zu", cachedCallFrames.size());
// compare
using namespace std::rel_ops; // enable complement comparing operators
for (auto itr = cachedCallFrames.begin(); itr < cachedCallFrames.end(); ++itr) {
@@ -603,12 +620,12 @@ size_t CallStack::ExpendCallStack(pid_t tid, std::vector &callFrames,
4 insert A after B in new stack
*/
const std::vector &cachedCallStack = *itr;
- if (cachedCallStack.size() < expendLimit) {
+ if (cachedCallStack.size() < expandLimit) {
HLOGM("cache callstack is too small, skip it");
- break;
+ continue; // check next
}
- expend = ExpendCallStack(callFrames, cachedCallStack, expendLimit);
- if (expend > 0) {
+ expand = DoExpandCallStack(callFrames, cachedCallStack, expandLimit);
+ if (expand > 0) {
break;
}
}
@@ -617,8 +634,8 @@ size_t CallStack::ExpendCallStack(pid_t tid, std::vector &callFrames,
// vector
cachedCallFrames[callFrames[0].ip_] = callFrames;
}
- HLOGM("expend %zu", expend);
- return expend;
+ HLOGM("expand %zu", expand);
+ return expand;
}
CallStack::CallStack() {}
@@ -633,4 +650,4 @@ CallStack::~CallStack()
}
} // namespace HiPerf
} // namespace Developtools
-} // namespace OHOS
\ No newline at end of file
+} // namespace OHOS
diff --git a/src/command.cpp b/src/command.cpp
index 5d5a42e79b882f212440b8101a140c426033c3f6..ec8a6741563b3fb56d0b30f23787569370fe998e 100755
--- a/src/command.cpp
+++ b/src/command.cpp
@@ -40,7 +40,7 @@ bool Command::DispatchCommands(std::vector arguments)
arguments.erase(arguments.begin());
if (!commandOption->callBackFunction(arguments)) {
- printf("unknown options: %s\n", arguments.front().c_str());
+ printf("unknown options: %s\nUse the help command to view help.\n", arguments.front().c_str());
return false;
}
// goto next args
diff --git a/src/debug_logger.cpp b/src/debug_logger.cpp
index e3679f3174d330f155a7e306bc6ca616933ca05c..4a844a2bb3e3bbdbff381f7ec2af050d053df4a8 100755
--- a/src/debug_logger.cpp
+++ b/src/debug_logger.cpp
@@ -116,7 +116,7 @@ int DebugLogger::Log(DebugLevel level, const std::string &logTag, const char *fm
const auto startWriteTime = steady_clock::now();
#endif
milliseconds timeStamp = duration_cast(startTime - timeStamp_);
- fprintf(file_, "%05" PRId64 "ms %s", (uint64_t)timeStamp.count(), buffer.data()); // to the file
+ fprintf(file_, "%05" PRId64 "ms %s", (int64_t)timeStamp.count(), buffer.data()); // to the file
#ifdef HIPERF_DEBUG_TIME
logWriteTimes_ += duration_cast(steady_clock::now() - startWriteTime);
#endif
diff --git a/src/option_debug.cpp b/src/option_debug.cpp
index 51cf254bf7ef7631548b46f5cf8f184fe67ccef1..7ed67a363210f0420ee79abf19320498dc878165 100755
--- a/src/option_debug.cpp
+++ b/src/option_debug.cpp
@@ -19,6 +19,9 @@ namespace Developtools {
namespace HiPerf {
static bool OnVerboseLevel(const std::vector &debugLevel)
{
+ if (debugLevel.size() <= 0) {
+ return false;
+ }
DebugLogger::GetInstance()->SetLogLevel(LEVEL_VERBOSE);
DebugLogger::GetInstance()->Disable(false);
return true;
@@ -26,6 +29,9 @@ static bool OnVerboseLevel(const std::vector &debugLevel)
static bool OnMuchLevel(const std::vector &debugLevel)
{
+ if (debugLevel.size() <= 0) {
+ return false;
+ }
DebugLogger::GetInstance()->SetLogLevel(LEVEL_MUCH);
DebugLogger::GetInstance()->Disable(false);
return true;
@@ -33,6 +39,9 @@ static bool OnMuchLevel(const std::vector &debugLevel)
static bool OnDebugLevel(const std::vector &debugLevel)
{
+ if (debugLevel.size() <= 0) {
+ return false;
+ }
DebugLogger::GetInstance()->SetLogLevel(LEVEL_DEBUG);
DebugLogger::GetInstance()->Disable(false);
return true;
@@ -40,12 +49,18 @@ static bool OnDebugLevel(const std::vector &debugLevel)
static bool OnNoDebug(const std::vector &debugLevel)
{
+ if (debugLevel.size() <= 0) {
+ return false;
+ }
DebugLogger::GetInstance()->Disable();
return true;
}
static bool OnMixLogOutput(const std::vector &debugLevel)
{
+ if (debugLevel.size() <= 0) {
+ return false;
+ }
DebugLogger::GetInstance()->SetMixLogOutput(true);
return true;
}
@@ -55,6 +70,8 @@ static bool OnLogPath(std::vector &args)
if (args.size() > 0) {
DebugLogger::GetInstance()->SetLogPath(args[0]);
args.erase(args.begin());
+ } else {
+ return false;
}
return true;
}
@@ -64,6 +81,8 @@ static bool OnLogTag(std::vector &args)
if (args.size() > 0) {
DebugLogger::GetInstance()->SetLogTags(args[0]);
args.erase(args.begin());
+ } else {
+ return false;
}
return true;
}
@@ -76,19 +95,28 @@ static bool OnHiLog(const std::vector &args)
#endif
void RegisterMainCommandDebug()
{
- Option::RegisterMainOption("--nodebug", "disbale debug log", OnNoDebug);
- Option::RegisterMainOption("--debug", "show debug log", OnDebugLevel);
- Option::RegisterMainOption("--verbose", "show debug log", OnVerboseLevel);
- Option::RegisterMainOption("--much", "show extremely much debug log", OnMuchLevel);
- Option::RegisterMainOption("--mixlog", "mix the log in output", OnMixLogOutput);
- Option::RegisterMainOption("--logpath", "log file name full path", OnLogPath);
- Option::RegisterMainOption(
- "--logtag", "enable log level for HILOG_TAG, usage format: [:level][,[:level]]",
- OnLogTag);
+ Option::RegisterMainOption("--nodebug", "disbale debug log, usage format: --nodebug [command] [args]",
+ OnNoDebug);
+ Option::RegisterMainOption("--debug", "show debug log, usage format: --debug [command] [args]",
+ OnDebugLevel);
+ Option::RegisterMainOption("--verbose", "show debug log, usage format: --verbose [command] [args]",
+ OnVerboseLevel);
+ Option::RegisterMainOption("--much", "show extremely much debug log, usage format: --much [command] [args]",
+ OnMuchLevel);
+ Option::RegisterMainOption("--mixlog", "mix the log in output, usage format: --much [command] [args]",
+ OnMixLogOutput);
+ Option::RegisterMainOption("--logpath",
+ "log file name full path, usage format: --logpath [filepath] [command] [args]",
+ OnLogPath);
+ std::string tagUsage = StringPrintf("%s\t%-20s\t%s\t%-20s\t%s",
+ "enable log level for HILOG_TAG, usage format: --logtag [:level][,[:level]] [command] [args]\n", " ",
+ "tag: Dump, Report, Record, Stat... level: D, V, M...\n", " ",
+ "example: hiperf --verbose --logtag Record:D [command] [args]");
+ Option::RegisterMainOption("--logtag", tagUsage.c_str(), OnLogTag);
#if is_ohos && !is_double_framework
Option::RegisterMainOption("--hilog", "use hilog not file to record log", OnHiLog);
#endif
}
} // namespace HiPerf
} // namespace Developtools
-} // namespace OHOS
\ No newline at end of file
+} // namespace OHOS
diff --git a/src/perf_event_record.cpp b/src/perf_event_record.cpp
index f328e6d866661527ac97d81869ac95b9395a05d3..f0fae6c1a2951a480f7a5053165e82fe873a2033 100755
--- a/src/perf_event_record.cpp
+++ b/src/perf_event_record.cpp
@@ -159,20 +159,30 @@ void PerfRecordSample::DumpLog(const std::string &prefix) const
data_.reg_nr, data_.dyn_size, data_.time);
}
-void PerfRecordSample::ReplaceWithCallStack()
+void PerfRecordSample::ReplaceWithCallStack(size_t originalSize)
{
// first we check if we have some user unwind stack need to merge ?
if (callFrames_.size() != 0) {
// when we have some kernel ips , we cp it first
- // new size is user call frames + kernel call frames + PERF_CONTEXT_USER(last +1)
- ips_.reserve(callFrames_.size() + data_.nr + 1);
+ // new size is user call frames + kernel call frames
+ // + PERF_CONTEXT_USER(last + 1) + expand mark(also PERF_CONTEXT_USER)
+ const unsigned int perfContextSize = 2;
+ ips_.reserve(data_.nr + callFrames_.size() + perfContextSize);
if (data_.nr > 0) {
ips_.assign(data_.ips, data_.ips + data_.nr);
}
// add user context mark
ips_.emplace_back(PERF_CONTEXT_USER);
+ // we also need make a expand mark just for debug only
+ const size_t beginIpsSize = ips_.size();
bool ret = std::all_of(callFrames_.begin(), callFrames_.end(), [&](const CallFrame &frame) {
ips_.emplace_back(frame.ip_);
+ if (originalSize != 0 and (originalSize != callFrames_.size()) and
+ ips_.size() == (originalSize + beginIpsSize)) {
+ // just for debug
+ // so we can see which frame begin is expand call frames
+ ips_.emplace_back(PERF_CONTEXT_USER);
+ }
return true;
});
if (ret) {
@@ -343,9 +353,22 @@ void PerfRecordSample::DumpData(int indent) const
PrintIndent(indent, "period %lld\n", data_.period);
}
if (sampleType_ & PERF_SAMPLE_CALLCHAIN) {
+ bool userContext = false;
PrintIndent(indent, "callchain nr=%lld\n", data_.nr);
for (uint64_t i = 0; i < data_.nr; ++i) {
- PrintIndent(indent + 1, "0x%llx\n", data_.ips[i]);
+ std::string_view supplement = "";
+ if ((sampleType_ & PERF_SAMPLE_STACK_USER) == 0 || data_.ips[i] != PERF_CONTEXT_USER) {
+ PrintIndent(indent + 1, "0x%llx%s\n", data_.ips[i], supplement.data());
+ continue;
+ }
+ // is PERF_SAMPLE_STACK_USER type and is PERF_CONTEXT_USER
+ if (!userContext) {
+ userContext = true;
+ supplement = " ";
+ } else {
+ supplement = " ";
+ }
+ PrintIndent(indent + 1, "0x%llx%s\n", data_.ips[i], supplement.data());
}
}
if (sampleType_ & PERF_SAMPLE_RAW) {
@@ -855,4 +878,4 @@ void PerfRecordSwitchCpuWide::DumpData(int indent) const
}
} // namespace HiPerf
} // namespace Developtools
-} // namespace OHOS
\ No newline at end of file
+} // namespace OHOS
diff --git a/src/perf_events.cpp b/src/perf_events.cpp
index df333e83c8b87942e71e038ec32c323f4b900388..ffafa5548cc60e492cc3dd553f0bc10fb2b8908a 100755
--- a/src/perf_events.cpp
+++ b/src/perf_events.cpp
@@ -205,6 +205,17 @@ bool PerfEvents::AddDefaultEvent(perf_type_id type)
return true;
}
+bool PerfEvents::AddOffCpuEvent()
+{
+ std::string eventName = "sched:sched_switch";
+ if (eventSpaceType_ == EventSpaceType::USER) {
+ eventName += ":u";
+ } else if (eventSpaceType_ == EventSpaceType::KERNEL) {
+ eventName += ":k";
+ }
+ return AddEvent(eventName);
+}
+
bool PerfEvents::AddEvents(const std::vector &eventStrings, bool group)
{
bool followGroup = false;
@@ -290,6 +301,17 @@ bool PerfEvents::AddEvent(const std::string &eventString, bool followGroup)
if (!ParseEventName(eventString, eventName, excludeUser, excludeKernel, isTracePointEvent)) {
return false;
}
+ if (excludeUser) {
+ if (requestPermission_ > PerfEventParanoid::KERNEL_USER) {
+ requestPermission_ = PerfEventParanoid::KERNEL_USER;
+ }
+
+ eventSpaceType_ |= EventSpaceType::KERNEL;
+ } else if (excludeKernel) {
+ eventSpaceType_ |= EventSpaceType::USER;
+ } else {
+ eventSpaceType_ |= EventSpaceType::USER_KERNEL;
+ }
if (isTracePointEvent) {
if (PERF_TRACEPOINT_CONFIGS.empty()) {
@@ -471,6 +493,11 @@ static void RecoverCaptureSig()
bool PerfEvents::PrepareTracking(void)
{
HLOGV("enter");
+
+ if (!CheckPermissions(requestPermission_)) {
+ return false;
+ }
+
// 1. prepare cpu pid
if (!PrepareFdEvents()) {
HLOGE("PrepareFdEvents() failed");
@@ -682,6 +709,12 @@ void PerfEvents::SetSystemTarget(bool systemTarget)
void PerfEvents::SetCpu(std::vector cpus)
{
cpus_ = cpus;
+
+ if (!cpus_.empty()) {
+ if (requestPermission_ > PerfEventParanoid::KERNEL_USER_CPU) {
+ requestPermission_ = PerfEventParanoid::KERNEL_USER_CPU;
+ }
+ }
}
void PerfEvents::SetPid(std::vector pids)
diff --git a/src/report_json_file.cpp b/src/report_json_file.cpp
index 465d4047bb655b5aa95ef04fe4701293797e2079..70a80d5d28aa698ab96d8e09de9c498705381fbb 100755
--- a/src/report_json_file.cpp
+++ b/src/report_json_file.cpp
@@ -148,7 +148,7 @@ void ReportJsonFile::AddReportCallStackReverse(uint64_t eventCount, ReportCallNo
ReportCallNodeItem &grandchildren = GetOrCreateMapItem(*child, funcId);
if (debug_) {
grandchildren.nodeIndex_ = nodeIndex_++;
- grandchildren.funcName_ = std::get<1>(functionList_.at(funcId));
+ grandchildren.funcName_ = std::get(functionList_.at(funcId));
}
// only the last one need count
if (it + 1 == frames.rend()) {
diff --git a/src/ring_buffer.cpp b/src/ring_buffer.cpp
index 9cbdf6be1916010828278caf5f3ee431fcd4ab79..91a834397969cf11c71a152960533c47c227ba06 100755
--- a/src/ring_buffer.cpp
+++ b/src/ring_buffer.cpp
@@ -21,7 +21,12 @@
namespace OHOS {
namespace Developtools {
namespace HiPerf {
-RingBuffer::RingBuffer(size_t size) : buf_(new uint8_t[size]), size_(size) {}
+RingBuffer::RingBuffer(size_t size) : size_(size)
+{
+ if (size > 0) {
+ buf_ = std::make_unique(size);
+ }
+}
RingBuffer::~RingBuffer() {}
diff --git a/src/subcommand_dump.cpp b/src/subcommand_dump.cpp
index 86d80315d366f92a8e444edb78ca735242139164..cae2b0c60a5db7e2d964307b3640c7c093225816 100644
--- a/src/subcommand_dump.cpp
+++ b/src/subcommand_dump.cpp
@@ -242,6 +242,8 @@ void SubCommandDump::DumpPrintFileHeader(int indent)
// read here , because we need found symbols
reader_->ReadFeatureSection();
+ SetDeviceArch(GetArchTypeFromUname(reader_->GetFeatureString(FEATURE::ARCH)));
+
// found symbols in file
for (auto &featureSection : reader_->GetFeatureSections()) {
if (featureSection.get()->featureId_ == FEATURE::HIPERF_FILES_SYMBOL) {
@@ -396,7 +398,8 @@ void SubCommandDump::DumpCallChain(int indent, std::unique_ptr
indent += LEVEL1;
for (auto frameIt = sample->callFrames_.begin(); frameIt != sample->callFrames_.end();
frameIt++) {
- PrintIndent(indent, "%s\n", frameIt->ToSymbolString().c_str());
+ PrintIndent(indent, "%02zd:%s\n", std::distance(frameIt, sample->callFrames_.end()),
+ frameIt->ToSymbolString().c_str());
}
}
}
diff --git a/src/subcommand_help.cpp b/src/subcommand_help.cpp
index b51be5fd43b78556bc3330a2eb542ca9e98faa14..d49f0bd814dcaf604a324aede0ec49362de0f00a 100644
--- a/src/subcommand_help.cpp
+++ b/src/subcommand_help.cpp
@@ -25,7 +25,7 @@ namespace HiPerf {
bool SubCommandHelp::OnSubCommand(std::vector &args)
{
HLOGV("enter");
-
+ OnHelp(args);
return true;
}
@@ -40,9 +40,9 @@ bool SubCommandHelp::OnHelp(std::vector &args)
if (args.empty()) {
const auto &mainOptions = Option::GetMainOptions();
HLOGD("%zu options found:", mainOptions.size());
- printf("Usage: hiperf [options] COMMAND [args for command]\n");
+ printf("Usage: hiperf [options] command [args for command]\n");
- printf("Options:\n");
+ printf("options:\n");
for (const auto &commandOption : mainOptions) {
printf("\t%-20s\t%s\n", commandOption.first.c_str(),
commandOption.second->help.c_str());
@@ -50,11 +50,11 @@ bool SubCommandHelp::OnHelp(std::vector &args)
auto &commands = SubCommand::GetSubCommands();
HLOGD("%zu cmds found:", commands.size());
- printf("Command:\n");
+ printf("command:\n");
for (const auto &command : commands) {
printf("\t%s:\t%s\n", command.second->Name().c_str(), command.second->Brief().c_str());
}
- printf("\nSee 'hiperf help COMMAND' for more information on a specific command.\n\n");
+ printf("\nSee 'hiperf help [command]' for more information on a specific command.\n\n");
} else {
auto command = SubCommand::FindSubCommand(args.front());
if (command != nullptr) {
diff --git a/src/subcommand_record.cpp b/src/subcommand_record.cpp
index f39dbdba44dc5be48e0c9f3c10f1a693bdcd9aab..cfa270ec71fe03967bad6f39498151fff6458e1d 100644
--- a/src/subcommand_record.cpp
+++ b/src/subcommand_record.cpp
@@ -126,7 +126,7 @@ void SubCommandRecord::DumpOptions() const
printf(" clockId_:\t%s\n", clockId_.c_str());
printf(" mmapPages_:\t%d\n", mmapPages_);
printf(" dataLimit:\t%s\n", strLimit_.c_str());
- printf(" callStack:\t%s\n", VectorToString(sampleTypes_).c_str());
+ printf(" callStack:\t%s\n", VectorToString(callStackType_).c_str());
printf(" branchSampleTypes:\t%s\n", VectorToString(vecBranchFilters_).c_str());
printf(" trackedCommand:\t%s\n", VectorToString(trackedCommand_).c_str());
printf(" pipe_input:\t%d\n", clientPipeInput_);
@@ -156,7 +156,7 @@ bool SubCommandRecord::GetOptions(std::vector &args)
if (!Option::GetOptionValue(args, "--disable-unwind", disableUnwind_)) {
return false;
}
- if (!Option::GetOptionValue(args, "--disable-callstack-expend", disableCallstackExpend_)) {
+ if (!Option::GetOptionValue(args, "--disable-callstack-expand", disableCallstackExpend_)) {
return false;
}
if (!Option::GetOptionValue(args, "--verbose", verboseReport_)) {
@@ -201,21 +201,21 @@ bool SubCommandRecord::GetOptions(std::vector &args)
if (!Option::GetOptionValue(args, "-g", selectGroups_)) {
return false;
}
- if (!Option::GetOptionValue(args, "-s", sampleTypes_)) {
+ if (!Option::GetOptionValue(args, "-s", callStackType_)) {
return false;
}
- std::vector sampleTypesB = {};
- if (!Option::GetOptionValue(args, "--call-stack", sampleTypesB)) {
+ std::vector callStackType = {};
+ if (!Option::GetOptionValue(args, "--call-stack", callStackType)) {
return false;
}
- if (!sampleTypes_.empty()) {
- if (!sampleTypesB.empty()) {
+ if (!callStackType_.empty()) {
+ if (!callStackType.empty()) {
printf("'-s %s --call-stack %s' option usage error, please check usage.\n",
- VectorToString(sampleTypes_).c_str(), VectorToString(sampleTypesB).c_str());
+ VectorToString(callStackType_).c_str(), VectorToString(callStackType).c_str());
return false;
}
} else {
- sampleTypes_ = sampleTypesB;
+ callStackType_ = callStackType;
}
if (!Option::GetOptionValue(args, "--data-limit", strLimit_)) {
@@ -293,9 +293,6 @@ bool SubCommandRecord::CheckSelectCpuPidOption()
return false;
}
}
- if (request_ > PerfEventParanoid::KERNEL_USER_CPU) {
- request_ = PerfEventParanoid::KERNEL_USER_CPU;
- }
}
if (!selectPids_.empty()) {
@@ -346,15 +343,12 @@ bool SubCommandRecord::CheckOptions()
if (!CheckDataLimitOption()) {
return false;
}
- if (!ParseCallStackOption(sampleTypes_)) {
+ if (!ParseCallStackOption(callStackType_)) {
return false;
}
if (!ParseBranchSampleType(vecBranchFilters_)) {
return false;
}
- if (!ParseEventList(selectEvents_) || !ParseGroupList(selectGroups_)) {
- return false;
- }
if (!CheckSelectCpuPidOption()) {
return false;
}
@@ -367,40 +361,6 @@ bool SubCommandRecord::CheckOptions()
return true;
}
-bool SubCommandRecord::ParseEventList(std::vector &list)
-{
- for (auto &nameStr : list) {
- std::string name;
- bool excludeUser = false;
- bool excludeKernel = false;
- bool isTracePoint = false;
- if (!perfEvents_.ParseEventName(nameStr, name, excludeUser, excludeKernel, isTracePoint)) {
- return false;
- }
- if (excludeUser) {
- if (request_ > PerfEventParanoid::KERNEL_USER) {
- request_ = PerfEventParanoid::KERNEL_USER;
- }
- eventSpaceType_ |= EventSpaceType::KERNEL;
- } else if (excludeKernel) {
- eventSpaceType_ |= EventSpaceType::USER;
- } else {
- eventSpaceType_ |= EventSpaceType::USER_KERNEL;
- }
- }
- return true;
-}
-
-bool SubCommandRecord::ParseGroupList(std::vector> &list)
-{
- for (auto &evnetList : list) {
- if (!ParseEventList(evnetList)) {
- return false;
- }
- }
- return true;
-}
-
bool SubCommandRecord::ParseOption(std::vector &args)
{
HLOGV("enter");
@@ -543,47 +503,47 @@ bool SubCommandRecord::ParseDataLimitOption(const std::string &str)
return true;
}
-bool SubCommandRecord::ParseCallStackOption(const std::vector &vecSampleTypes)
+bool SubCommandRecord::ParseCallStackOption(const std::vector &callStackType)
{
- if (vecSampleTypes.empty()) {
+ if (callStackType.empty()) {
return true;
- } else if (vecSampleTypes[0] == "fp") {
- if (vecSampleTypes.size() != 1) {
- printf("Invalid -s value %s.\n", VectorToString(vecSampleTypes).c_str());
+ } else if (callStackType[0] == "fp") {
+ if (callStackType.size() != 1) {
+ printf("Invalid -s value %s.\n", VectorToString(callStackType).c_str());
return false;
}
- fpCallchainSample_ = true;
- } else if (vecSampleTypes[0] == "dwarf") {
- if (vecSampleTypes.size() > MAX_DWARF_CALL_CHAIN) {
- printf("Invalid -s value %s.\n", VectorToString(vecSampleTypes).c_str());
+ isCallStackFp_ = true;
+ } else if (callStackType[0] == "dwarf") {
+ if (callStackType.size() > MAX_DWARF_CALL_CHAIN) {
+ printf("Invalid -s value %s.\n", VectorToString(callStackType).c_str());
return false;
- } else if (vecSampleTypes.size() == MAX_DWARF_CALL_CHAIN) {
+ } else if (callStackType.size() == MAX_DWARF_CALL_CHAIN) {
try {
- dwarfSampleStackSize_ = std::stoul(vecSampleTypes.at(1));
+ callStackDwarfSize_ = std::stoul(callStackType.at(1));
} catch (...) {
printf("Invalid -s value, dwarf stack size, '%s' is illegal.\n",
- vecSampleTypes.at(1).c_str());
+ callStackType.at(1).c_str());
return false;
}
- if (dwarfSampleStackSize_ < MIN_SAMPLE_STACK_SIZE) {
+ if (callStackDwarfSize_ < MIN_SAMPLE_STACK_SIZE) {
printf("Invalid -s value, dwarf stack size, '%s' is too small.\n",
- vecSampleTypes.at(1).c_str());
+ callStackType.at(1).c_str());
return false;
}
- if (dwarfSampleStackSize_ > MAX_SAMPLE_STACK_SIZE) {
+ if (callStackDwarfSize_ > MAX_SAMPLE_STACK_SIZE) {
printf("Invalid -s value, dwarf stack size, '%s' is bigger than max value %d.\n",
- vecSampleTypes.at(1).c_str(), MAX_SAMPLE_STACK_SIZE);
+ callStackType.at(1).c_str(), MAX_SAMPLE_STACK_SIZE);
return false;
}
- if ((dwarfSampleStackSize_ & MASK_ALIGNED_8) != 0) {
+ if ((callStackDwarfSize_ & MASK_ALIGNED_8) != 0) {
printf("Invalid -s value, dwarf stack size, '%s' is not 8 byte aligned.\n",
- vecSampleTypes.at(1).c_str());
+ callStackType.at(1).c_str());
return false;
}
}
- dwarfCallchainSample_ = true;
+ isCallStackDwarf_ = true;
} else {
- printf("Invalid -s value '%s'.\n", vecSampleTypes.at(0).c_str());
+ printf("Invalid -s value '%s'.\n", callStackType.at(0).c_str());
return false;
}
return true;
@@ -675,9 +635,10 @@ bool SubCommandRecord::TraceOffCpu()
bool SubCommandRecord::PreparePerfEvent()
{
- if (!perfEvents_.CheckPermissions(request_)) {
- return false;
- }
+ // we need to notify perfEvents_ sampling mode by SetRecordCallBack first
+ auto processRecord = std::bind(&SubCommandRecord::ProcessRecord, this, std::placeholders::_1);
+ perfEvents_.SetRecordCallBack(processRecord);
+
perfEvents_.SetCpu(selectCpus_);
perfEvents_.SetPid(selectPids_); // Tids has insert Pids in CheckTargetProcessOptions()
@@ -685,11 +646,11 @@ bool SubCommandRecord::PreparePerfEvent()
perfEvents_.SetTimeOut(timeStopSec_);
perfEvents_.SetVerboseReport(verboseReport_);
perfEvents_.SetMmapPages(mmapPages_);
- if (fpCallchainSample_) {
+ if (isCallStackFp_) {
perfEvents_.SetSampleStackType(PerfEvents::SampleStackType::FP);
- } else if (dwarfCallchainSample_) {
+ } else if (isCallStackDwarf_) {
perfEvents_.SetSampleStackType(PerfEvents::SampleStackType::DWARF);
- perfEvents_.SetDwarfSampleStackSize(dwarfSampleStackSize_);
+ perfEvents_.SetDwarfSampleStackSize(callStackDwarfSize_);
}
if (!perfEvents_.SetBranchSampleType(branchSampleType_)) {
printf("branch sample %s is not supported\n", VectorToString(vecBranchFilters_).c_str());
@@ -714,24 +675,6 @@ bool SubCommandRecord::PreparePerfEvent()
selectEvents_.push_back("hw-cpu-cycles");
}
- // cpu off add after default event (we need both sched_switch and user selected events)
- if (offCPU_) {
- if (std::find(selectEvents_.begin(), selectEvents_.end(), "sched_switch") ==
- selectEvents_.end()) {
- // insert a sched_switch event to trace offcpu event
- if (eventSpaceType_ == EventSpaceType::USER_KERNEL) {
- selectEvents_.push_back("sched:sched_switch");
- } else if (eventSpaceType_ == EventSpaceType::KERNEL) {
- selectEvents_.push_back("sched:sched_switch:k");
- } else if (eventSpaceType_ == EventSpaceType::USER) {
- selectEvents_.push_back("sched:sched_switch:u");
- }
- } else {
- printf("--offcpu is not supported event sched_switch\n");
- return false;
- }
- }
-
if (!perfEvents_.AddEvents(selectEvents_)) {
HLOGE("Fail to AddEvents events");
return false;
@@ -742,11 +685,24 @@ bool SubCommandRecord::PreparePerfEvent()
return false;
}
}
+ // cpu off add after default event (we need both sched_switch and user selected events)
+ if (offCPU_) {
+ if (std::find(selectEvents_.begin(), selectEvents_.end(), "sched_switch") !=
+ selectEvents_.end()) {
+ printf("--offcpu is not supported event sched_switch\n");
+ return false;
+ }
+ // insert a sched_switch event to trace offcpu event
+ if (!perfEvents_.AddOffCpuEvent()) {
+ HLOGE("Fail to AddEOffCpuvent");
+ return false;
+ }
+ }
return true;
}
-bool SubCommandRecord::PrepareSys()
+bool SubCommandRecord::PrepareSysKernel()
{
if (!SetPerfMaxSampleRate()) {
HLOGE("Fail to call SetPerfMaxSampleRate(%d)", frequency_);
@@ -764,8 +720,11 @@ bool SubCommandRecord::PrepareSys()
return true;
}
-bool SubCommandRecord::PrepareVR()
+bool SubCommandRecord::PrepareVirtualRuntime()
{
+ auto saveRecord = std::bind(&SubCommandRecord::SaveRecord, this, std::placeholders::_1);
+ virtualRuntime_.SetRecordMode(saveRecord);
+
// do some config for virtualRuntime_
virtualRuntime_.SetCallStackExpend(disableCallstackExpend_ ? 0 : 1);
// these is same for virtual runtime
@@ -777,6 +736,12 @@ bool SubCommandRecord::PrepareVR()
}
}
+ // load vsdo first
+ virtualRuntime_.LoadVdso();
+
+ // prepare from kernel and ko
+ virtualRuntime_.UpdateKernelSpaceMaps();
+ virtualRuntime_.UpdateKernelModulesSpaceMaps();
return true;
}
@@ -1025,18 +990,8 @@ bool SubCommandRecord::OnSubCommand(std::vector &args)
return true;
}
- // we need do some record in CreateInitRecordFile , so we need set callback before it
- auto processRecord = std::bind(&SubCommandRecord::ProcessRecord, this, std::placeholders::_1);
- auto saveRecord = std::bind(&SubCommandRecord::SaveRecord, this, std::placeholders::_1);
-
- // two ways:
- // perfEvents_ -> processRecord -> virtualRuntime_ -> saveRecord
- // -> saveRecord
- perfEvents_.SetRecordCallBack(processRecord);
- virtualRuntime_.SetRecordMode(saveRecord);
-
// prepare PerfEvents
- if (!PrepareSys() || !PreparePerfEvent() || !PrepareVR()) {
+ if (!PrepareSysKernel() or !PreparePerfEvent()) {
return false;
}
@@ -1051,18 +1006,15 @@ bool SubCommandRecord::OnSubCommand(std::vector &args)
return false;
}
+ if (!PrepareVirtualRuntime()) {
+ return false;
+ }
+
// make a thread wait the other command
if (clientPipeOutput_ != -1) {
clientCommandHanle_ = std::thread(&SubCommandRecord::ClientCommandHandle, this);
}
- // load vsdo first
- virtualRuntime_.LoadVdso();
-
- // prepare from kernel and ko
- virtualRuntime_.UpdateKernelSpaceMaps();
- virtualRuntime_.UpdateKernelModulesSpaceMaps();
-
// start tracking
if (!perfEvents_.StartTracking(!isFifoServer_)) {
return false;
@@ -1072,16 +1024,14 @@ bool SubCommandRecord::OnSubCommand(std::vector &args)
if (!FinishWriteRecordFile()) {
HLOGE("Fail to finish record file %s", outputFilename_.c_str());
return false;
- }
-
- // post process record file
- if (!PostProcessRecordFile()) {
+ } else if (!PostProcessRecordFile()) {
HLOGE("Fail to post process record file");
return false;
}
// finial report
RecordCompleted();
+
CloseClientThread();
return true;
}
@@ -1405,8 +1355,8 @@ bool SubCommandRecord::PostProcessRecordFile()
}
return true;
}
-#define USE_COLLECT_SYMBOLIC
+#if USE_COLLECT_SYMBOLIC
void SubCommandRecord::SymbolicHits()
{
for (auto &vaddr : kernelSymbolsHits_) {
@@ -1420,12 +1370,13 @@ void SubCommandRecord::SymbolicHits()
}
}
}
+#endif
bool SubCommandRecord::CollectionSymbol(std::unique_ptr record)
{
if (record->GetType() == PERF_RECORD_SAMPLE) {
PerfRecordSample *sample = static_cast(record.get());
-#ifdef USE_COLLECT_SYMBOLIC
+#if USE_COLLECT_SYMBOLIC
perf_callchain_context context = record->inKernel() ? PERF_CONTEXT_KERNEL
: PERF_CONTEXT_USER;
// if no nr use ip
@@ -1475,7 +1426,7 @@ bool SubCommandRecord::FinishWriteRecordFile()
HLOGD("Load user symbols");
fileWriter_->ReadDataSection(
std::bind(&SubCommandRecord::CollectionSymbol, this, std::placeholders::_1));
-#ifdef USE_COLLECT_SYMBOLIC
+#if USE_COLLECT_SYMBOLIC
SymbolicHits();
#endif
HLOGD("Write the symbols to perf.data");
diff --git a/src/subcommand_stat.cpp b/src/subcommand_stat.cpp
index 645250f9f787221ef6173bd092b1b40564fb2be5..956cf05295ed496c12598bf80a52d6e78f34e2a1 100644
--- a/src/subcommand_stat.cpp
+++ b/src/subcommand_stat.cpp
@@ -13,6 +13,8 @@
* limitations under the License.
*/
+#define HILOG_TAG "Stat"
+
#include
#include
#include
@@ -144,13 +146,14 @@ bool SubCommandStat::FindEventCount(
const std::string &configName, const __u64 group_id, __u64 &eventCount, double &scale)
{
auto itr = countEvents.find(configName);
- if (itr != countEvents.end() && itr->second->id == group_id) {
- if (itr->second->time_running < itr->second->time_enabled &&
- itr->second->time_running != 0) {
+ if (itr != countEvents.end()) {
+ eventCount = itr->second->eventCount;
+ if (itr->second->id == group_id
+ && itr->second->time_running < itr->second->time_enabled
+ && itr->second->time_running != 0) {
scale = static_cast(itr->second->time_enabled) / itr->second->time_running;
+ return true;
}
- eventCount = itr->second->eventCount;
- return true;
}
return false;
}
@@ -306,33 +309,6 @@ bool SubCommandStat::CheckOptionPid(std::vector pids)
return true;
}
-bool SubCommandStat::ParseEventList(std::vector &list)
-{
- for (auto &nameStr : list) {
- std::string name;
- bool isUser = false;
- bool isKernel = false;
- bool isTracePoint = false;
- if (!perfEvents_.ParseEventName(nameStr, name, isKernel, isUser, isTracePoint)) {
- return false;
- }
- if (isKernel) {
- request_ = KERNEL_USER;
- }
- }
- return true;
-}
-
-bool SubCommandStat::ParseGroupList(std::vector> &list)
-{
- for (auto &evnetList : list) {
- if (!ParseEventList(evnetList)) {
- return false;
- }
- }
- return true;
-}
-
bool SubCommandStat::OnSubCommand(std::vector &args)
{
HLOGV("enter");
@@ -367,10 +343,6 @@ bool SubCommandStat::OnSubCommand(std::vector &args)
printf("-t stat events on existing thread id\n");
return false;
}
- // check event
- if (!ParseGroupList(selectEvents_) || !ParseGroupList(selectGroups_)) {
- return false;
- }
perfEvents_.SetSystemTarget(targetSystemWide_);
perfEvents_.SetTimeOut(timeStopSec_);
perfEvents_.SetTimeReport(timeReportMs_);
@@ -401,9 +373,6 @@ bool RegisterSubCommandStat()
bool SubCommandStat::PrepairEvents()
{
- if (!perfEvents_.CheckPermissions(request_)) {
- return false;
- }
if (selectEvents_.empty() && selectGroups_.empty()) {
perfEvents_.AddDefaultEvent(PERF_TYPE_HARDWARE);
perfEvents_.AddDefaultEvent(PERF_TYPE_SOFTWARE);
@@ -436,7 +405,6 @@ bool SubCommandStat::CheckSelectCpuPidOption()
return false;
}
}
- request_ = KERNEL_USER_CPU;
}
} else {
// the cpu default -1
diff --git a/src/symbols_file.cpp b/src/symbols_file.cpp
index 0b0ef4d0ea98152acaf509fc68d0299223d534d2..ddcc531295ac5074b527b7230d107ee4936382fc 100755
--- a/src/symbols_file.cpp
+++ b/src/symbols_file.cpp
@@ -981,7 +981,7 @@ public:
const auto thisTime = std::chrono::steady_clock::now();
const auto usedTimeMsTick =
std::chrono::duration_cast(thisTime - startTime);
- HLOGV("Load kernel symbols (total %" PRId64 " ms)\n", (uint64_t)usedTimeMsTick.count());
+ HLOGV("Load kernel symbols (total %" PRId64 " ms)\n", (int64_t)usedTimeMsTick.count());
// load complete
return true;
}
diff --git a/src/virtual_runtime.cpp b/src/virtual_runtime.cpp
index 22928f8f46a39968947033d0eed070210c325323..48d2d123f3110088971557018b920d4219c94fb5 100755
--- a/src/virtual_runtime.cpp
+++ b/src/virtual_runtime.cpp
@@ -300,6 +300,7 @@ void VirtualRuntime::MakeCallFrame(Symbol &symbol, CallFrame &callFrame)
callFrame.symbolName_ = symbol.Name();
callFrame.symbolIndex_ = symbol.index_;
callFrame.filePath_ = symbol.module_.empty() ? symbol.comm_ : symbol.module_;
+ HLOG_ASSERT_MESSAGE(!callFrame.symbolName_.empty(), "%s", symbol.ToDebugString().c_str());
}
void VirtualRuntime::SymbolicCallFrame(PerfRecordSample &recordSample, uint64_t ip,
@@ -362,11 +363,12 @@ void VirtualRuntime::UnwindFromRecord(PerfRecordSample &recordSample)
#endif
size_t oldSize = recordSample.callFrames_.size();
HLOGV("unwind %zu", recordSample.callFrames_.size());
- callstack_.ExpendCallStack(thread.tid_, recordSample.callFrames_, callstackMergeLevel_);
- HLOGV("expend %zu (+%zu)", recordSample.callFrames_.size(),
+ callstack_.ExpandCallStack(thread.tid_, recordSample.callFrames_, callstackMergeLevel_);
+ HLOGV("expand %zu (+%zu)", recordSample.callFrames_.size(),
recordSample.callFrames_.size() - oldSize);
+
+ recordSample.ReplaceWithCallStack(oldSize);
}
- recordSample.ReplaceWithCallStack();
#ifdef HIPERF_DEBUG_TIME
unwindFromRecordTimes_ += duration_cast(steady_clock::now() - startTime);
@@ -521,7 +523,7 @@ const Symbol VirtualRuntime::GetUserSymbol(uint64_t ip, const VirtualThread &thr
if (symbolsFile != nullptr) {
vaddrSymbol.fileVaddr_ =
symbolsFile->GetVaddrInSymbols(ip, mmap->begin_, mmap->pageoffset_);
- vaddrSymbol.module_ = mmap->name_;
+ vaddrSymbol.module_ = mmap->nameHold_;
HLOGV("found symbol vaddr 0x%" PRIx64 " for runtime vaddr 0x%" PRIx64 " at '%s'",
vaddrSymbol.fileVaddr_, ip, mmap->name_.c_str());
if (!symbolsFile->SymbolsLoaded()) {
@@ -557,13 +559,14 @@ bool VirtualRuntime::GetSymbolCache(uint64_t ip, pid_t pid, pid_t tid, Symbol &s
}
Symbol &foundSymbol = kernelSymbolCache_[ip];
foundSymbol.hit_++;
- HLOGM("hit kernel cache 0x%" PRIx64 " %d", ip, foundSymbol.hit_);
+ HLOGV("hit kernel cache 0x%" PRIx64 " %d", ip, foundSymbol.hit_);
symbol = foundSymbol;
return true;
- } else if (threadSymbolCache_[tid].count(ip)) {
+ } else if (threadSymbolCache_[tid].count(ip) != 0) {
Symbol &foundSymbol = threadSymbolCache_[tid][ip];
foundSymbol.hit_++;
- HLOGM("hit user cache 0x%" PRIx64 " %d", ip, foundSymbol.hit_);
+ HLOGV("hit user cache 0x%" PRIx64 " %d %s", ip, foundSymbol.hit_,
+ foundSymbol.ToDebugString().c_str());
symbol = foundSymbol;
return true;
} else {
@@ -575,9 +578,9 @@ bool VirtualRuntime::GetSymbolCache(uint64_t ip, pid_t pid, pid_t tid, Symbol &s
const Symbol VirtualRuntime::GetSymbol(uint64_t ip, pid_t pid, pid_t tid,
const perf_callchain_context &context)
{
- HLOGM("try find tid %u ip 0x%" PRIx64 " in %zu symbolsFiles ", tid, ip, symbolsFiles_.size());
+ HLOGV("try find tid %u ip 0x%" PRIx64 " in %zu symbolsFiles ", tid, ip, symbolsFiles_.size());
Symbol symbol;
- if (!threadSymbolCache_.count(tid)) {
+ if (threadSymbolCache_.find(tid) == threadSymbolCache_.end()) {
threadSymbolCache_[tid].reserve(THREAD_SYMBOL_CACHE_LIMIT);
}
if (GetSymbolCache(ip, pid, tid, symbol, context)) {
@@ -587,6 +590,8 @@ const Symbol VirtualRuntime::GetSymbol(uint64_t ip, pid_t pid, pid_t tid,
// check userspace memmap
symbol = GetUserSymbol(ip, GetThread(pid, tid));
threadSymbolCache_[tid][ip] = symbol;
+ HLOGV("cache ip 0x%" PRIx64 " to %s", ip,
+ threadSymbolCache_[tid][ip].ToDebugString().c_str());
}
if (context == PERF_CONTEXT_KERNEL or (context == PERF_CONTEXT_MAX and !symbol.isValid())) {
diff --git a/test/BUILD.gn b/test/BUILD.gn
index 67d749e4a176b48eeb5c4612b69f9a007331f906..5334ee5134ab582dfde13b30621896c33a6cbf71 100644
--- a/test/BUILD.gn
+++ b/test/BUILD.gn
@@ -180,14 +180,10 @@ group("hiperf_test") {
":hiperf_fuzztest(${host_toolchain})",
":hiperf_unittest(${host_toolchain})",
]
- } else if (hiperf_test_fuzz){
- deps = [
- ":hiperf_fuzztest",
- ":hiperf_unittest",
- ]
} else {
- deps = [
- ":hiperf_unittest",
- ]
+ deps = [ ":hiperf_unittest" ]
+ }
+ if (hiperf_test_fuzz) {
+ deps += [ ":hiperf_fuzztest" ]
}
}
diff --git a/test/unittest/common/native/callstack_test.cpp b/test/unittest/common/native/callstack_test.cpp
index a508efd0206dcbb808f445a4907b0565a83c8571..7fb0f9b965eb3708c4edda3be88b8a699530d531 100755
--- a/test/unittest/common/native/callstack_test.cpp
+++ b/test/unittest/common/native/callstack_test.cpp
@@ -16,6 +16,7 @@
#include "callstack_test.h"
using namespace testing::ext;
+using namespace testing;
using namespace std;
using namespace OHOS::HiviewDFX;
namespace OHOS {
@@ -46,7 +47,7 @@ void CallStackTest::SetUp() {}
void CallStackTest::TearDown() {}
/**
- * @tc.name: ExpendCallStack
+ * @tc.name: ExpandCallStack
* @tc.desc:
* @tc.type: FUNC
*/
@@ -56,7 +57,7 @@ HWTEST_F(CallStackTest, ExpendCallStackEmpty, TestSize.Level1)
3 2 1
cache A -> B -> C
new C
- expend A -> B -> C
+ expand A -> B -> C
*/
ScopeDebugLevel tempLogLevel(LEVEL_MUCH);
CallStack callStack;
@@ -68,13 +69,13 @@ HWTEST_F(CallStackTest, ExpendCallStackEmpty, TestSize.Level1)
};
std::vector stack2 = {};
- ASSERT_EQ(callStack.ExpendCallStack(0, stack1), 0u);
- ASSERT_EQ(callStack.ExpendCallStack(0, stack2), 0u);
+ ASSERT_EQ(callStack.ExpandCallStack(0, stack1), 0u);
+ ASSERT_EQ(callStack.ExpandCallStack(0, stack2), 0u);
ASSERT_NE(stack1, stack2);
}
/**
- * @tc.name: ExpendCallStack
+ * @tc.name: ExpandCallStack
* @tc.desc:
* @tc.type: FUNC
*/
@@ -84,7 +85,7 @@ HWTEST_F(CallStackTest, ExpendCallStackC, TestSize.Level1)
3 2 1
cache A -> B -> C
new C
- expend A -> B -> C
+ expand A -> B -> C
*/
ScopeDebugLevel tempLogLevel(LEVEL_MUCH);
CallStack callStack;
@@ -98,13 +99,13 @@ HWTEST_F(CallStackTest, ExpendCallStackC, TestSize.Level1)
{0x1u, 0x1u},
};
- ASSERT_EQ(callStack.ExpendCallStack(0, stack1), 0u);
- ASSERT_EQ(callStack.ExpendCallStack(0, stack2), 2u);
+ ASSERT_EQ(callStack.ExpandCallStack(0, stack1), 0u);
+ ASSERT_EQ(callStack.ExpandCallStack(0, stack2), 2u);
ASSERT_EQ(stack1, stack2);
}
/**
- * @tc.name: ExpendCallStack
+ * @tc.name: ExpandCallStack
* @tc.desc:
* @tc.type: FUNC
*/
@@ -114,7 +115,7 @@ HWTEST_F(CallStackTest, ExpendCallStackBC, TestSize.Level1)
3 2 1
cache A -> B -> C
new B -> C
- expend A -> B -> C
+ expand A -> B -> C
*/
ScopeDebugLevel tempLogLevel(LEVEL_MUCH);
CallStack callStack;
@@ -129,13 +130,13 @@ HWTEST_F(CallStackTest, ExpendCallStackBC, TestSize.Level1)
{0x2u, 0x2u},
};
- ASSERT_EQ(callStack.ExpendCallStack(0, stack1), 0u);
- ASSERT_EQ(callStack.ExpendCallStack(0, stack2), 1u);
+ ASSERT_EQ(callStack.ExpandCallStack(0, stack1), 0u);
+ ASSERT_EQ(callStack.ExpandCallStack(0, stack2), 1u);
ASSERT_EQ(stack1, stack2);
}
/**
- * @tc.name: ExpendCallStack
+ * @tc.name: ExpandCallStack
* @tc.desc:
* @tc.type: FUNC
*/
@@ -145,7 +146,7 @@ HWTEST_F(CallStackTest, ExpendCallStackABC, TestSize.Level1)
3 2 1
cache A -> B -> C
new A -> B -> C
- expend A -> B -> C
+ expand A -> B -> C
*/
ScopeDebugLevel tempLogLevel(LEVEL_MUCH);
CallStack callStack;
@@ -161,13 +162,13 @@ HWTEST_F(CallStackTest, ExpendCallStackABC, TestSize.Level1)
{0x3u, 0x3u},
};
- ASSERT_EQ(callStack.ExpendCallStack(0, stack1), 0u);
- ASSERT_EQ(callStack.ExpendCallStack(0, stack2), 0u);
+ ASSERT_EQ(callStack.ExpandCallStack(0, stack1), 0u);
+ ASSERT_EQ(callStack.ExpandCallStack(0, stack2), 0u);
ASSERT_EQ(stack1, stack2);
}
/**
- * @tc.name: ExpendCallStack
+ * @tc.name: ExpandCallStack
* @tc.desc:
* @tc.type: FUNC
*/
@@ -177,7 +178,7 @@ HWTEST_F(CallStackTest, ExpendCallStackAB, TestSize.Level1)
3 2 1
cache A -> B -> C
new A -> B
- expend A -> B
+ expand A -> B
*/
ScopeDebugLevel tempLogLevel(LEVEL_MUCH);
CallStack callStack;
@@ -192,13 +193,13 @@ HWTEST_F(CallStackTest, ExpendCallStackAB, TestSize.Level1)
{0x3u, 0x3u},
};
- ASSERT_EQ(callStack.ExpendCallStack(0, stack1), 0u);
- ASSERT_EQ(callStack.ExpendCallStack(0, stack2), 0u);
+ ASSERT_EQ(callStack.ExpandCallStack(0, stack1), 0u);
+ ASSERT_EQ(callStack.ExpandCallStack(0, stack2), 0u);
ASSERT_NE(stack1, stack2);
}
/**
- * @tc.name: ExpendCallStack
+ * @tc.name: ExpandCallStack
* @tc.desc:
* @tc.type: FUNC
*/
@@ -208,7 +209,7 @@ HWTEST_F(CallStackTest, ExpendCallStackA, TestSize.Level1)
3 2 1
cache A -> B -> C
new A
- expend A
+ expand A
*/
ScopeDebugLevel tempLogLevel(LEVEL_MUCH);
CallStack callStack;
@@ -222,13 +223,13 @@ HWTEST_F(CallStackTest, ExpendCallStackA, TestSize.Level1)
{0x3u, 0x3u},
};
- ASSERT_EQ(callStack.ExpendCallStack(0, stack1), 0u);
- ASSERT_EQ(callStack.ExpendCallStack(0, stack2), 0u);
+ ASSERT_EQ(callStack.ExpandCallStack(0, stack1), 0u);
+ ASSERT_EQ(callStack.ExpandCallStack(0, stack2), 0u);
ASSERT_NE(stack1, stack2);
}
/**
- * @tc.name: ExpendCallStack
+ * @tc.name: ExpandCallStack
* @tc.desc:
* @tc.type: FUNC
*/
@@ -238,7 +239,7 @@ HWTEST_F(CallStackTest, ExpendCallStackB, TestSize.Level1)
3 2 1
cache A -> B -> C
new B
- expend A -> B
+ expand A -> B
*/
ScopeDebugLevel tempLogLevel(LEVEL_MUCH);
CallStack callStack;
@@ -255,14 +256,14 @@ HWTEST_F(CallStackTest, ExpendCallStackB, TestSize.Level1)
{0x2u, 0x2u},
{0x3u, 0x3u},
};
- ASSERT_EQ(callStack.ExpendCallStack(0, stack1), 0u);
- ASSERT_EQ(callStack.ExpendCallStack(0, stack2), 1u);
+ ASSERT_EQ(callStack.ExpandCallStack(0, stack1), 0u);
+ ASSERT_EQ(callStack.ExpandCallStack(0, stack2), 1u);
ASSERT_NE(stack1, stack2);
ASSERT_EQ(stack3, stack2);
}
/**
- * @tc.name: ExpendCallStack
+ * @tc.name: ExpandCallStack
* @tc.desc:
* @tc.type: FUNC
*/
@@ -272,7 +273,7 @@ HWTEST_F(CallStackTest, ExpendCallStackB2, TestSize.Level1)
3 2 1
cache A -> B -> C
new B
- expend A -> B
+ expand A -> B
*/
ScopeDebugLevel tempLogLevel(LEVEL_MUCH);
CallStack callStack;
@@ -289,14 +290,14 @@ HWTEST_F(CallStackTest, ExpendCallStackB2, TestSize.Level1)
{0x2u, 0x2u},
{0x3u, 0x3u},
};
- ASSERT_EQ(callStack.ExpendCallStack(0, stack1, 2), 0u);
- ASSERT_EQ(callStack.ExpendCallStack(0, stack2, 2), 0u);
+ ASSERT_EQ(callStack.ExpandCallStack(0, stack1, 2), 0u);
+ ASSERT_EQ(callStack.ExpandCallStack(0, stack2, 2), 0u);
ASSERT_NE(stack1, stack2);
ASSERT_NE(stack3, stack2);
}
/**
- * @tc.name: ExpendCallStack
+ * @tc.name: ExpandCallStack
* @tc.desc:
* @tc.type: FUNC
*/
@@ -306,7 +307,7 @@ HWTEST_F(CallStackTest, ExpendCallStackB0, TestSize.Level1)
3 2 1
cache A -> B -> C
new B
- expend A -> B
+ expand A -> B
*/
ScopeDebugLevel tempLogLevel(LEVEL_MUCH);
CallStack callStack;
@@ -323,14 +324,14 @@ HWTEST_F(CallStackTest, ExpendCallStackB0, TestSize.Level1)
{0x2u, 0x2u},
{0x3u, 0x3u},
};
- ASSERT_EQ(callStack.ExpendCallStack(0, stack1, 0), 0u);
- ASSERT_EQ(callStack.ExpendCallStack(0, stack2, 0), 0u);
+ ASSERT_EQ(callStack.ExpandCallStack(0, stack1, 0), 0u);
+ ASSERT_EQ(callStack.ExpandCallStack(0, stack2, 0), 0u);
ASSERT_NE(stack1, stack2);
ASSERT_NE(stack3, stack2);
}
/**
- * @tc.name: ExpendCallStack
+ * @tc.name: ExpandCallStack
* @tc.desc:
* @tc.type: FUNC
*/
@@ -340,9 +341,9 @@ HWTEST_F(CallStackTest, ExpendCallStackBC2, TestSize.Level1)
3 2 1
cache A -> B -> C
new B -> C
- expend A -> B -> C
+ expand A -> B -> C
*/
- ScopeDebugLevel tempLogLevel(LEVEL_MUCH);
+ ScopeDebugLevel tempLogLevel(LEVEL_MUCH, true);
CallStack callStack;
std::vector stack1 = {
@@ -355,13 +356,13 @@ HWTEST_F(CallStackTest, ExpendCallStackBC2, TestSize.Level1)
{0x2u, 0x2u},
};
- ASSERT_EQ(callStack.ExpendCallStack(0, stack1, 2), 0u);
- ASSERT_EQ(callStack.ExpendCallStack(0, stack2, 2), 1u);
+ ASSERT_EQ(callStack.ExpandCallStack(0, stack1, 2), 0u);
+ ASSERT_EQ(callStack.ExpandCallStack(0, stack2, 2), 1u);
ASSERT_EQ(stack1, stack2);
}
/**
- * @tc.name: ExpendCallStack
+ * @tc.name: ExpandCallStack
* @tc.desc:
* @tc.type: FUNC
*/
@@ -400,17 +401,17 @@ HWTEST_F(CallStackTest, ExpendCallStackABCDE, TestSize.Level1)
{0xB, 0xB},
};
- ASSERT_EQ(callStack.ExpendCallStack(0, stackFull), 0u);
- ASSERT_EQ(callStack.ExpendCallStack(0, stackBC), 1u);
- ASSERT_EQ(callStack.ExpendCallStack(0, stackABC), 0u);
- ASSERT_EQ(callStack.ExpendCallStack(0, stackBFF), 1u);
+ ASSERT_EQ(callStack.ExpandCallStack(0, stackFull), 0u);
+ ASSERT_EQ(callStack.ExpandCallStack(0, stackBC), 1u);
+ ASSERT_EQ(callStack.ExpandCallStack(0, stackABC), 0u);
+ ASSERT_EQ(callStack.ExpandCallStack(0, stackBFF), 1u);
// use stackBFF
- ASSERT_EQ(callStack.ExpendCallStack(0, stackBFF2, 2), 1u);
+ ASSERT_EQ(callStack.ExpandCallStack(0, stackBFF2, 2), 1u);
}
/**
- * @tc.name: ExpendCallStack
+ * @tc.name: ExpandCallStack
* @tc.desc:
* @tc.type: FUNC
*/
@@ -436,12 +437,12 @@ HWTEST_F(CallStackTest, ExpendCallStackFailure, TestSize.Level1)
{0xD, 0xD},
};
- ASSERT_EQ(callStack.ExpendCallStack(0, stackFull), 0u);
- ASSERT_EQ(callStack.ExpendCallStack(0, stackDE), 0u);
+ ASSERT_EQ(callStack.ExpandCallStack(0, stackFull), 0u);
+ ASSERT_EQ(callStack.ExpandCallStack(0, stackDE), 0u);
}
/**
- * @tc.name: ExpendCallStack
+ * @tc.name: ExpandCallStack
* @tc.desc:
* @tc.type: FUNC
*/
@@ -471,28 +472,28 @@ HWTEST_F(CallStackTest, ExpendCallStackTwoChance, TestSize.Level1)
{0xC, 0xC},
{0x2, 0x2},
};
- ASSERT_EQ(callStack.ExpendCallStack(0, stack0), 0u);
- ASSERT_EQ(callStack.ExpendCallStack(0, stack1), 0u);
- ASSERT_EQ(callStack.ExpendCallStack(0, stackC), 1u);
+ ASSERT_EQ(callStack.ExpandCallStack(0, stack0), 0u);
+ ASSERT_EQ(callStack.ExpandCallStack(0, stack1), 0u);
+ ASSERT_EQ(callStack.ExpandCallStack(0, stackC), 1u);
}
/**
- * @tc.name: ExpendCallStack
+ * @tc.name: ExpandCallStack
* @tc.desc:
* @tc.type: FUNC
*/
HWTEST_F(CallStackTest, ExpendCallStackFullCache, TestSize.Level1)
{
CallStack callStack;
- for (size_t i = 0; i < MAX_CALL_FRAME_EXPEND_CACHE_SIZE; i++) {
+ for (size_t i = 0; i < MAX_CALL_FRAME_EXPAND_CACHE_SIZE; i++) {
std::vector stack = {{rnd_(), rnd_()}};
- callStack.ExpendCallStack(0, stack);
+ callStack.ExpandCallStack(0, stack);
}
- for (size_t i = 0; i < MAX_CALL_FRAME_EXPEND_CACHE_SIZE; i++) {
+ for (size_t i = 0; i < MAX_CALL_FRAME_EXPAND_CACHE_SIZE; i++) {
std::vector stack = {{rnd_(), rnd_()}};
- callStack.ExpendCallStack(0, stack);
+ callStack.ExpandCallStack(0, stack);
}
- EXPECT_EQ(callStack.cachedCallFramesMap_[0].size(), MAX_CALL_FRAME_EXPEND_CACHE_SIZE);
+ EXPECT_EQ(callStack.cachedCallFramesMap_[0].size(), MAX_CALL_FRAME_EXPAND_CACHE_SIZE);
}
/**
@@ -531,7 +532,7 @@ HWTEST_F(CallStackTest, GetUnwErrorName, TestSize.Level1)
}
/**
- * @tc.name: ExpendCallStack
+ * @tc.name: ExpandCallStack
* @tc.desc:
* @tc.type: FUNC
*/
@@ -541,10 +542,100 @@ HWTEST_F(CallStackTest, ExpendCallStackSmall, TestSize.Level1)
std::vector stack0 = {};
std::vector stack1 = {{0x1, 0x1}};
std::vector stack2 = {{0x1, 0x1}, {0x2, 0x2}};
- ASSERT_EQ(callStack.ExpendCallStack(0, stack0), 0u);
- ASSERT_EQ(callStack.ExpendCallStack(0, stack1), 0u);
- ASSERT_EQ(callStack.ExpendCallStack(0, stack1), 0u);
- ASSERT_EQ(callStack.ExpendCallStack(0, stack2, 2), 0u);
+ ASSERT_EQ(callStack.ExpandCallStack(0, stack0), 0u);
+ ASSERT_EQ(callStack.ExpandCallStack(0, stack1), 0u);
+ ASSERT_EQ(callStack.ExpandCallStack(0, stack1), 0u);
+ ASSERT_EQ(callStack.ExpandCallStack(0, stack2, 2), 0u);
+}
+
+/**
+ * @tc.name: ExpandCallStack
+ * @tc.desc:
+ * @tc.type: FUNC
+ */
+HWTEST_F(CallStackTest, ExpendCallStackLimit, TestSize.Level1)
+{
+ /*
+ 3 2 1 0
+ cache A -> B -> C
+ stack2 C
+ expand C
+
+ stack3 B -> C
+ expand A -> B -> C
+
+ stack4 C -> D
+ expand C
+ */
+ ScopeDebugLevel tempLogLevel(LEVEL_MUCH, true);
+ CallStack callStack;
+
+ std::vector stack1 = {
+ {0x1u, 0x1u},
+ {0x2u, 0x2u},
+ {0x3u, 0x3u},
+ };
+ std::vector stack2 = {
+ {0x1u, 0x1u},
+ };
+ std::vector stack3 = {
+ {0x1u, 0x1u},
+ {0x2u, 0x2u},
+ };
+ std::vector stack4 = {
+ {0x0u, 0x0u},
+ {0x1u, 0x1u},
+ };
+
+ ASSERT_EQ(callStack.ExpandCallStack(0, stack1, 2u), 0u);
+ ASSERT_EQ(callStack.ExpandCallStack(0, stack2, 2u), 0u);
+ ASSERT_EQ(callStack.ExpandCallStack(0, stack3, 2u), 1u);
+ EXPECT_THAT(stack1, ContainerEq(stack3));
+ ASSERT_EQ(callStack.ExpandCallStack(0, stack4, 2u), 0u);
+}
+
+/**
+ * @tc.name: ExpandCallStack
+ * @tc.desc:
+ * @tc.type: FUNC
+ */
+HWTEST_F(CallStackTest, ExpendCallStackABABAB, TestSize.Level1)
+{
+ /*
+ Caller Called
+ cache A -> B -> C -> A -> B -> C -> A -> B
+ stack2 C
+ expand A -> B -> C -> A -> B -> C
+
+ stack3 B -> C
+ expand A -> B -> C -> A -> B -> C
+
+ stack4 C -> D
+ expand A -> B -> C -> A -> B -> C -> D
+ */
+ ScopeDebugLevel tempLogLevel(LEVEL_MUCH, true);
+ CallStack callStack;
+
+ std::vector stack1 = {
+ {0xb, 0xb}, {0xa, 0xa}, {0xc, 0xc}, {0xb, 0xb},
+ {0xa, 0xa}, {0xc, 0xc}, {0xb, 0xb}, {0xa, 0xa},
+ };
+ std::vector stack2 = {
+ {0xc, 0xc},
+ };
+ std::vector stack3 = {
+ {0xc, 0xc},
+ {0xb, 0xb},
+ };
+ std::vector stack4 = {
+ {0xd, 0xd},
+ {0xc, 0xc},
+ };
+
+ ASSERT_EQ(callStack.ExpandCallStack(0, stack1), 0u);
+ ASSERT_EQ(callStack.ExpandCallStack(0, stack2), 5u);
+ ASSERT_EQ(callStack.ExpandCallStack(0, stack3), 4u);
+ ASSERT_EQ(callStack.ExpandCallStack(0, stack4), 5u);
}
/**
* @tc.name: UnwindCallStack
diff --git a/test/unittest/common/native/hiperf_client_test.cpp b/test/unittest/common/native/hiperf_client_test.cpp
index b702fc400b26e6ef4ef66b1baf6d5b0481db181b..3b639f410d59da19d8e2d60e01df776072a1f97f 100644
--- a/test/unittest/common/native/hiperf_client_test.cpp
+++ b/test/unittest/common/native/hiperf_client_test.cpp
@@ -49,7 +49,6 @@ void HiperfClientTest::SetUp() {}
void HiperfClientTest::TearDown()
{
- this_thread::sleep_for(1s);
}
/**
diff --git a/test/unittest/common/native/perf_events_test.cpp b/test/unittest/common/native/perf_events_test.cpp
index f7d2c4910ae2e9694b50f66d68c4eac0efed1214..eeb9d9d9f4a49d61ed178a32ca65921272d5cdce 100755
--- a/test/unittest/common/native/perf_events_test.cpp
+++ b/test/unittest/common/native/perf_events_test.cpp
@@ -200,8 +200,6 @@ HWTEST_F(PerfEventsTest, RecordNormal, TestSize.Level1)
event.SetMmapPages(DEFAULT_SAMPLE_MMAPAGE);
event.SetRecordCallBack(RecordCount);
- ASSERT_TRUE(event.CheckPermissions());
-
std::vector selectCpus_;
event.SetCpu(selectCpus_);
std::vector pids;
@@ -254,7 +252,6 @@ HWTEST_F(PerfEventsTest, RecordSetAll, TestSize.Level1)
g_recordCount = 0;
event.SetMmapPages(DEFAULT_SAMPLE_MMAPAGE);
event.SetRecordCallBack(RecordCount);
- ASSERT_TRUE(event.CheckPermissions());
SetAllConfig(event);
ASSERT_EQ(event.PrepareTracking(), true);
std::thread runThread(RunTrack, std::ref(event));
diff --git a/test/unittest/common/native/subcommand_record_test.cpp b/test/unittest/common/native/subcommand_record_test.cpp
index 5d7fcc61eb1dac71fff60e1da6870c1bf814497e..8085ec5bbfe083e747f8f27a21b12d7cc6ea744c 100644
--- a/test/unittest/common/native/subcommand_record_test.cpp
+++ b/test/unittest/common/native/subcommand_record_test.cpp
@@ -569,7 +569,7 @@ HWTEST_F(SubCommandRecordTest, DisableUnwind, TestSize.Level1)
HWTEST_F(SubCommandRecordTest, DisableCallstackMerge, TestSize.Level1)
{
- TestRecordCommand("-d 2 -s dwarf,16 --disable-callstack-expend ");
+ TestRecordCommand("-d 2 -s dwarf,16 --disable-callstack-expand ");
}
// symbol dir
diff --git a/test/unittest/common/native/subcommand_stat_test.cpp b/test/unittest/common/native/subcommand_stat_test.cpp
index 28492458a74d8a31a701fa8e8254981cebcb997e..34e8b49d0d8a280eae28bdc64656566074802cdf 100644
--- a/test/unittest/common/native/subcommand_stat_test.cpp
+++ b/test/unittest/common/native/subcommand_stat_test.cpp
@@ -1574,27 +1574,11 @@ HWTEST_F(SubCommandStatTest, TestOnSubCommand_cmd, TestSize.Level1)
HWTEST_F(SubCommandStatTest, TestOnSubCommand_ni, TestSize.Level1)
{
StdoutRecord stdoutRecord;
- stdoutRecord.Start();
- std::string testCMD {"stat -c 0 -d 3 --dumpoptions -e "};
const std::string configName {"sw-cpu-clock"};
- testCMD += configName;
- const std::string cmdPath {" ./../../../../developtools/hiperf/hiperf_example_cmd"};
- testCMD += cmdPath;
- const auto tick1 = std::chrono::steady_clock::now();
- EXPECT_EQ(Command::DispatchCommand(testCMD), true);
- const auto tock1 = std::chrono::steady_clock::now();
- const auto costMs1 = std::chrono::duration_cast(tock1 - tick1);
- EXPECT_LE(costMs1.count(), defaultRunTimeoutMs);
- std::string stringOut = stdoutRecord.Stop();
- if (HasFailure()) {
- printf("output:\n%s", stringOut.c_str());
- }
- int counterValueWithInherit = CounterValue(stringOut, configName);
- EXPECT_NE(counterValueWithInherit, 0);
- HLOGD("%s %d", configName.c_str(), counterValueWithInherit);
+ const std::string cmdPath {" ls"};
stdoutRecord.Start();
- testCMD = "stat --no-inherit -c 0 -d 3 --dumpoptions -e ";
+ std::string testCMD = "stat --no-inherit -c 0 -d 3 --dumpoptions -e ";
testCMD += configName;
testCMD += cmdPath;
const auto tick2 = std::chrono::steady_clock::now();
@@ -1602,7 +1586,7 @@ HWTEST_F(SubCommandStatTest, TestOnSubCommand_ni, TestSize.Level1)
const auto tock2 = std::chrono::steady_clock::now();
const auto costMs2 = std::chrono::duration_cast(tock2 - tick2);
EXPECT_LE(costMs2.count(), defaultRunTimeoutMs);
- stringOut = stdoutRecord.Stop();
+ std::string stringOut = stdoutRecord.Stop();
if (HasFailure()) {
printf("output:\n%s", stringOut.c_str());
}
diff --git a/test/unittest/resource/ohos_test.xml b/test/unittest/resource/ohos_test.xml
index ef6d95fc631c98774cde1e13c3948516b11a55e4..217e1000b0287c0580bfd7c3c91edd8b2dd64c8a 100644
--- a/test/unittest/resource/ohos_test.xml
+++ b/test/unittest/resource/ohos_test.xml
@@ -50,7 +50,7 @@
-
+