diff --git a/device/plugins/native_daemon/native_memory_profiler_sa/include/native_memory_profiler_sa_client_manager.h b/device/plugins/native_daemon/native_memory_profiler_sa/include/native_memory_profiler_sa_client_manager.h index 7a1b4599a3f2e4413b15fa4d4a1f81bf5fccdd97..44c92d15cac4cbea49fdaacda8170a1ebeb8efbe 100644 --- a/device/plugins/native_daemon/native_memory_profiler_sa/include/native_memory_profiler_sa_client_manager.h +++ b/device/plugins/native_daemon/native_memory_profiler_sa/include/native_memory_profiler_sa_client_manager.h @@ -33,7 +33,7 @@ public: static int32_t Stop(uint32_t pid); static int32_t Stop(const std::string& name); static int32_t DumpData(uint32_t fd, std::shared_ptr& config); - static int32_t GetMallocStats(int fd, int pid, int type); + static int32_t GetMallocStats(int fd, int pid, int type, bool printNmdOnly = false); static sptr GetRemoteService(); private: diff --git a/device/plugins/native_daemon/native_memory_profiler_sa/include/native_memory_profiler_sa_config.h b/device/plugins/native_daemon/native_memory_profiler_sa/include/native_memory_profiler_sa_config.h index 8e7e8312e249137d9fdac08ccb0ee87e8b21494f..d1d9e529a06209c28e0c5f41b29ce548ae21cacf 100644 --- a/device/plugins/native_daemon/native_memory_profiler_sa/include/native_memory_profiler_sa_config.h +++ b/device/plugins/native_daemon/native_memory_profiler_sa/include/native_memory_profiler_sa_config.h @@ -56,6 +56,7 @@ public: uint32_t sampleInterval_{0}; bool responseLibraryMode_{false}; bool printNmd_{false}; + bool printNmdOnly_{false}; uint32_t nmdPid_{0}; uint32_t nmdType_{0}; int32_t jsStackReport_{0}; diff --git a/device/plugins/native_daemon/native_memory_profiler_sa/src/native_memory_profiler_sa_client_manager.cpp b/device/plugins/native_daemon/native_memory_profiler_sa/src/native_memory_profiler_sa_client_manager.cpp index b227a1e7acb158a15fe5baa53a690f2fd602ff49..652e38c59d2c3704df857c4da82552729f540c54 100644 --- a/device/plugins/native_daemon/native_memory_profiler_sa/src/native_memory_profiler_sa_client_manager.cpp +++ b/device/plugins/native_daemon/native_memory_profiler_sa/src/native_memory_profiler_sa_client_manager.cpp @@ -23,6 +23,9 @@ namespace OHOS::Developtools::NativeDaemon { namespace { constexpr uint32_t LIB_SMS = 4096; constexpr uint32_t CALL_STACK_SMS = 16384; +constexpr uint32_t NMD_DURATION = 5; +constexpr uint32_t NMD_SHMEM = 300; +constexpr int ONLY_NMD = 2; } int32_t NativeMemoryProfilerSaClientManager::Start(std::shared_ptr& config) @@ -119,15 +122,26 @@ bool NativeMemoryProfilerSaClientManager::CheckConfig(const std::shared_ptr 0, RET_ERR, "NativeMemoryProfilerSaClientManager: GetMallocStats invalid pid"); - CHECK_TRUE(type == 0 || type == 1, RET_ERR, "NativeMemoryProfilerSaClientManager: type is invalid"); + CHECK_TRUE(type == 0 || type == 1 || type == ONLY_NMD, RET_ERR, + "NativeMemoryProfilerSaClientManager: type is invalid"); std::shared_ptr config = std::make_shared(); config->printNmd_ = true; + config->printNmdOnly_ = printNmdOnly; + if (config->printNmdOnly_) { + config->pid_ = static_cast(pid); + config->duration_ = NMD_DURATION; + config->mallocDisable_ = true; + config->mmapDisable_ = true; + config->shareMemorySize_ = NMD_SHMEM; + } config->nmdPid_ = static_cast(pid); config->nmdType_ = static_cast(type); + CHECK_NOTNULL(config, RET_ERR, "NativeMemoryProfilerSaClientManager: config is nullptr"); + CHECK_TRUE(CheckConfig(config), RET_ERR, "CheckConfig failed"); auto service = GetRemoteService(); if (service == nullptr) { PROFILER_LOG_ERROR(LOG_CORE, "NativeMemoryProfilerSaClientManager: stop GetRemoteService failed"); diff --git a/device/plugins/native_daemon/native_memory_profiler_sa/src/native_memory_profiler_sa_config.cpp b/device/plugins/native_daemon/native_memory_profiler_sa/src/native_memory_profiler_sa_config.cpp index d10a254b794d884dcc2e2f19c26a90d0aa723fe5..332590474db223d48d76f164911a72bed9f9c6c4 100644 --- a/device/plugins/native_daemon/native_memory_profiler_sa/src/native_memory_profiler_sa_config.cpp +++ b/device/plugins/native_daemon/native_memory_profiler_sa/src/native_memory_profiler_sa_config.cpp @@ -46,6 +46,7 @@ bool NativeMemoryProfilerSaConfig::Marshalling(Parcel& parcel) const WRITEUINT32(parcel, sampleInterval_); WRITEBOOL(parcel, responseLibraryMode_); WRITEBOOL(parcel, printNmd_); + WRITEBOOL(parcel, printNmdOnly_); WRITEUINT32(parcel, nmdPid_); WRITEUINT32(parcel, nmdType_); WRITEINT32(parcel, jsStackReport_); @@ -85,6 +86,7 @@ bool NativeMemoryProfilerSaConfig::Unmarshalling(Parcel& parcel, std::shared_ptr READUINT32(parcel, config->sampleInterval_); READBOOL(parcel, config->responseLibraryMode_); READBOOL(parcel, config->printNmd_); + READBOOL(parcel, config->printNmdOnly_); READUINT32(parcel, config->nmdPid_); READUINT32(parcel, config->nmdType_); READINT32(parcel, config->jsStackReport_); diff --git a/device/plugins/native_daemon/native_memory_profiler_sa/src/native_memory_profiler_sa_service.cpp b/device/plugins/native_daemon/native_memory_profiler_sa/src/native_memory_profiler_sa_service.cpp index 2f50d3645298d668d453fd1c7cc0635b2b50fd50..da1a28bde154dcf9038047782dd7d3254ab947dd 100644 --- a/device/plugins/native_daemon/native_memory_profiler_sa/src/native_memory_profiler_sa_service.cpp +++ b/device/plugins/native_daemon/native_memory_profiler_sa/src/native_memory_profiler_sa_service.cpp @@ -113,7 +113,9 @@ int32_t NativeMemoryProfilerSaService::DumpData(uint32_t fd, std::shared_ptrprintNmd_) { std::lock_guard guard(nmdMtx_); nmdPidType_[config->nmdPid_] = std::make_pair(fd, config->nmdType_); - return RET_OK; + if (!config->printNmdOnly_) { + return RET_OK; + } } if (StartHook(config, fd) == RET_ERR) { close(fd); @@ -236,8 +238,12 @@ int32_t NativeMemoryProfilerSaService::StartHook(std::shared_ptr= 0, RET_ERR, "Failed to open file(%s)", config->filePath_.c_str()); fd = static_cast(fdTemp); } - - std::shared_ptr writeFile = std::make_shared(fd); + std::shared_ptr writeFile = nullptr; + if (config->printNmdOnly_) { + writeFile = std::make_shared(0); + } else { + writeFile = std::make_shared(fd); + } CHECK_NOTNULL(writeFile, RET_ERR, "Failed to create TraceFileWriter"); writeFile->SetTimeSource(); @@ -258,7 +264,9 @@ int32_t NativeMemoryProfilerSaService::StartHook(std::shared_ptrWriteHookConfig(); + if (!config->printNmdOnly_) { + hook->WriteHookConfig(); + } hook->StartPluginSession(); int32_t timerFd = scheduleTaskManager_.ScheduleTask( diff --git a/device/plugins/native_daemon/native_memory_profiler_sa/test/unittest/native_memory_profiler_sa_client_manager_test.cpp b/device/plugins/native_daemon/native_memory_profiler_sa/test/unittest/native_memory_profiler_sa_client_manager_test.cpp index 88caed4058bcea8f565a60813f78707aa94c4bb1..7c1db17e744b0a36e3be1ea12d171fbf7145828f 100644 --- a/device/plugins/native_daemon/native_memory_profiler_sa/test/unittest/native_memory_profiler_sa_client_manager_test.cpp +++ b/device/plugins/native_daemon/native_memory_profiler_sa/test/unittest/native_memory_profiler_sa_client_manager_test.cpp @@ -34,6 +34,7 @@ using namespace testing::ext; namespace { const std::string NATIVE_PARAM = "hiviewdfx.hiprofiler.native_memoryd.start"; const std::string TEST_PROC_NAME = "hiview"; +const int NMD_ONLY_TYPE = 2; } class NativeMemoryProfilerSaClientManagerTest : public testing::Test { @@ -121,4 +122,20 @@ HWTEST_F(NativeMemoryProfilerSaClientManagerTest, NativeMemoryProfilerSaClientMa sleep(1); } +/** + * @tc.name: NativeMemoryProfilerSaClientManagerTest003 + * @tc.desc: Test nmd-only mode + * @tc.type: FUNC + */ +HWTEST_F(NativeMemoryProfilerSaClientManagerTest, NativeMemoryProfilerSaClientManagerTest003, TestSize.Level3) +{ + using namespace OHOS::Developtools::NativeDaemon; + using namespace OHOS::Security::AccessToken; + AccessTokenID tokenID = AccessTokenKit::GetNativeTokenId(TEST_PROC_NAME); + SetSelfTokenID(tokenID); + + EXPECT_EQ(NativeMemoryProfilerSaClientManager::GetMallocStats(0, 0, NMD_ONLY_TYPE, true), RET_ERR); + EXPECT_EQ(NativeMemoryProfilerSaClientManager::GetMallocStats(0, 0, 1), RET_ERR); +} + #endif // NATIVE_MEMORY_PROFILER_SA_CLINET_MANAGER_TEST_H \ No newline at end of file diff --git a/device/plugins/native_daemon/src/stack_preprocess.cpp b/device/plugins/native_daemon/src/stack_preprocess.cpp index 1b356b49c8f8985ae43995c49dba9d6576a10938..d9fafb88c54fae3a97a2235bb74e71b224d832da 100644 --- a/device/plugins/native_daemon/src/stack_preprocess.cpp +++ b/device/plugins/native_daemon/src/stack_preprocess.cpp @@ -132,7 +132,7 @@ StackPreprocess::~StackPreprocess() void StackPreprocess::FinishTraceFile() { - if (isSaService_) { + if (isSaService_ && (writer_ != nullptr)) { std::shared_ptr tfPtr = std::static_pointer_cast(writer_); tfPtr->SetDurationTime(); tfPtr->Finish(); @@ -149,6 +149,9 @@ void StackPreprocess::SetWriter(const std::shared_ptr& writer) void StackPreprocess::SetWriter(const WriterStructPtr& writer) { + if (writer == nullptr) { + return; + } resultWriter_ = writer; auto ctx = resultWriter_->startReport(resultWriter_); if (ctx == nullptr) { @@ -1277,7 +1280,7 @@ void StackPreprocess::FlushData(ProtoEncoder::BatchNativeHookData& stackData) int messageLen = stackData.Finish(); RandomWriteCtx* ctx = nullptr; - if (!isSaService_) { + if ((!isSaService_) && (resultWriter_ != nullptr)) { resultWriter_->finishReport(resultWriter_, messageLen); resultWriter_->flush(resultWriter_); ctx = resultWriter_->startReport(resultWriter_); @@ -1482,9 +1485,10 @@ void StackPreprocess::WriteHookConfig() const size_t configSize = hookConfig_.ByteSizeLong(); auto buffer = std::make_unique(configSize); hookConfig_.SerializeToArray(buffer.get(), configSize); - - writer_->ResetPos(); - profilerPluginData_.Reset(writer_->GetCtx()); + if (writer_ != nullptr) { + writer_->ResetPos(); + profilerPluginData_.Reset(writer_->GetCtx()); + } profilerPluginData_.set_name("nativehook_config"); profilerPluginData_.set_version("1.02"); profilerPluginData_.set_status(0); @@ -1502,8 +1506,10 @@ void StackPreprocess::WriteHookConfig() RandomWriteCtx* StackPreprocess::StartReport() { - writer_->ResetPos(); - profilerPluginData_.Reset(writer_->GetCtx()); + if (writer_ != nullptr) { + writer_->ResetPos(); + profilerPluginData_.Reset(writer_->GetCtx()); + } profilerPluginData_.set_name("nativehook"); profilerPluginData_.set_version("1.02"); profilerPluginData_.set_status(0); diff --git a/device/plugins/native_hook/src/hook_client.cpp b/device/plugins/native_hook/src/hook_client.cpp index 86bda6ae93c43d53aa9113f848d619788dfd06df..1b3345903f0e878c76736a893442de9b78ef8633 100644 --- a/device/plugins/native_hook/src/hook_client.cpp +++ b/device/plugins/native_hook/src/hook_client.cpp @@ -1187,7 +1187,7 @@ int hook_prctl(int(*fn)(int, ...), if (fn) { ret = fn(option, arg2, arg3, arg4, arg5); } - if (reinterpret_cast(arg5) == nullptr || IsPidChanged()) { + if (reinterpret_cast(arg5) == nullptr || IsPidChanged() || g_ClientConfig.mmapDisable) { return ret; } std::weak_ptr weakClient = g_hookClient; diff --git a/device/plugins/native_hook/src/hook_socket_client.cpp b/device/plugins/native_hook/src/hook_socket_client.cpp index 1dc0d61ecc29baebe5f2121da26882bc24eb3c6d..1179ad2517890aa56d987aa2723c4daa3c80fef2 100644 --- a/device/plugins/native_hook/src/hook_socket_client.cpp +++ b/device/plugins/native_hook/src/hook_socket_client.cpp @@ -31,6 +31,7 @@ namespace { constexpr int FLUSH_FLAG = 20; +constexpr int ONLY_NMD_TYPE = 2; std::atomic g_flushCount = 0; std::atomic g_disableHook = false; constexpr uint32_t MEMCHECK_DETAILINFO_MAXSIZE = 102400; @@ -127,7 +128,7 @@ bool HookSocketClient::ProtocolProc(SocketContext &context, uint32_t pnum, const smbFd_, eventFd_, config_->isBlocked); struct mallinfo2 mi = mallinfo2(); nmdType_ = config_->nmdType; - if (nmdType_ == 0) { + if (nmdType_ == 0 || nmdType_ == ONLY_NMD_TYPE) { SendNmdInfo(); } return true; diff --git a/device/services/profiler_service/src/trace_file_writer.cpp b/device/services/profiler_service/src/trace_file_writer.cpp index efa9accf891d085a53af464767646b54891c5cc8..b269420d658ebd13fec6052b6cc75941ae4ee544 100644 --- a/device/services/profiler_service/src/trace_file_writer.cpp +++ b/device/services/profiler_service/src/trace_file_writer.cpp @@ -46,6 +46,7 @@ TraceFileWriter::TraceFileWriter(const std::string& path) : TraceFileWriter(path TraceFileWriter::TraceFileWriter(int32_t fd) : fd_(fd) { + CHECK_TRUE(fd_ != 0, NO_RETVAL, "only-nmd mode, no need to use TraceFileWriter"); if (write(fd_, &header_, sizeof(header_)) != sizeof(header_)) { PROFILER_LOG_ERROR(LOG_CORE, "write initial header failed!, error: %s", strerror(errno)); } @@ -93,6 +94,7 @@ TraceFileWriter::TraceFileWriter(const std::string& path, bool splitFile, uint32 TraceFileWriter::~TraceFileWriter() { + CHECK_TRUE(fd_ != 0, NO_RETVAL, "only-nmd mode, no need to use TraceFileWriter"); (void)FlushStream(); if (stream_.is_open()) { stream_.close(); @@ -109,6 +111,7 @@ std::string TraceFileWriter::Path() const bool TraceFileWriter::SetPluginConfig(const void* data, size_t size) { + CHECK_TRUE(fd_ != 0, false, "SetPluginConfig, nmd mode no need to use TraceFileWriter"); if (isSplitFile_) { std::vector configVec; auto configData = reinterpret_cast(data); @@ -125,6 +128,7 @@ void TraceFileWriter::WriteStandalonePluginData( const std::string &pluginName, const std::string &data, const std::string &pluginVersion) { + CHECK_TRUE(fd_ != 0, NO_RETVAL, "WriteStandalonePluginData, nmd mode no need to use TraceFileWriter"); LITE::ProfilerPluginData pluginData; pluginData.set_name(pluginName); pluginData.set_data(data); @@ -150,6 +154,7 @@ void TraceFileWriter::WriteStandalonePluginData( void TraceFileWriter::SetTimeStamp() { + CHECK_TRUE(fd_ != 0, NO_RETVAL, "SetTimeStamp, nmd mode no need to use TraceFileWriter"); header_.data_.boottime = headerDataTime_.boottime; header_.data_.realtime = headerDataTime_.realtime; header_.data_.realtimeCoarse = headerDataTime_.realtimeCoarse; @@ -161,6 +166,7 @@ void TraceFileWriter::SetTimeStamp() void TraceFileWriter::SetTimeSource() { + CHECK_TRUE(fd_ != 0, NO_RETVAL, "SetTimeSource, nmd mode no need to use TraceFileWriter"); constexpr uint64_t nanoSeconds = 1000000000; struct timespec ts; clock_gettime(CLOCK_BOOTTIME, &ts); @@ -185,6 +191,7 @@ void TraceFileWriter::SetTimeSource() void TraceFileWriter::SetDurationTime() { + CHECK_TRUE(fd_ != 0, NO_RETVAL, "SetDurationTime, nmd mode no need to use TraceFileWriter"); struct timespec ts; clock_gettime(CLOCK_BOOTTIME, &ts); constexpr uint64_t nanoSeconds = 1000000000; @@ -194,6 +201,7 @@ void TraceFileWriter::SetDurationTime() bool TraceFileWriter::WriteHeader() { + CHECK_TRUE(fd_ != 0, false, "WriteHeader, nmd-only mode no need to use TraceFileWriter"); LogDiskUsage(); if (isSplitFile_) { std::string timeStr = COMMON::GetTimeStr(); @@ -237,6 +245,7 @@ void TraceFileWriter::DeleteOldSplitFile() long TraceFileWriter::Write(const void* data, size_t size) { + CHECK_TRUE(fd_ != 0, 0, "Write, nmd-only mode no need to use TraceFileWriter"); if (isSplitFile_ && !isStop_) { if (IsSplitFile(size)) { return -1; @@ -270,6 +279,7 @@ long TraceFileWriter::WriteStandalonePluginFile(const std::string &file, const std::string &version, DataType type) { + CHECK_TRUE(fd_ != 0, 0, "WriteStandalonePluginFile, no need to use TraceFileWriter"); CHECK_TRUE(stream_.is_open(), 0, "binary file %s not open or open failed!", path_.c_str()); auto retFile = COMMON::CheckNotExistsFilePath(file); if (!retFile.first) { @@ -326,6 +336,7 @@ long TraceFileWriter::WriteStandalonePluginFile(const std::string &file, bool TraceFileWriter::IsSplitFile(uint32_t size) { + CHECK_TRUE(fd_ != 0, false, "IsSplitFile, nmd-only mode no need to use TraceFileWriter"); dataSize_ += sizeof(uint32_t) + size; if (dataSize_ >= splitFileMaxSize_) { PROFILER_LOG_INFO(LOG_CORE, "need to split the file(%s), data size:%d, size: %d, splitFileMaxSize_:%d", @@ -357,6 +368,7 @@ bool TraceFileWriter::IsSplitFile(uint32_t size) long TraceFileWriter::Write(const MessageLite& message) { + CHECK_TRUE(fd_ != 0, 0, "Write, nmd-only mode no need to use TraceFileWriter"); auto size = message.ByteSizeLong(); if (isSplitFile_ && !isStop_) { if (IsSplitFile(size)) { @@ -373,6 +385,7 @@ long TraceFileWriter::Write(const MessageLite& message) bool TraceFileWriter::Finish() { + CHECK_TRUE(fd_ != 0, false, "Finish(), nmd-only mode no need to use TraceFileWriter"); // update header info helper_.Update(header_); SetTimeStamp(); // add timestamp in header @@ -408,6 +421,7 @@ bool TraceFileWriter::Finish() bool TraceFileWriter::Flush() { + CHECK_TRUE(fd_ != 0, false, "Finish(), nmd-only mode no need to use TraceFileWriter"); return FlushStream(); }