mirror of
https://gitee.com/openharmony/developtools_hiperf
synced 2024-11-22 23:20:17 +00:00
告警清理
Signed-off-by:wenlong12 <wenlong12@huawei.com> Signed-off-by: wenlong12 <wenlong12@huawei.com>
This commit is contained in:
parent
c6abb4898f
commit
09e676838b
@ -284,7 +284,6 @@ struct SpeDecoder {
|
|||||||
struct SpePkt packet;
|
struct SpePkt packet;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SpeDecoder *SpeDecoderNew(struct SpeParams *params);
|
|
||||||
struct SpeDecoder *SpeDecoderDataNew(const unsigned char *speBuf, size_t speLen);
|
struct SpeDecoder *SpeDecoderDataNew(const unsigned char *speBuf, size_t speLen);
|
||||||
void SpeDecoderFree(struct SpeDecoder *decoder);
|
void SpeDecoderFree(struct SpeDecoder *decoder);
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
// called from main
|
// called from main
|
||||||
static bool RegisterSubCommand(std::string, std::unique_ptr<SubCommand>);
|
static bool RegisterSubCommand(const std::string&, std::unique_ptr<SubCommand>);
|
||||||
|
|
||||||
// get some cmd
|
// get some cmd
|
||||||
static const std::map<std::string, std::unique_ptr<SubCommand>> &GetSubCommands();
|
static const std::map<std::string, std::unique_ptr<SubCommand>> &GetSubCommands();
|
||||||
|
@ -310,7 +310,7 @@ bool IsBeta();
|
|||||||
bool IsAllowProfilingUid();
|
bool IsAllowProfilingUid();
|
||||||
bool IsHiviewCall();
|
bool IsHiviewCall();
|
||||||
bool PowerOfTwo(uint64_t n);
|
bool PowerOfTwo(uint64_t n);
|
||||||
bool IsNumberic(const std::string& str);
|
bool IsNumeric(const std::string& str);
|
||||||
|
|
||||||
const std::string HMKERNEL = "HongMeng";
|
const std::string HMKERNEL = "HongMeng";
|
||||||
|
|
||||||
|
@ -31,28 +31,20 @@ static std::unique_ptr<HiperfClient::Client> g_hiperfClient =
|
|||||||
static std::unique_ptr<HiperfClient::RecordOption> g_hiperfRecordOption =
|
static std::unique_ptr<HiperfClient::RecordOption> g_hiperfRecordOption =
|
||||||
std::make_unique<HiperfClient::RecordOption>();
|
std::make_unique<HiperfClient::RecordOption>();
|
||||||
|
|
||||||
static std::vector<std::string> StringSplit(std::string source, const std::string &split = ",")
|
static std::vector<std::string> StringSplit(const std::string& text, char delimiter = ',')
|
||||||
{
|
{
|
||||||
size_t pos = 0;
|
std::vector<std::string> tokens;
|
||||||
std::vector<std::string> result;
|
std::string token;
|
||||||
|
std::istringstream tokenStream(text);
|
||||||
// find
|
while (std::getline(tokenStream, token, delimiter)) {
|
||||||
while ((pos = source.find(split)) != std::string::npos) {
|
|
||||||
// split
|
|
||||||
std::string token = source.substr(0, pos);
|
|
||||||
if (!token.empty()) {
|
if (!token.empty()) {
|
||||||
result.push_back(token);
|
tokens.push_back(token);
|
||||||
}
|
}
|
||||||
source.erase(0, pos + split.length());
|
|
||||||
}
|
}
|
||||||
// add last token
|
return tokens;
|
||||||
if (!source.empty()) {
|
|
||||||
result.push_back(source);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsNumberic(const std::string& str)
|
static bool IsNumeric(const std::string& str)
|
||||||
{
|
{
|
||||||
std::istringstream iss(str);
|
std::istringstream iss(str);
|
||||||
int number;
|
int number;
|
||||||
@ -66,25 +58,17 @@ static bool IsNumberic(const std::string& str)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::vector<int> StringSplitToInt(std::string source, const std::string &split = ",")
|
static std::vector<int> StringSplitToInt(const std::string& text, char delimiter = ',')
|
||||||
{
|
{
|
||||||
size_t pos = 0;
|
std::vector<int> tokens;
|
||||||
std::vector<int> result;
|
std::string token;
|
||||||
|
std::istringstream tokenStream(text);
|
||||||
// find
|
while (std::getline(tokenStream, token, delimiter)) {
|
||||||
while ((pos = source.find(split)) != std::string::npos) {
|
if (IsNumeric(token)) {
|
||||||
// split
|
tokens.push_back(std::stoi(token));
|
||||||
std::string token = source.substr(0, pos);
|
|
||||||
if (IsNumberic(token)) {
|
|
||||||
result.push_back(std::stoi(token));
|
|
||||||
}
|
}
|
||||||
source.erase(0, pos + split.length());
|
|
||||||
}
|
}
|
||||||
// add last token
|
return tokens;
|
||||||
if (IsNumberic(source)) {
|
|
||||||
result.push_back(std::stoi(source));
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string GetJsStringFromOption(const napi_env &env, const napi_callback_info &info)
|
static std::string GetJsStringFromOption(const napi_env &env, const napi_callback_info &info)
|
||||||
|
@ -79,7 +79,7 @@ const std::map<unw_error_t, const std::string> UNW_ERROR_MAP = {
|
|||||||
};
|
};
|
||||||
const std::string CallStack::GetUnwErrorName(int error)
|
const std::string CallStack::GetUnwErrorName(int error)
|
||||||
{
|
{
|
||||||
if (UNW_ERROR_MAP.count(static_cast<unw_error_t>(-error)) > 0) {
|
if (UNW_ERROR_MAP.find(static_cast<unw_error_t>(-error)) != UNW_ERROR_MAP.end()) {
|
||||||
return UNW_ERROR_MAP.at(static_cast<unw_error_t>(-error));
|
return UNW_ERROR_MAP.at(static_cast<unw_error_t>(-error));
|
||||||
} else {
|
} else {
|
||||||
return "UNKNOW_UNW_ERROR";
|
return "UNKNOW_UNW_ERROR";
|
||||||
@ -292,7 +292,7 @@ int CallStack::AccessMem([[maybe_unused]] unw_addr_space_t as, unw_word_t addr,
|
|||||||
return -UNW_EUNSPEC;
|
return -UNW_EUNSPEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addr < unwindInfoPtr->callStack.stackPoint_ or
|
if (addr < unwindInfoPtr->callStack.stackPoint_ ||
|
||||||
addr + sizeof(unw_word_t) >= unwindInfoPtr->callStack.stackEnd_) {
|
addr + sizeof(unw_word_t) >= unwindInfoPtr->callStack.stackEnd_) {
|
||||||
if (ReadVirtualThreadMemory(*unwindInfoPtr, addr, valuePoint)) {
|
if (ReadVirtualThreadMemory(*unwindInfoPtr, addr, valuePoint)) {
|
||||||
HLOGM("access_mem addr get val 0x%" UNW_WORD_PFLAG ", from mmap", *valuePoint);
|
HLOGM("access_mem addr get val 0x%" UNW_WORD_PFLAG ", from mmap", *valuePoint);
|
||||||
@ -540,8 +540,8 @@ size_t CallStack::DoExpandCallStack(std::vector<DfxFrame> &newCallFrames,
|
|||||||
{
|
{
|
||||||
int maxCycle = 0;
|
int maxCycle = 0;
|
||||||
|
|
||||||
if (expandLimit == 0 or newCallFrames.size() < expandLimit or
|
if (expandLimit == 0 || newCallFrames.size() < expandLimit ||
|
||||||
cachedCallFrames.size() < expandLimit or
|
cachedCallFrames.size() < expandLimit ||
|
||||||
cachedCallFrames.size() >= MAX_CALL_FRAME_UNWIND_SIZE) {
|
cachedCallFrames.size() >= MAX_CALL_FRAME_UNWIND_SIZE) {
|
||||||
HLOGM("expandLimit %zu not match new %zu cache %zu", expandLimit, newCallFrames.size(),
|
HLOGM("expandLimit %zu not match new %zu cache %zu", expandLimit, newCallFrames.size(),
|
||||||
cachedCallFrames.size());
|
cachedCallFrames.size());
|
||||||
@ -777,7 +777,7 @@ int CallStack::AccessMem2(uintptr_t addr, uintptr_t *val, void *arg)
|
|||||||
"unwindInfoPtr is null or address overflow at 0x%" UNW_WORD_PFLAG " increase 0x%zu",
|
"unwindInfoPtr is null or address overflow at 0x%" UNW_WORD_PFLAG " increase 0x%zu",
|
||||||
addr, sizeof(uintptr_t));
|
addr, sizeof(uintptr_t));
|
||||||
|
|
||||||
if (addr < unwindInfoPtr->callStack.stackPoint_ or
|
if (addr < unwindInfoPtr->callStack.stackPoint_ ||
|
||||||
addr + sizeof(uintptr_t) >= unwindInfoPtr->callStack.stackEnd_) {
|
addr + sizeof(uintptr_t) >= unwindInfoPtr->callStack.stackEnd_) {
|
||||||
if (ReadVirtualThreadMemory(*unwindInfoPtr, addr, val)) {
|
if (ReadVirtualThreadMemory(*unwindInfoPtr, addr, val)) {
|
||||||
HLOGM("access_mem addr get val 0x%" UNW_WORD_PFLAG ", from mmap", *val);
|
HLOGM("access_mem addr get val 0x%" UNW_WORD_PFLAG ", from mmap", *val);
|
||||||
|
@ -15,19 +15,15 @@
|
|||||||
|
|
||||||
#include "debug_logger.h"
|
#include "debug_logger.h"
|
||||||
|
|
||||||
#include <ratio>
|
|
||||||
|
|
||||||
#include "option.h"
|
#include "option.h"
|
||||||
#if defined(is_ohos) && is_ohos
|
#if defined(is_ohos) && is_ohos
|
||||||
#include "hiperf_hilog.h"
|
#include "hiperf_hilog.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using namespace std::literals::chrono_literals;
|
|
||||||
using namespace std::chrono;
|
|
||||||
namespace OHOS {
|
namespace OHOS {
|
||||||
namespace Developtools {
|
namespace Developtools {
|
||||||
namespace HiPerf {
|
namespace HiPerf {
|
||||||
DebugLogger::DebugLogger() : timeStamp_(steady_clock::now()), logPath_(DEFAULT_LOG_PATH)
|
DebugLogger::DebugLogger() : timeStamp_(std::chrono::steady_clock::now()), logPath_(DEFAULT_LOG_PATH)
|
||||||
{
|
{
|
||||||
OpenLog();
|
OpenLog();
|
||||||
}
|
}
|
||||||
@ -82,12 +78,12 @@ int DebugLogger::Log(DebugLevel level, const std::string &logTag, const char *fm
|
|||||||
{
|
{
|
||||||
constexpr const int DEFAULT_STRING_BUF_SIZE = 4096;
|
constexpr const int DEFAULT_STRING_BUF_SIZE = 4096;
|
||||||
#ifdef HIPERF_DEBUG_TIME
|
#ifdef HIPERF_DEBUG_TIME
|
||||||
const auto startSprintf = steady_clock::now();
|
const auto startSprintf = std::chrono::steady_clock::now();
|
||||||
#endif
|
#endif
|
||||||
const auto startTime = steady_clock::now();
|
const auto startTime = std::chrono::steady_clock::now();
|
||||||
if (!ShouldLog(level, logTag) or logDisabled_ or fmt == nullptr) {
|
if (!ShouldLog(level, logTag) || logDisabled_ || fmt == nullptr) {
|
||||||
#ifdef HIPERF_DEBUG_TIME
|
#ifdef HIPERF_DEBUG_TIME
|
||||||
logTimes_ += duration_cast<microseconds>(steady_clock::now() - startSprintf);
|
logTimes_ += duration_cast<microseconds>(std::chrono::steady_clock::now() - startSprintf);
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -99,9 +95,9 @@ int DebugLogger::Log(DebugLevel level, const std::string &logTag, const char *fm
|
|||||||
ret = vsnprintf_s(buffer.data(), buffer.size(), buffer.size() >= 1 ? buffer.size() - 1 : 0, fmt, va);
|
ret = vsnprintf_s(buffer.data(), buffer.size(), buffer.size() >= 1 ? buffer.size() - 1 : 0, fmt, va);
|
||||||
va_end(va);
|
va_end(va);
|
||||||
#ifdef HIPERF_DEBUG_TIME
|
#ifdef HIPERF_DEBUG_TIME
|
||||||
logSprintfTimes_ += duration_cast<microseconds>(steady_clock::now() - startSprintf);
|
logSprintfTimes_ += duration_cast<microseconds>(std::chrono::steady_clock::now() - startSprintf);
|
||||||
#endif
|
#endif
|
||||||
if ((mixLogOutput_ and level < LEVEL_FATAL) or level == LEVEL_FATAL) {
|
if ((mixLogOutput_ && level < LEVEL_FATAL) || level == LEVEL_FATAL) {
|
||||||
ret = fprintf(stdout, "%s", buffer.data()); // to the stdout
|
ret = fprintf(stdout, "%s", buffer.data()); // to the stdout
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,17 +109,17 @@ int DebugLogger::Log(DebugLevel level, const std::string &logTag, const char *fm
|
|||||||
} else if (file_ != nullptr) {
|
} else if (file_ != nullptr) {
|
||||||
std::lock_guard<std::recursive_mutex> lock(logMutex_);
|
std::lock_guard<std::recursive_mutex> lock(logMutex_);
|
||||||
#ifdef HIPERF_DEBUG_TIME
|
#ifdef HIPERF_DEBUG_TIME
|
||||||
const auto startWriteTime = steady_clock::now();
|
const auto startWriteTime = std::chrono::steady_clock::now();
|
||||||
#endif
|
#endif
|
||||||
milliseconds timeStamp = duration_cast<milliseconds>(startTime - timeStamp_);
|
auto timeStamp = startTime - timeStamp_;
|
||||||
fprintf(file_, "%05" PRId64 "ms %s", (int64_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
|
#ifdef HIPERF_DEBUG_TIME
|
||||||
logWriteTimes_ += duration_cast<microseconds>(steady_clock::now() - startWriteTime);
|
logWriteTimes_ += duration_cast<microseconds>(std::chrono::steady_clock::now() - startWriteTime);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HIPERF_DEBUG_TIME
|
#ifdef HIPERF_DEBUG_TIME
|
||||||
logTimes_ += duration_cast<microseconds>(steady_clock::now() - startTime);
|
logTimes_ += duration_cast<microseconds>(std::chrono::steady_clock::now() - startTime);
|
||||||
logCount_++;
|
logCount_++;
|
||||||
#endif
|
#endif
|
||||||
if (level == LEVEL_FATAL && exitOnFatal_) {
|
if (level == LEVEL_FATAL && exitOnFatal_) {
|
||||||
@ -170,7 +166,7 @@ bool DebugLogger::SetLogPath(const std::string &newLogPath)
|
|||||||
{
|
{
|
||||||
// make sure not write happend when rename
|
// make sure not write happend when rename
|
||||||
std::lock_guard<std::recursive_mutex> lock(logMutex_);
|
std::lock_guard<std::recursive_mutex> lock(logMutex_);
|
||||||
if (newLogPath.empty() and newLogPath != logPath_) {
|
if (newLogPath.empty() && newLogPath != logPath_) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (file_ != nullptr) {
|
if (file_ != nullptr) {
|
||||||
|
@ -47,7 +47,7 @@ int Report(const char *perfFile, const char *reportFile, const char *reportOptio
|
|||||||
{
|
{
|
||||||
std::unique_ptr<SubCommandReport> report = std::make_unique<SubCommandReport>();
|
std::unique_ptr<SubCommandReport> report = std::make_unique<SubCommandReport>();
|
||||||
HLOGD("report the file %s to %s\n", perfFile, reportFile);
|
HLOGD("report the file %s to %s\n", perfFile, reportFile);
|
||||||
if (perfFile != nullptr and reportFile != nullptr) {
|
if (perfFile != nullptr && reportFile != nullptr) {
|
||||||
std::vector<std::string> args;
|
std::vector<std::string> args;
|
||||||
args.emplace_back("-i");
|
args.emplace_back("-i");
|
||||||
args.emplace_back(perfFile);
|
args.emplace_back(perfFile);
|
||||||
@ -77,7 +77,7 @@ int ReportUnwindJson(const char *perfFile, const char *reportFile, const char *s
|
|||||||
{
|
{
|
||||||
std::unique_ptr<SubCommandReport> report = std::make_unique<SubCommandReport>();
|
std::unique_ptr<SubCommandReport> report = std::make_unique<SubCommandReport>();
|
||||||
HLOGD("report the file %s to json file %s symbols from %s\n", perfFile, reportFile, symbolsDir);
|
HLOGD("report the file %s to json file %s symbols from %s\n", perfFile, reportFile, symbolsDir);
|
||||||
if (perfFile != nullptr and reportFile != nullptr) {
|
if (perfFile != nullptr && reportFile != nullptr) {
|
||||||
std::vector<std::string> args;
|
std::vector<std::string> args;
|
||||||
args.emplace_back("-i");
|
args.emplace_back("-i");
|
||||||
args.emplace_back(perfFile);
|
args.emplace_back(perfFile);
|
||||||
@ -119,11 +119,13 @@ const char *ReportGetSymbolFiles(const char *perfFile)
|
|||||||
static std::string result; // static for hold the c_str buffer
|
static std::string result; // static for hold the c_str buffer
|
||||||
result.clear();
|
result.clear();
|
||||||
if (perfFile == nullptr) {
|
if (perfFile == nullptr) {
|
||||||
|
HLOGW("perfFile is nullptr.");
|
||||||
return result.c_str();
|
return result.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto reader = GetReader(perfFile);
|
auto reader = GetReader(perfFile);
|
||||||
if (reader == nullptr) {
|
if (reader == nullptr) {
|
||||||
|
HLOGW("reader is nullptr.");
|
||||||
return result.c_str();
|
return result.c_str();
|
||||||
}
|
}
|
||||||
// found symbols in file
|
// found symbols in file
|
||||||
|
@ -47,7 +47,7 @@ int main(const int argc, const char *argv[])
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc < 0 || argc > 128) { // 128 : max input argument counts
|
if (argc > 128) { // 128 : max input argument counts
|
||||||
printf("The number of input arguments exceeds the upper limit.\n");
|
printf("The number of input arguments exceeds the upper limit.\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ std::vector<std::string>::iterator FindOption(argsVector &args, const std::strin
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto it = find(args.begin(), args.end(), optionName);
|
auto it = std::find(args.begin(), args.end(), optionName);
|
||||||
if (it != args.end()) {
|
if (it != args.end()) {
|
||||||
if (tmpit != args.end() && it > tmpit) {
|
if (tmpit != args.end() && it > tmpit) {
|
||||||
it = args.end();
|
it = args.end();
|
||||||
|
@ -20,8 +20,6 @@
|
|||||||
|
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
|
|
||||||
using namespace OHOS::HiviewDFX;
|
|
||||||
using namespace std;
|
|
||||||
namespace OHOS {
|
namespace OHOS {
|
||||||
namespace Developtools {
|
namespace Developtools {
|
||||||
namespace HiPerf {
|
namespace HiPerf {
|
||||||
@ -339,7 +337,7 @@ void PerfRecordSample::ReplaceWithCallStack(size_t originalSize)
|
|||||||
const size_t beginIpsSize = ips_.size();
|
const size_t beginIpsSize = ips_.size();
|
||||||
bool ret = std::all_of(callFrames_.begin(), callFrames_.end(), [&](const DfxFrame &frame) {
|
bool ret = std::all_of(callFrames_.begin(), callFrames_.end(), [&](const DfxFrame &frame) {
|
||||||
ips_.emplace_back(frame.pc);
|
ips_.emplace_back(frame.pc);
|
||||||
if (originalSize != 0 and (originalSize != callFrames_.size()) and
|
if (originalSize != 0 && (originalSize != callFrames_.size()) &&
|
||||||
ips_.size() == (originalSize + beginIpsSize)) {
|
ips_.size() == (originalSize + beginIpsSize)) {
|
||||||
// just for debug
|
// just for debug
|
||||||
// so we can see which frame begin is expand call frames
|
// so we can see which frame begin is expand call frames
|
||||||
|
@ -412,7 +412,7 @@ void PerfEvents::SetConfig(std::map<const std::string, unsigned long long> &speO
|
|||||||
bool PerfEvents::AddEvent(perf_type_id type, __u64 config, bool excludeUser, bool excludeKernel,
|
bool PerfEvents::AddEvent(perf_type_id type, __u64 config, bool excludeUser, bool excludeKernel,
|
||||||
bool followGroup)
|
bool followGroup)
|
||||||
{
|
{
|
||||||
HLOG_ASSERT(!excludeUser or !excludeKernel);
|
HLOG_ASSERT(!excludeUser || !excludeKernel);
|
||||||
CHECK_TRUE(followGroup && eventGroupItem_.empty(), false, 1, "no group leader create before");
|
CHECK_TRUE(followGroup && eventGroupItem_.empty(), false, 1, "no group leader create before");
|
||||||
// found the event name
|
// found the event name
|
||||||
CHECK_TRUE(!IsEventSupport(type, config), false, 0, "");
|
CHECK_TRUE(!IsEventSupport(type, config), false, 0, "");
|
||||||
|
@ -134,12 +134,13 @@ bool PerfFileSection::Read(std::string &value)
|
|||||||
CHECK_TRUE(!Read(size), false, 0, "");
|
CHECK_TRUE(!Read(size), false, 0, "");
|
||||||
// if size large than buf size or 0 size ?
|
// if size large than buf size or 0 size ?
|
||||||
// don't assert for fuzz test
|
// don't assert for fuzz test
|
||||||
CHECK_TRUE(size == 0 or size > maxSize_, false, 0, "");
|
CHECK_TRUE(size == 0 || size > maxSize_, false, 0, "");
|
||||||
char buf[size];
|
char *buf = new char[size];
|
||||||
CHECK_TRUE(!Read(buf, size), false, 0, "");
|
CHECK_TRUE(!Read(buf, size), false, 0, "");
|
||||||
CHECK_TRUE(buf[size - 1] != 0, false, 0, "");
|
CHECK_TRUE(buf[size - 1] != 0, false, 0, "");
|
||||||
value = buf;
|
value = buf;
|
||||||
HLOGDUMMY("Read String size %u buf : %s", size, value.c_str());
|
HLOGDUMMY("Read String size %u buf : %s", size, value.c_str());
|
||||||
|
delete []buf;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
void PerfFileSection::Skip(size_t size)
|
void PerfFileSection::Skip(size_t size)
|
||||||
|
@ -46,7 +46,9 @@ std::unique_ptr<PerfFileReader> PerfFileReader::Instance(const std::string &file
|
|||||||
if (!reader->ReadFileHeader()) {
|
if (!reader->ReadFileHeader()) {
|
||||||
// Fail to read header, maybe its compressed
|
// Fail to read header, maybe its compressed
|
||||||
if (reader->IsGzipFile()) {
|
if (reader->IsGzipFile()) {
|
||||||
fclose(fp);
|
if (fp != nullptr) {
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
reader->fp_ = nullptr;
|
reader->fp_ = nullptr;
|
||||||
|
|
||||||
CHECK_TRUE(!UncompressFile(fileName, UNCOMPRESS_TMP_FILE), nullptr, 1,
|
CHECK_TRUE(!UncompressFile(fileName, UNCOMPRESS_TMP_FILE), nullptr, 1,
|
||||||
@ -80,7 +82,7 @@ PerfFileReader::PerfFileReader(const std::string &fileName, FILE *fp) : fp_(fp),
|
|||||||
featureSectionOffset_ = 0;
|
featureSectionOffset_ = 0;
|
||||||
struct stat fileStat;
|
struct stat fileStat;
|
||||||
if (fp != nullptr) {
|
if (fp != nullptr) {
|
||||||
if (fstat(fileno(fp), &fileStat) != -1 and fileStat.st_size > 0) {
|
if (fstat(fileno(fp), &fileStat) != -1 && fileStat.st_size > 0) {
|
||||||
fileSize_ = fileStat.st_size;
|
fileSize_ = fileStat.st_size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -110,7 +112,7 @@ bool PerfFileReader::IsValidDataFile()
|
|||||||
|
|
||||||
bool PerfFileReader::IsGzipFile()
|
bool PerfFileReader::IsGzipFile()
|
||||||
{
|
{
|
||||||
return header_.magic[0] == '\x1f' and header_.magic[1] == '\x8b';
|
return header_.magic[0] == '\x1f' && header_.magic[1] == '\x8b';
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PerfFileReader::ReadFileHeader()
|
bool PerfFileReader::ReadFileHeader()
|
||||||
@ -404,7 +406,7 @@ bool PerfFileReader::ReadFeatureSection()
|
|||||||
HLOGV("process feature %d:%s", feature, PerfFileSection::GetFeatureName(feature).c_str());
|
HLOGV("process feature %d:%s", feature, PerfFileSection::GetFeatureName(feature).c_str());
|
||||||
HLOGV(" sectionHeader -> read offset '0x%" PRIx64 " size '0x%" PRIx64 "'",
|
HLOGV(" sectionHeader -> read offset '0x%" PRIx64 " size '0x%" PRIx64 "'",
|
||||||
sectionHeader.offset, sectionHeader.size);
|
sectionHeader.offset, sectionHeader.size);
|
||||||
CHECK_TRUE(sectionHeader.size == 0 or sectionHeader.size > fileSize_, false, 1,
|
CHECK_TRUE(sectionHeader.size == 0 || sectionHeader.size > fileSize_, false, 1,
|
||||||
"sectionHeader.size %" PRIu64 " is not correct", sectionHeader.size);
|
"sectionHeader.size %" PRIu64 " is not correct", sectionHeader.size);
|
||||||
|
|
||||||
std::vector<char> buf(sectionHeader.size);
|
std::vector<char> buf(sectionHeader.size);
|
||||||
|
@ -63,7 +63,7 @@ uint64_t GetSupportedRegMask(ArchType arch)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
result = std::numeric_limits<uint64_t>::max();
|
result = std::numeric_limits<uint64_t>::max();
|
||||||
HLOGE("unsupport arch %d", arch);
|
HLOGE("unsupport arch %u", arch);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@ -272,7 +272,7 @@ ArchType GetDeviceArch()
|
|||||||
|
|
||||||
void UpdateRegForABI(ArchType arch, u64 *regs)
|
void UpdateRegForABI(ArchType arch, u64 *regs)
|
||||||
{
|
{
|
||||||
if (g_deviceArchType == ArchType::ARCH_ARM64 and arch == ArchType::ARCH_ARM) {
|
if (g_deviceArchType == ArchType::ARCH_ARM64 && arch == ArchType::ARCH_ARM) {
|
||||||
// arm in arm64
|
// arm in arm64
|
||||||
regs[PERF_REG_ARM_PC] = regs[PERF_REG_ARM64_PC];
|
regs[PERF_REG_ARM_PC] = regs[PERF_REG_ARM64_PC];
|
||||||
}
|
}
|
||||||
|
@ -41,49 +41,47 @@ void Report::AddReportItem(const PerfRecordSample &sample, bool includeCallStack
|
|||||||
configIndex, sample.data_.id);
|
configIndex, sample.data_.id);
|
||||||
VirtualThread &thread = virtualRuntime_.GetThread(sample.data_.pid, sample.data_.tid);
|
VirtualThread &thread = virtualRuntime_.GetThread(sample.data_.pid, sample.data_.tid);
|
||||||
HLOG_ASSERT(sample.callFrames_.size() > 0);
|
HLOG_ASSERT(sample.callFrames_.size() > 0);
|
||||||
if (sample.callFrames_.size() > 0) {
|
// if we need callstack ?
|
||||||
// if we need callstack ?
|
if (includeCallStack) {
|
||||||
if (includeCallStack) {
|
// we will use caller mode , from last to first
|
||||||
// we will use caller mode , from last to first
|
auto frameIt = sample.callFrames_.rbegin();
|
||||||
auto frameIt = sample.callFrames_.rbegin();
|
ReportItem &item = configs_[configIndex].reportItems_.emplace_back(
|
||||||
|
sample.data_.pid, sample.data_.tid, thread.name_, frameIt->mapName,
|
||||||
|
frameIt->funcName, frameIt->funcOffset, sample.data_.period);
|
||||||
|
HLOGD("ReportItem: %s", item.ToDebugString().c_str());
|
||||||
|
HLOG_ASSERT(!item.func_.empty());
|
||||||
|
|
||||||
|
std::vector<ReportItemCallFrame> *currentCallFrames = &item.callStacks_;
|
||||||
|
for (frameIt = sample.callFrames_.rbegin(); frameIt != sample.callFrames_.rend();
|
||||||
|
frameIt++) {
|
||||||
|
HLOG_ASSERT(frameIt->pc < PERF_CONTEXT_MAX);
|
||||||
|
// in add items case , right one should only have 1 callstack
|
||||||
|
// so just new callfames and move to next level
|
||||||
|
ReportItemCallFrame &nextCallFrame = currentCallFrames->emplace_back(
|
||||||
|
frameIt->funcName, frameIt->funcOffset, frameIt->mapName,
|
||||||
|
sample.data_.period,
|
||||||
|
(std::next(frameIt) == sample.callFrames_.rend()) ? sample.data_.period : 0);
|
||||||
|
HLOGV("add callframe %s", nextCallFrame.ToDebugString().c_str());
|
||||||
|
currentCallFrames = &nextCallFrame.childs;
|
||||||
|
}
|
||||||
|
HLOGV("callstack %zu", item.callStacks_.size());
|
||||||
|
if (item.callStacks_.size() > 0) {
|
||||||
|
HLOGV("callstack 2nd level %zu", item.callStacks_[0].childs.size());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
auto frameIt = sample.callFrames_.begin();
|
||||||
|
if (frameIt != sample.callFrames_.end()) {
|
||||||
|
HLOG_ASSERT(frameIt->pc < PERF_CONTEXT_MAX);
|
||||||
|
// for arkjs frame, skip the stub.an frame
|
||||||
|
if (StringEndsWith(frameIt->mapName, "stub.an") && sample.callFrames_.size() > 1) {
|
||||||
|
HLOGV("stub.an frame, go to next, mapname %s", frameIt->mapName.c_str());
|
||||||
|
frameIt++;
|
||||||
|
}
|
||||||
ReportItem &item = configs_[configIndex].reportItems_.emplace_back(
|
ReportItem &item = configs_[configIndex].reportItems_.emplace_back(
|
||||||
sample.data_.pid, sample.data_.tid, thread.name_, frameIt->mapName,
|
sample.data_.pid, sample.data_.tid, thread.name_, frameIt->mapName,
|
||||||
frameIt->funcName, frameIt->funcOffset, sample.data_.period);
|
frameIt->funcName, frameIt->funcOffset, sample.data_.period);
|
||||||
HLOGD("ReportItem: %s", item.ToDebugString().c_str());
|
HLOGV("%s", item.ToDebugString().c_str());
|
||||||
HLOG_ASSERT(!item.func_.empty());
|
HLOG_ASSERT(!item.func_.empty());
|
||||||
|
|
||||||
std::vector<ReportItemCallFrame> *currentCallFrames = &item.callStacks_;
|
|
||||||
for (frameIt = sample.callFrames_.rbegin(); frameIt != sample.callFrames_.rend();
|
|
||||||
frameIt++) {
|
|
||||||
HLOG_ASSERT(frameIt->pc < PERF_CONTEXT_MAX);
|
|
||||||
// in add items case , right one should only have 1 callstack
|
|
||||||
// so just new callfames and move to next level
|
|
||||||
ReportItemCallFrame &nextCallFrame = currentCallFrames->emplace_back(
|
|
||||||
frameIt->funcName, frameIt->funcOffset, frameIt->mapName,
|
|
||||||
sample.data_.period,
|
|
||||||
(std::next(frameIt) == sample.callFrames_.rend()) ? sample.data_.period : 0);
|
|
||||||
HLOGV("add callframe %s", nextCallFrame.ToDebugString().c_str());
|
|
||||||
currentCallFrames = &nextCallFrame.childs;
|
|
||||||
}
|
|
||||||
HLOGV("callstack %zu", item.callStacks_.size());
|
|
||||||
if (item.callStacks_.size() > 0) {
|
|
||||||
HLOGV("callstack 2nd level %zu", item.callStacks_[0].childs.size());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
auto frameIt = sample.callFrames_.begin();
|
|
||||||
if (frameIt != sample.callFrames_.end()) {
|
|
||||||
HLOG_ASSERT(frameIt->pc < PERF_CONTEXT_MAX);
|
|
||||||
// for arkjs frame, skip the stub.an frame
|
|
||||||
if (StringEndsWith(frameIt->mapName, "stub.an") && sample.callFrames_.size() > 1) {
|
|
||||||
HLOGV("stub.an frame, go to next, mapname %s", frameIt->mapName.c_str());
|
|
||||||
frameIt++;
|
|
||||||
}
|
|
||||||
ReportItem &item = configs_[configIndex].reportItems_.emplace_back(
|
|
||||||
sample.data_.pid, sample.data_.tid, thread.name_, frameIt->mapName,
|
|
||||||
frameIt->funcName, frameIt->funcOffset, sample.data_.period);
|
|
||||||
HLOGV("%s", item.ToDebugString().c_str());
|
|
||||||
HLOG_ASSERT(!item.func_.empty());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
configs_[configIndex].sampleCount_++;
|
configs_[configIndex].sampleCount_++;
|
||||||
@ -321,7 +319,7 @@ bool Report::MultiLevelSorting(const ReportItem &a, const ReportItem &b)
|
|||||||
#ifdef HIPERF_DEBUG
|
#ifdef HIPERF_DEBUG
|
||||||
if (DebugLogger::GetInstance()->GetLogLevel() <= LEVEL_VERBOSE) {
|
if (DebugLogger::GetInstance()->GetLogLevel() <= LEVEL_VERBOSE) {
|
||||||
bool result2 = MultiLevelCompare(b, a) > 0;
|
bool result2 = MultiLevelCompare(b, a) > 0;
|
||||||
if (result and result == result2) {
|
if (result && result == result2) {
|
||||||
HLOGE("MultiLevelSorting a->b %d vs b->a %d", result, result2);
|
HLOGE("MultiLevelSorting a->b %d vs b->a %d", result, result2);
|
||||||
HLOGE("left %s", a.ToDebugString().c_str());
|
HLOGE("left %s", a.ToDebugString().c_str());
|
||||||
HLOGE("right %s", b.ToDebugString().c_str());
|
HLOGE("right %s", b.ToDebugString().c_str());
|
||||||
@ -456,14 +454,14 @@ void Report::OutputStdCallFrames(int indent, const ReportItemCallFrame &callFram
|
|||||||
NO_RETVAL, 0, "");
|
NO_RETVAL, 0, "");
|
||||||
|
|
||||||
// print it self
|
// print it self
|
||||||
if (callFrame.selfEventCount_ != 0 and callFrame.selfEventCount_ != callFrame.eventCount_) {
|
if (callFrame.selfEventCount_ != 0 && callFrame.selfEventCount_ != callFrame.eventCount_) {
|
||||||
OutputStdCallFrame(indent + CALLSTACK_INDENT, "[run in self function]",
|
OutputStdCallFrame(indent + CALLSTACK_INDENT, "[run in self function]",
|
||||||
callFrame.selfEventCount_, callFrame.eventCount_);
|
callFrame.selfEventCount_, callFrame.eventCount_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// printf children
|
// printf children
|
||||||
// if only one children
|
// if only one children
|
||||||
if (callFrame.childs.size() == 1u and
|
if (callFrame.childs.size() == 1u &&
|
||||||
callFrame.childs[0].eventCount_ == callFrame.eventCount_) {
|
callFrame.childs[0].eventCount_ == callFrame.eventCount_) {
|
||||||
HLOGV("childCallFream %*c %s", indent, ' ', callFrame.childs[0].func_.data());
|
HLOGV("childCallFream %*c %s", indent, ' ', callFrame.childs[0].func_.data());
|
||||||
// don't indent if same count (only one 100% children)
|
// don't indent if same count (only one 100% children)
|
||||||
@ -519,7 +517,7 @@ void Report::OutputStdContentItem(const ReportItem &reportItem)
|
|||||||
|
|
||||||
void Report::OutputStdItemHeating(float heat, float heat2)
|
void Report::OutputStdItemHeating(float heat, float heat2)
|
||||||
{
|
{
|
||||||
if (heat == heat2 and heat == 0.0f) {
|
if (heat == heat2 && heat == 0.0f) {
|
||||||
fprintf(output_, "something error , all it is end.\n");
|
fprintf(output_, "something error , all it is end.\n");
|
||||||
} else if (heat2 == 0) {
|
} else if (heat2 == 0) {
|
||||||
// only have first
|
// only have first
|
||||||
@ -560,7 +558,7 @@ void Report::OutputStdContentDiff(ReportEventConfigItem &left, ReportEventConfig
|
|||||||
if (MultiLevelSame(*it, *it2)) {
|
if (MultiLevelSame(*it, *it2)) {
|
||||||
// we found the same item
|
// we found the same item
|
||||||
// output the diff heating
|
// output the diff heating
|
||||||
if (it->heat > option_.heatLimit_ and it2->heat > option_.heatLimit_) {
|
if (it->heat > option_.heatLimit_ && it2->heat > option_.heatLimit_) {
|
||||||
OutputStdItemHeating(it->heat, it2->heat);
|
OutputStdItemHeating(it->heat, it2->heat);
|
||||||
OutputStdContentItem(*it);
|
OutputStdContentItem(*it);
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ uint8_t *RingBuffer::AllocForWrite(size_t writeSize)
|
|||||||
if (writePos + writeSize > readPos) {
|
if (writePos + writeSize > readPos) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
} else if (writePos == readPos and writeHead != readHead) {
|
} else if (writePos == readPos && writeHead != readHead) {
|
||||||
// writePos catch up with readPos, but buffer is full
|
// writePos catch up with readPos, but buffer is full
|
||||||
return nullptr;
|
return nullptr;
|
||||||
} else {
|
} else {
|
||||||
|
@ -259,7 +259,9 @@ static int SpePktOutString(int *err, char **bufPtr, size_t *bufLen,
|
|||||||
if (err && *err) {
|
if (err && *err) {
|
||||||
return *err;
|
return *err;
|
||||||
}
|
}
|
||||||
|
if (*bufLen - 1 < 0) {
|
||||||
|
HLOGW("SpePktOutString failed, bufLen: %d", static_cast<int>(*bufLen));
|
||||||
|
}
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
ret = vsnprintf_s(*bufPtr, *bufLen, *bufLen - 1, fmt, args);
|
ret = vsnprintf_s(*bufPtr, *bufLen, *bufLen - 1, fmt, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
@ -268,6 +270,7 @@ static int SpePktOutString(int *err, char **bufPtr, size_t *bufLen,
|
|||||||
if (err && !*err) {
|
if (err && !*err) {
|
||||||
*err = ret;
|
*err = ret;
|
||||||
}
|
}
|
||||||
|
HLOGW("vsnprintf_s failed: %d\n", ret);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the return value is *bufLen or greater, the output was
|
* If the return value is *bufLen or greater, the output was
|
||||||
@ -627,21 +630,6 @@ static u64 SpeCalcIp(int index, u64 payload)
|
|||||||
return payload;
|
return payload;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SpeDecoder *SpeDecoderNew(struct SpeParams *params)
|
|
||||||
{
|
|
||||||
CHECK_TRUE(params == nullptr, nullptr, 1, "Invalid pointer!");
|
|
||||||
struct SpeDecoder *decoder;
|
|
||||||
|
|
||||||
decoder = static_cast<struct SpeDecoder*>(malloc(sizeof(struct SpeDecoder)));
|
|
||||||
if (!decoder) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
decoder->data = params->data;
|
|
||||||
|
|
||||||
return decoder;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SpeDecoderFree(struct SpeDecoder *decoder)
|
void SpeDecoderFree(struct SpeDecoder *decoder)
|
||||||
{
|
{
|
||||||
CHECK_TRUE(decoder == nullptr, NO_RETVAL, 1, "Invalid pointer!");
|
CHECK_TRUE(decoder == nullptr, NO_RETVAL, 1, "Invalid pointer!");
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
#include "debug_logger.h"
|
#include "debug_logger.h"
|
||||||
#include "option.h"
|
#include "option.h"
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
namespace OHOS {
|
namespace OHOS {
|
||||||
namespace Developtools {
|
namespace Developtools {
|
||||||
namespace HiPerf {
|
namespace HiPerf {
|
||||||
@ -146,7 +145,7 @@ void SubCommand::ExcludeThreadsFromSelectTids(const std::vector<std::string> &ex
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SubCommand::RegisterSubCommand(std::string cmdName, std::unique_ptr<SubCommand> subCommand)
|
bool SubCommand::RegisterSubCommand(const std::string& cmdName, std::unique_ptr<SubCommand> subCommand)
|
||||||
{
|
{
|
||||||
HLOGV("%s", cmdName.c_str());
|
HLOGV("%s", cmdName.c_str());
|
||||||
if (cmdName.empty()) {
|
if (cmdName.empty()) {
|
||||||
@ -158,7 +157,7 @@ bool SubCommand::RegisterSubCommand(std::string cmdName, std::unique_ptr<SubComm
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_SubCommandsMap.count(cmdName) == 0) {
|
if (g_SubCommandsMap.find(cmdName) == g_SubCommandsMap.end()) {
|
||||||
std::lock_guard<std::mutex> lock(g_subCommandMutex);
|
std::lock_guard<std::mutex> lock(g_subCommandMutex);
|
||||||
g_SubCommandsMap.insert(std::make_pair(cmdName, std::move(subCommand)));
|
g_SubCommandsMap.insert(std::make_pair(cmdName, std::move(subCommand)));
|
||||||
return true;
|
return true;
|
||||||
|
@ -381,13 +381,15 @@ void SubCommandDump::DumpAttrPortion(int indent)
|
|||||||
|
|
||||||
void SubCommandDump::ExprotUserStack(const PerfRecordSample &recordSample)
|
void SubCommandDump::ExprotUserStack(const PerfRecordSample &recordSample)
|
||||||
{
|
{
|
||||||
if (recordSample.data_.reg_nr > 0 and recordSample.data_.dyn_size > 0) {
|
if (recordSample.data_.reg_nr > 0 && recordSample.data_.dyn_size > 0) {
|
||||||
// <pid>_<tid>_user_regs_<time>
|
// <pid>_<tid>_user_regs_<time>
|
||||||
std::string userRegs =
|
std::string userRegs =
|
||||||
StringPrintf("hiperf_%d_%d_user_regs_%zu.dump", recordSample.data_.pid,
|
StringPrintf("hiperf_%d_%d_user_regs_%zu.dump", recordSample.data_.pid,
|
||||||
recordSample.data_.tid, exportSampleIndex_);
|
recordSample.data_.tid, exportSampleIndex_);
|
||||||
std::string resolvedPath = CanonicalizeSpecPath(userRegs.c_str());
|
std::string resolvedPath = CanonicalizeSpecPath(userRegs.c_str());
|
||||||
std::unique_ptr<FILE, decltype(&fclose)> fpUserRegs(fopen(resolvedPath.c_str(), "wb"), fclose);
|
FILE *userRegsFp = fopen(resolvedPath.c_str(), "wb");
|
||||||
|
CHECK_TRUE(userRegsFp == nullptr, NO_RETVAL, 1, "open userRegs failed");
|
||||||
|
std::unique_ptr<FILE, decltype(&fclose)> fpUserRegs(userRegsFp, fclose);
|
||||||
fwrite(recordSample.data_.user_regs, sizeof(u64), recordSample.data_.reg_nr,
|
fwrite(recordSample.data_.user_regs, sizeof(u64), recordSample.data_.reg_nr,
|
||||||
fpUserRegs.get());
|
fpUserRegs.get());
|
||||||
|
|
||||||
@ -395,7 +397,9 @@ void SubCommandDump::ExprotUserStack(const PerfRecordSample &recordSample)
|
|||||||
StringPrintf("hiperf_%d_%d_user_data_%zu.dump", recordSample.data_.pid,
|
StringPrintf("hiperf_%d_%d_user_data_%zu.dump", recordSample.data_.pid,
|
||||||
recordSample.data_.tid, exportSampleIndex_);
|
recordSample.data_.tid, exportSampleIndex_);
|
||||||
std::string resolvePath = CanonicalizeSpecPath(userData.c_str());
|
std::string resolvePath = CanonicalizeSpecPath(userData.c_str());
|
||||||
std::unique_ptr<FILE, decltype(&fclose)> fpUserData(fopen(resolvePath.c_str(), "wb"), fclose);
|
FILE *UserDataFp = fopen(resolvePath.c_str(), "wb");
|
||||||
|
CHECK_TRUE(UserDataFp == nullptr, NO_RETVAL, 1, "open UserData failed");
|
||||||
|
std::unique_ptr<FILE, decltype(&fclose)> fpUserData(UserDataFp, fclose);
|
||||||
fwrite(recordSample.data_.stack_data, sizeof(u8), recordSample.data_.dyn_size,
|
fwrite(recordSample.data_.stack_data, sizeof(u8), recordSample.data_.dyn_size,
|
||||||
fpUserData.get());
|
fpUserData.get());
|
||||||
}
|
}
|
||||||
@ -592,7 +596,7 @@ void SubCommandDump::SetHM()
|
|||||||
if (isHM_) {
|
if (isHM_) {
|
||||||
pid_t devhost = -1;
|
pid_t devhost = -1;
|
||||||
std::string str = reader_->GetFeatureString(FEATURE::HIPERF_HM_DEVHOST);
|
std::string str = reader_->GetFeatureString(FEATURE::HIPERF_HM_DEVHOST);
|
||||||
if (IsNumberic(str)) {
|
if (IsNumeric(str)) {
|
||||||
devhost = std::stoll(str);
|
devhost = std::stoll(str);
|
||||||
}
|
}
|
||||||
vr_.SetDevhostPid(devhost);
|
vr_.SetDevhostPid(devhost);
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
|
|
||||||
#include "subcommand_help.h"
|
#include "subcommand_help.h"
|
||||||
#include "debug_logger.h"
|
#include "debug_logger.h"
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
namespace OHOS {
|
namespace OHOS {
|
||||||
namespace Developtools {
|
namespace Developtools {
|
||||||
|
@ -181,7 +181,7 @@ bool SubCommandRecord::GetSpeOptions()
|
|||||||
for (auto item: valueExpressions) {
|
for (auto item: valueExpressions) {
|
||||||
std::vector<std::string> expressions = StringSplit(item, "=");
|
std::vector<std::string> expressions = StringSplit(item, "=");
|
||||||
size_t itemNum = 2;
|
size_t itemNum = 2;
|
||||||
if (expressions.size() == itemNum && IsNumberic(expressions[1])) {
|
if (expressions.size() == itemNum && IsNumeric(expressions[1])) {
|
||||||
std::string name = expressions[0];
|
std::string name = expressions[0];
|
||||||
unsigned long long num = std::stoull(expressions[1]);
|
unsigned long long num = std::stoull(expressions[1]);
|
||||||
if (speOptMap_.find(name) != speOptMap_.end()) {
|
if (speOptMap_.find(name) != speOptMap_.end()) {
|
||||||
@ -544,7 +544,7 @@ bool SubCommandRecord::CheckTargetProcessOptions()
|
|||||||
}
|
}
|
||||||
hasTarget = true;
|
hasTarget = true;
|
||||||
}
|
}
|
||||||
if (!hasTarget and (controlCmd_.empty() or controlCmd_ == CONTROL_CMD_PREPARE)) {
|
if (!hasTarget && (controlCmd_.empty() || controlCmd_ == CONTROL_CMD_PREPARE)) {
|
||||||
printf("please select a target process\n");
|
printf("please select a target process\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -601,11 +601,11 @@ bool SubCommandRecord::ParseDataLimitOption(const std::string &str)
|
|||||||
{
|
{
|
||||||
uint unit = 1;
|
uint unit = 1;
|
||||||
char c = str.at(str.size() >= 1 ? str.size() - 1 : 0);
|
char c = str.at(str.size() >= 1 ? str.size() - 1 : 0);
|
||||||
if (c == 'K' or c == 'k') {
|
if (c == 'K' || c == 'k') {
|
||||||
unit = KILO;
|
unit = KILO;
|
||||||
} else if (c == 'm' or c == 'M') {
|
} else if (c == 'm' || c == 'M') {
|
||||||
unit = KILO * KILO;
|
unit = KILO * KILO;
|
||||||
} else if (c == 'g' or c == 'G') {
|
} else if (c == 'g' || c == 'G') {
|
||||||
unit = KILO * KILO * KILO;
|
unit = KILO * KILO * KILO;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@ -697,8 +697,8 @@ bool SubCommandRecord::ParseBranchSampleType(const std::vector<std::string> &vec
|
|||||||
|
|
||||||
bool SubCommandRecord::ParseControlCmd(const std::string cmd)
|
bool SubCommandRecord::ParseControlCmd(const std::string cmd)
|
||||||
{
|
{
|
||||||
if (cmd.empty() or cmd == CONTROL_CMD_PREPARE or cmd == CONTROL_CMD_START or
|
if (cmd.empty() || cmd == CONTROL_CMD_PREPARE || cmd == CONTROL_CMD_START ||
|
||||||
cmd == CONTROL_CMD_PAUSE or cmd == CONTROL_CMD_RESUME or cmd == CONTROL_CMD_STOP) {
|
cmd == CONTROL_CMD_PAUSE || cmd == CONTROL_CMD_RESUME || cmd == CONTROL_CMD_STOP) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -783,7 +783,7 @@ bool SubCommandRecord::TraceOffCpu()
|
|||||||
int enable = -1;
|
int enable = -1;
|
||||||
std::string node = SCHED_SWITCH;
|
std::string node = SCHED_SWITCH;
|
||||||
const std::string nodeDebug = SCHED_SWITCH_DEBUG;
|
const std::string nodeDebug = SCHED_SWITCH_DEBUG;
|
||||||
CHECK_TRUE(!ReadIntFromProcFile(node.c_str(), enable) and !ReadIntFromProcFile(nodeDebug.c_str(), enable),
|
CHECK_TRUE(!ReadIntFromProcFile(node.c_str(), enable) && !ReadIntFromProcFile(nodeDebug.c_str(), enable),
|
||||||
false, LOG_TYPE_PRINTF, "Cannot trace off CPU, event sched:sched_switch is not available (%s or %s)\n",
|
false, LOG_TYPE_PRINTF, "Cannot trace off CPU, event sched:sched_switch is not available (%s or %s)\n",
|
||||||
node.c_str(), nodeDebug.c_str());
|
node.c_str(), nodeDebug.c_str());
|
||||||
|
|
||||||
@ -905,7 +905,7 @@ bool SubCommandRecord::PrepareVirtualRuntime()
|
|||||||
// do some config for virtualRuntime_
|
// do some config for virtualRuntime_
|
||||||
virtualRuntime_.SetCallStackExpend(disableCallstackExpend_ ? 0 : 1);
|
virtualRuntime_.SetCallStackExpend(disableCallstackExpend_ ? 0 : 1);
|
||||||
// these is same for virtual runtime
|
// these is same for virtual runtime
|
||||||
virtualRuntime_.SetDisableUnwind(disableUnwind_ or delayUnwind_);
|
virtualRuntime_.SetDisableUnwind(disableUnwind_ || delayUnwind_);
|
||||||
virtualRuntime_.EnableDebugInfoSymbolic(enableDebugInfoSymbolic_);
|
virtualRuntime_.EnableDebugInfoSymbolic(enableDebugInfoSymbolic_);
|
||||||
if (!symbolDir_.empty()) {
|
if (!symbolDir_.empty()) {
|
||||||
if (!virtualRuntime_.SetSymbolsPaths(symbolDir_)) {
|
if (!virtualRuntime_.SetSymbolsPaths(symbolDir_)) {
|
||||||
@ -1089,7 +1089,7 @@ bool SubCommandRecord::CreateFifoServer()
|
|||||||
{
|
{
|
||||||
char errInfo[ERRINFOLEN] = { 0 };
|
char errInfo[ERRINFOLEN] = { 0 };
|
||||||
const mode_t fifoMode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
|
const mode_t fifoMode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
|
||||||
if (mkfifo(CONTROL_FIFO_FILE_S2C.c_str(), fifoMode) != 0 or
|
if (mkfifo(CONTROL_FIFO_FILE_S2C.c_str(), fifoMode) != 0 ||
|
||||||
mkfifo(CONTROL_FIFO_FILE_C2S.c_str(), fifoMode) != 0) {
|
mkfifo(CONTROL_FIFO_FILE_C2S.c_str(), fifoMode) != 0) {
|
||||||
if (errno == EEXIST) {
|
if (errno == EEXIST) {
|
||||||
printf("another sampling service is running.\n");
|
printf("another sampling service is running.\n");
|
||||||
@ -1134,7 +1134,7 @@ bool SubCommandRecord::CreateFifoServer()
|
|||||||
if (fd != -1) {
|
if (fd != -1) {
|
||||||
WaitFifoReply(fd, CONTROL_WAITREPY_TOMEOUT, reply);
|
WaitFifoReply(fd, CONTROL_WAITREPY_TOMEOUT, reply);
|
||||||
}
|
}
|
||||||
if (fd == -1 or reply != HiperfClient::ReplyOK) {
|
if (fd == -1 || reply != HiperfClient::ReplyOK) {
|
||||||
if (reply != HiperfClient::ReplyOK) {
|
if (reply != HiperfClient::ReplyOK) {
|
||||||
printf("%s\n", reply.c_str());
|
printf("%s\n", reply.c_str());
|
||||||
}
|
}
|
||||||
@ -1225,7 +1225,7 @@ bool SubCommandRecord::OnSubCommand(std::vector<std::string> &args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// prepare PerfEvents
|
// prepare PerfEvents
|
||||||
if (!PrepareSysKernel() or !PreparePerfEvent()) {
|
if (!PrepareSysKernel() || !PreparePerfEvent()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,14 +123,14 @@ void SubCommandReport::DumpOptions() const
|
|||||||
bool SubCommandReport::VerifyDisplayOption()
|
bool SubCommandReport::VerifyDisplayOption()
|
||||||
{
|
{
|
||||||
for (std::string &number : reportOption_.displayPids_) {
|
for (std::string &number : reportOption_.displayPids_) {
|
||||||
if (!IsDigits(number) or number.front() == '-') {
|
if (!IsDigits(number) || number.front() == '-') {
|
||||||
printf("error number for pid '%s'\n", number.c_str());
|
printf("error number for pid '%s'\n", number.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::string &number : reportOption_.displayTids_) {
|
for (std::string &number : reportOption_.displayTids_) {
|
||||||
if (!IsDigits(number) or number.front() == '-') {
|
if (!IsDigits(number) || number.front() == '-') {
|
||||||
printf("error number for tid '%s'\n", number.c_str());
|
printf("error number for tid '%s'\n", number.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -151,11 +151,11 @@ bool SubCommandReport::VerifyOption()
|
|||||||
}
|
}
|
||||||
const float min = 0.0;
|
const float min = 0.0;
|
||||||
const float max = 100.0;
|
const float max = 100.0;
|
||||||
if (reportOption_.heatLimit_ < min or reportOption_.heatLimit_ > max) {
|
if (reportOption_.heatLimit_ < min || reportOption_.heatLimit_ > max) {
|
||||||
printf("head limit error. must in (0 <= limit < 100).\n");
|
printf("head limit error. must in (0 <= limit < 100).\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (reportOption_.callStackHeatLimit_ < min or reportOption_.callStackHeatLimit_ > max) {
|
if (reportOption_.callStackHeatLimit_ < min || reportOption_.callStackHeatLimit_ > max) {
|
||||||
printf("head limit error. must in (0 <= limit < 100).\n");
|
printf("head limit error. must in (0 <= limit < 100).\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -164,7 +164,7 @@ bool SubCommandReport::VerifyOption()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!recordFile_[SECOND].empty()) {
|
if (!recordFile_[SECOND].empty()) {
|
||||||
if (protobufFormat_ or jsonFormat_ or showCallStack_) {
|
if (protobufFormat_ || jsonFormat_ || showCallStack_) {
|
||||||
printf("diff don't support any export mode(like json , flame or proto)\n");
|
printf("diff don't support any export mode(like json , flame or proto)\n");
|
||||||
} else {
|
} else {
|
||||||
diffMode_ = true;
|
diffMode_ = true;
|
||||||
@ -256,7 +256,7 @@ bool SubCommandReport::RecordCallBack(std::unique_ptr<PerfEventRecord> record)
|
|||||||
HLOGV("current sample period %llu ", sample->data_.period);
|
HLOGV("current sample period %llu ", sample->data_.period);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (cpuOffMode_ and cpuOffids_.size() > 0 and cpuOffids_.count(sample->data_.id) > 0) {
|
if (cpuOffMode_ && cpuOffids_.size() > 0 && cpuOffids_.count(sample->data_.id) > 0) {
|
||||||
BroadcastSample(sample);
|
BroadcastSample(sample);
|
||||||
} else {
|
} else {
|
||||||
ProcessSample(sample);
|
ProcessSample(sample);
|
||||||
@ -369,7 +369,7 @@ void SubCommandReport::LoadEventDesc()
|
|||||||
|
|
||||||
HLOGV("event name[%zu]: %s ids: %s", i, fileAttr.name.c_str(),
|
HLOGV("event name[%zu]: %s ids: %s", i, fileAttr.name.c_str(),
|
||||||
VectorToString(fileAttr.ids).c_str());
|
VectorToString(fileAttr.ids).c_str());
|
||||||
if (cpuOffMode_ and fileAttr.name == cpuOffEventName) {
|
if (cpuOffMode_ && fileAttr.name == cpuOffEventName) {
|
||||||
// found cpuoff event id
|
// found cpuoff event id
|
||||||
std::set<uint64_t> cpuOffids(fileAttr.ids.begin(), fileAttr.ids.end());
|
std::set<uint64_t> cpuOffids(fileAttr.ids.begin(), fileAttr.ids.end());
|
||||||
cpuOffids_ = cpuOffids;
|
cpuOffids_ = cpuOffids;
|
||||||
@ -440,7 +440,7 @@ void SubCommandReport::FlushCacheRecord()
|
|||||||
for (auto &pair : prevSampleCache_) {
|
for (auto &pair : prevSampleCache_) {
|
||||||
std::unique_ptr<PerfRecordSample> sample = std::move(pair.second);
|
std::unique_ptr<PerfRecordSample> sample = std::move(pair.second);
|
||||||
sample->data_.period = 1u;
|
sample->data_.period = 1u;
|
||||||
if (cpuOffMode_ and cpuOffids_.size() > 0 and cpuOffids_.count(sample->data_.id) > 0) {
|
if (cpuOffMode_ && cpuOffids_.size() > 0 && cpuOffids_.count(sample->data_.id) > 0) {
|
||||||
BroadcastSample(sample);
|
BroadcastSample(sample);
|
||||||
} else {
|
} else {
|
||||||
ProcessSample(sample);
|
ProcessSample(sample);
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
|
|
||||||
const uint16_t ONE_HUNDRED = 100;
|
const uint16_t ONE_HUNDRED = 100;
|
||||||
const uint16_t THOUSNADS_SEPARATOR = 3;
|
const uint16_t THOUSANDS_SEPARATOR = 3;
|
||||||
namespace OHOS {
|
namespace OHOS {
|
||||||
namespace Developtools {
|
namespace Developtools {
|
||||||
namespace HiPerf {
|
namespace HiPerf {
|
||||||
@ -56,7 +56,7 @@ void SubCommandStat::DumpOptions() const
|
|||||||
|
|
||||||
bool SubCommandStat::ParseOption(std::vector<std::string> &args)
|
bool SubCommandStat::ParseOption(std::vector<std::string> &args)
|
||||||
{
|
{
|
||||||
if (args.size() == 1 and args[0] == "-h") {
|
if (args.size() == 1 && args[0] == "-h") {
|
||||||
args.clear();
|
args.clear();
|
||||||
helpOption_ = true;
|
helpOption_ = true;
|
||||||
PrintUsage();
|
PrintUsage();
|
||||||
@ -203,7 +203,7 @@ void SubCommandStat::PrintPerValue(const std::unique_ptr<PerfEvents::ReportSum>
|
|||||||
// print value
|
// print value
|
||||||
std::string strEventCount = std::to_string(reportSum->eventCountSum);
|
std::string strEventCount = std::to_string(reportSum->eventCountSum);
|
||||||
for (size_t i = strEventCount.size() >= 1 ? strEventCount.size() - 1 : 0, j = 1; i > 0; --i, ++j) {
|
for (size_t i = strEventCount.size() >= 1 ? strEventCount.size() - 1 : 0, j = 1; i > 0; --i, ++j) {
|
||||||
if (j == THOUSNADS_SEPARATOR) {
|
if (j == THOUSANDS_SEPARATOR) {
|
||||||
j = 0;
|
j = 0;
|
||||||
strEventCount.insert(strEventCount.begin() + i, ',');
|
strEventCount.insert(strEventCount.begin() + i, ',');
|
||||||
}
|
}
|
||||||
@ -306,7 +306,7 @@ void SubCommandStat::ReportNormal(
|
|||||||
std::string comment = comments[configName];
|
std::string comment = comments[configName];
|
||||||
std::string strEventCount = std::to_string(it->second->eventCount);
|
std::string strEventCount = std::to_string(it->second->eventCount);
|
||||||
for (size_t i = strEventCount.size() >= 1 ? strEventCount.size() - 1 : 0, j = 1; i > 0; --i, ++j) {
|
for (size_t i = strEventCount.size() >= 1 ? strEventCount.size() - 1 : 0, j = 1; i > 0; --i, ++j) {
|
||||||
if (j == THOUSNADS_SEPARATOR) {
|
if (j == THOUSANDS_SEPARATOR) {
|
||||||
strEventCount.insert(strEventCount.begin() + i, ',');
|
strEventCount.insert(strEventCount.begin() + i, ',');
|
||||||
j = 0;
|
j = 0;
|
||||||
}
|
}
|
||||||
@ -610,7 +610,9 @@ bool SubCommandStat::CheckOptionPid(std::vector<pid_t> pids)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (auto pid : pids) {
|
for (auto pid : pids) {
|
||||||
if (!IsDir("/proc/" + std::to_string(pid))) {
|
std::ostringstream oss;
|
||||||
|
oss << "/proc/" << pid;
|
||||||
|
if (!IsDir(oss.str())) {
|
||||||
printf("not exit pid %d\n", pid);
|
printf("not exit pid %d\n", pid);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -43,9 +43,6 @@
|
|||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
#include "ipc_utilities.h"
|
#include "ipc_utilities.h"
|
||||||
|
|
||||||
using namespace OHOS::HiviewDFX;
|
|
||||||
using namespace std::chrono;
|
|
||||||
|
|
||||||
namespace OHOS {
|
namespace OHOS {
|
||||||
namespace Developtools {
|
namespace Developtools {
|
||||||
namespace HiPerf {
|
namespace HiPerf {
|
||||||
@ -98,7 +95,7 @@ std::string SymbolsFile::SearchReadableFile(const std::vector<std::string> &sear
|
|||||||
const std::string &filePath) const
|
const std::string &filePath) const
|
||||||
{
|
{
|
||||||
if (filePath.empty()) {
|
if (filePath.empty()) {
|
||||||
HLOGW("nothing to found");
|
HLOGW("filePath is empty, nothing to found");
|
||||||
return filePath;
|
return filePath;
|
||||||
}
|
}
|
||||||
for (auto searchPath : searchPaths) {
|
for (auto searchPath : searchPaths) {
|
||||||
@ -154,7 +151,7 @@ const std::string SymbolsFile::FindSymbolFile(
|
|||||||
|
|
||||||
// only access the patch in onRecording_
|
// only access the patch in onRecording_
|
||||||
// in report mode we don't load any thing in runtime path
|
// in report mode we don't load any thing in runtime path
|
||||||
if (foundPath.empty() and onRecording_) {
|
if (foundPath.empty() && onRecording_) {
|
||||||
// try access direct at last
|
// try access direct at last
|
||||||
if (CheckPathReadable(symboleFilePath)) {
|
if (CheckPathReadable(symboleFilePath)) {
|
||||||
// found direct folder
|
// found direct folder
|
||||||
@ -799,7 +796,7 @@ public:
|
|||||||
bool LoadSymbols(std::shared_ptr<DfxMap> map, const std::string &symbolFilePath) override
|
bool LoadSymbols(std::shared_ptr<DfxMap> map, const std::string &symbolFilePath) override
|
||||||
{
|
{
|
||||||
symbolsLoaded_ = true;
|
symbolsLoaded_ = true;
|
||||||
if (module_ == filePath_ and onRecording_) {
|
if (module_ == filePath_ && onRecording_) {
|
||||||
// file name still not convert to ko file path
|
// file name still not convert to ko file path
|
||||||
// this is in record mode
|
// this is in record mode
|
||||||
HLOGV("find ko name %s", module_.c_str());
|
HLOGV("find ko name %s", module_.c_str());
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
namespace OHOS {
|
namespace OHOS {
|
||||||
namespace Developtools {
|
namespace Developtools {
|
||||||
namespace HiPerf {
|
namespace HiPerf {
|
||||||
|
static uint64_t MAX_LOOP_COUNT = 10000;
|
||||||
|
|
||||||
std::unique_ptr<TrackedCommand> TrackedCommand::CreateInstance(const std::vector<std::string> &args)
|
std::unique_ptr<TrackedCommand> TrackedCommand::CreateInstance(const std::vector<std::string> &args)
|
||||||
{
|
{
|
||||||
std::unique_ptr<TrackedCommand> command {new (std::nothrow) TrackedCommand(args)};
|
std::unique_ptr<TrackedCommand> command {new (std::nothrow) TrackedCommand(args)};
|
||||||
@ -104,9 +106,14 @@ bool TrackedCommand::StartCommand()
|
|||||||
// send start signal to start execution of command
|
// send start signal to start execution of command
|
||||||
ssize_t nbyte {0};
|
ssize_t nbyte {0};
|
||||||
char startSignal {1};
|
char startSignal {1};
|
||||||
|
int loopCount = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
nbyte = write(startFd_, &startSignal, 1);
|
nbyte = write(startFd_, &startSignal, 1);
|
||||||
if (nbyte == -1) {
|
if (nbyte == -1) {
|
||||||
|
if (loopCount++ > MAX_LOOP_COUNT) {
|
||||||
|
HLOGE("read failed.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -115,9 +122,14 @@ bool TrackedCommand::StartCommand()
|
|||||||
// check execution state of command
|
// check execution state of command
|
||||||
// read acknowledgement signal
|
// read acknowledgement signal
|
||||||
char ackSignal {0};
|
char ackSignal {0};
|
||||||
|
loopCount = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
nbyte = read(ackFd_, &ackSignal, 1);
|
nbyte = read(ackFd_, &ackSignal, 1);
|
||||||
if (nbyte == -1 and (errno == EINTR or errno == EIO)) {
|
if (nbyte == -1 && (errno == EINTR || errno == EIO)) {
|
||||||
|
if (loopCount++ > MAX_LOOP_COUNT) {
|
||||||
|
HLOGE("read failed.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
HLOGE("*** nbyte: %zd, ackSignal: %d ***\n", nbyte, ackSignal);
|
HLOGE("*** nbyte: %zd, ackSignal: %d ***\n", nbyte, ackSignal);
|
||||||
@ -140,9 +152,14 @@ void TrackedCommand::ExecuteCommand(const int &startFd, const int &ackFd)
|
|||||||
// waiting start signal
|
// waiting start signal
|
||||||
char startSignal {0};
|
char startSignal {0};
|
||||||
ssize_t nbyte {0};
|
ssize_t nbyte {0};
|
||||||
|
int loopCount = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
nbyte = read(startFd, &startSignal, 1);
|
nbyte = read(startFd, &startSignal, 1);
|
||||||
if (nbyte == -1) {
|
if (nbyte == -1) {
|
||||||
|
if (loopCount++ > MAX_LOOP_COUNT) {
|
||||||
|
HLOGE("read failed.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -162,9 +179,14 @@ void TrackedCommand::ExecuteCommand(const int &startFd, const int &ackFd)
|
|||||||
}
|
}
|
||||||
// execv() or execvp() failed, send failure signal
|
// execv() or execvp() failed, send failure signal
|
||||||
char ackSignal {1};
|
char ackSignal {1};
|
||||||
|
loopCount = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
nbyte = write(ackFd, &ackSignal, 1);
|
nbyte = write(ackFd, &ackSignal, 1);
|
||||||
if (nbyte == -1) {
|
if (nbyte == -1) {
|
||||||
|
if (loopCount++ > MAX_LOOP_COUNT) {
|
||||||
|
HLOGE("read failed.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -180,7 +202,7 @@ bool TrackedCommand::WaitCommand(int &wstatus)
|
|||||||
pid_t pid = waitpid(childPid_, &wstatus, WNOHANG);
|
pid_t pid = waitpid(childPid_, &wstatus, WNOHANG);
|
||||||
if (pid == 0) {
|
if (pid == 0) {
|
||||||
return false;
|
return false;
|
||||||
} else { // pid == childPid_ or pid == -1
|
} else { // pid == childPid_ || pid == -1
|
||||||
childPid_ = -1;
|
childPid_ = -1;
|
||||||
state_ = State::COMMAND_STOPPED;
|
state_ = State::COMMAND_STOPPED;
|
||||||
return true;
|
return true;
|
||||||
|
@ -182,8 +182,8 @@ bool UniqueStackTable::GetIpsByStackId(StackId stackId, std::vector<u64>& ips)
|
|||||||
|
|
||||||
bool UniqueStackTable::ImportNode(uint32_t index, const Node& node)
|
bool UniqueStackTable::ImportNode(uint32_t index, const Node& node)
|
||||||
{
|
{
|
||||||
Node *tableHead = reinterpret_cast<Node *>(tableBuf_.get());
|
|
||||||
CHECK_TRUE(index >= tableSize_, false, 0, "");
|
CHECK_TRUE(index >= tableSize_, false, 0, "");
|
||||||
|
Node *tableHead = reinterpret_cast<Node *>(tableBuf_.get());
|
||||||
tableHead[index].value = node.value;
|
tableHead[index].value = node.value;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -280,7 +280,7 @@ std::string ReadFileToString(const std::string &fileName)
|
|||||||
{
|
{
|
||||||
std::string resolvedPath = CanonicalizeSpecPath(fileName.c_str());
|
std::string resolvedPath = CanonicalizeSpecPath(fileName.c_str());
|
||||||
std::ifstream inputString(resolvedPath, std::ios::in);
|
std::ifstream inputString(resolvedPath, std::ios::in);
|
||||||
if (!inputString or !inputString.is_open()) {
|
if (!inputString || !inputString.is_open()) {
|
||||||
return EMPTY_STRING;
|
return EMPTY_STRING;
|
||||||
}
|
}
|
||||||
std::istreambuf_iterator<char> firstIt = {inputString};
|
std::istreambuf_iterator<char> firstIt = {inputString};
|
||||||
@ -845,7 +845,7 @@ bool IsHiviewCall()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsNumberic(const std::string& str)
|
bool IsNumeric(const std::string& str)
|
||||||
{
|
{
|
||||||
std::istringstream iss(str);
|
std::istringstream iss(str);
|
||||||
int number;
|
int number;
|
||||||
|
@ -248,7 +248,11 @@ void VirtualRuntime::UpdateKernelModulesSpaceMaps()
|
|||||||
while (getline(ifs, line)) {
|
while (getline(ifs, line)) {
|
||||||
uint64_t addr = 0;
|
uint64_t addr = 0;
|
||||||
uint64_t size = 0;
|
uint64_t size = 0;
|
||||||
char module[line.size()];
|
uint64_t lineSize = line.size();
|
||||||
|
if (lineSize > 4096) { // 4096: line length
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
char *module = new char[lineSize];
|
||||||
/*
|
/*
|
||||||
name size load map
|
name size load map
|
||||||
hi_mipi_rx 53248 0 - Live 0xbf109000 (O)
|
hi_mipi_rx 53248 0 - Live 0xbf109000 (O)
|
||||||
@ -262,7 +266,7 @@ void VirtualRuntime::UpdateKernelModulesSpaceMaps()
|
|||||||
hi3516cv500_base,sys_config,hi_proc,hi_irq,Live 0xbf000000 (O)
|
hi3516cv500_base,sys_config,hi_proc,hi_irq,Live 0xbf000000 (O)
|
||||||
*/
|
*/
|
||||||
int ret = sscanf_s(line.c_str(), "%s%" PRIu64 "%*u%*s%*s 0x%" PRIx64 "", module,
|
int ret = sscanf_s(line.c_str(), "%s%" PRIu64 "%*u%*s%*s 0x%" PRIx64 "", module,
|
||||||
sizeof(module), &size, &addr, sizeof(addr));
|
lineSize, &size, &addr, sizeof(addr));
|
||||||
constexpr int numSlices {3};
|
constexpr int numSlices {3};
|
||||||
if (ret == numSlices) {
|
if (ret == numSlices) {
|
||||||
auto &map = koMaps.emplace_back(addr, addr + size, 0, "", std::string(module));
|
auto &map = koMaps.emplace_back(addr, addr + size, 0, "", std::string(module));
|
||||||
@ -270,6 +274,7 @@ void VirtualRuntime::UpdateKernelModulesSpaceMaps()
|
|||||||
} else {
|
} else {
|
||||||
HLOGE("unknown line %d: '%s'", ret, line.c_str());
|
HLOGE("unknown line %d: '%s'", ret, line.c_str());
|
||||||
}
|
}
|
||||||
|
delete []module;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (std::all_of(koMaps.begin(), koMaps.end(),
|
if (std::all_of(koMaps.begin(), koMaps.end(),
|
||||||
@ -1062,13 +1067,13 @@ const DfxSymbol VirtualRuntime::GetUserSymbol(uint64_t ip, const VirtualThread &
|
|||||||
bool VirtualRuntime::GetSymbolCache(uint64_t fileVaddr, DfxSymbol &symbol,
|
bool VirtualRuntime::GetSymbolCache(uint64_t fileVaddr, DfxSymbol &symbol,
|
||||||
const perf_callchain_context &context)
|
const perf_callchain_context &context)
|
||||||
{
|
{
|
||||||
if (context == PERF_CONTEXT_MAX and kThreadSymbolCache_.count(fileVaddr)) {
|
if (context == PERF_CONTEXT_MAX && kThreadSymbolCache_.count(fileVaddr)) {
|
||||||
CHECK_TRUE(kThreadSymbolCache_.find(symbol.fileVaddr_) == kThreadSymbolCache_.end(), false, 0, "");
|
CHECK_TRUE(kThreadSymbolCache_.find(symbol.fileVaddr_) == kThreadSymbolCache_.end(), false, 0, "");
|
||||||
symbol = kThreadSymbolCache_[symbol.fileVaddr_];
|
symbol = kThreadSymbolCache_[symbol.fileVaddr_];
|
||||||
symbol.hit_++;
|
symbol.hit_++;
|
||||||
HLOGV("hit kernel thread cache 0x%" PRIx64 " %d", fileVaddr, symbol.hit_);
|
HLOGV("hit kernel thread cache 0x%" PRIx64 " %d", fileVaddr, symbol.hit_);
|
||||||
return true;
|
return true;
|
||||||
} else if (context != PERF_CONTEXT_USER and kernelSymbolCache_.count(fileVaddr)) {
|
} else if (context != PERF_CONTEXT_USER && kernelSymbolCache_.count(fileVaddr)) {
|
||||||
CHECK_TRUE(kernelSymbolCache_.find(symbol.fileVaddr_) == kernelSymbolCache_.end(), false, 0, "");
|
CHECK_TRUE(kernelSymbolCache_.find(symbol.fileVaddr_) == kernelSymbolCache_.end(), false, 0, "");
|
||||||
symbol = kernelSymbolCache_[symbol.fileVaddr_];
|
symbol = kernelSymbolCache_[symbol.fileVaddr_];
|
||||||
symbol.hit_++;
|
symbol.hit_++;
|
||||||
@ -1110,7 +1115,7 @@ DfxSymbol VirtualRuntime::GetSymbol(uint64_t ip, pid_t pid, pid_t tid, const per
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context == PERF_CONTEXT_USER or (context == PERF_CONTEXT_MAX and !symbol.IsValid())) {
|
if (context == PERF_CONTEXT_USER || (context == PERF_CONTEXT_MAX && !symbol.IsValid())) {
|
||||||
// check userspace memmap
|
// check userspace memmap
|
||||||
symbol = GetUserSymbol(ip, GetThread(pid, tid));
|
symbol = GetUserSymbol(ip, GetThread(pid, tid));
|
||||||
if (userSymbolCache_.find(symbol.fileVaddr_) == userSymbolCache_.end()) {
|
if (userSymbolCache_.find(symbol.fileVaddr_) == userSymbolCache_.end()) {
|
||||||
@ -1121,7 +1126,7 @@ DfxSymbol VirtualRuntime::GetSymbol(uint64_t ip, pid_t pid, pid_t tid, const per
|
|||||||
userSymbolCache_[symbol.fileVaddr_].ToDebugString().c_str());
|
userSymbolCache_[symbol.fileVaddr_].ToDebugString().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context == PERF_CONTEXT_KERNEL or (context == PERF_CONTEXT_MAX and !symbol.IsValid())) {
|
if (context == PERF_CONTEXT_KERNEL || (context == PERF_CONTEXT_MAX && !symbol.IsValid())) {
|
||||||
// check kernelspace
|
// check kernelspace
|
||||||
HLOGM("try found addr in kernelspace %zu maps", kernelSpaceMemMaps_.size());
|
HLOGM("try found addr in kernelspace %zu maps", kernelSpaceMemMaps_.size());
|
||||||
symbol = GetKernelSymbol(ip, kernelSpaceMemMaps_, GetThread(pid, tid));
|
symbol = GetKernelSymbol(ip, kernelSpaceMemMaps_, GetThread(pid, tid));
|
||||||
|
@ -366,7 +366,7 @@ void VirtualThread::SortMemMaps()
|
|||||||
{
|
{
|
||||||
for (int currPos = 1; currPos < static_cast<int>(memMaps_.size()); ++currPos) {
|
for (int currPos = 1; currPos < static_cast<int>(memMaps_.size()); ++currPos) {
|
||||||
int targetPos = currPos - 1;
|
int targetPos = currPos - 1;
|
||||||
while (targetPos >= 0 and memMaps_[memMapsIndexs_[currPos]]->end < memMaps_[memMapsIndexs_[targetPos]]->end) {
|
while (targetPos >= 0 && memMaps_[memMapsIndexs_[currPos]]->end < memMaps_[memMapsIndexs_[targetPos]]->end) {
|
||||||
--targetPos;
|
--targetPos;
|
||||||
}
|
}
|
||||||
if (targetPos < currPos - 1) {
|
if (targetPos < currPos - 1) {
|
||||||
|
Loading…
Reference in New Issue
Block a user