* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef HIPERF_VIRTUAL_THREAD_H
#define HIPERF_VIRTUAL_THREAD_H
#include <cinttypes>
#include <functional>
#include <unordered_set>
#include <unordered_map>
#include "debug_logger.h"
#include "dfx_maps.h"
#include "perf_event_record.h"
#include "symbols_file.h"
namespace OHOS {
namespace Developtools {
namespace HiPerf {
03284000-03289000 r--p 00000000 b3:05 289 /system/bin/sh
032b7000-032b9000 rw-p 00000000 00:00 0
aff60000-aff96000 r--p 00000000 b3:05 923 /system/lib/libc++.so
affeb000-affed000 rw-p 00000000 00:00 0
b0023000-b0024000 r--p 00000000 b3:05 959 /system/lib/libdl.so
*/
inline const std::string MMAP_NAME_HEAP = "[heap]";
inline const std::string MMAP_NAME_ANON = "[anon]";
class VirtualThread {
public:
VirtualThread(const VirtualThread &) = delete;
VirtualThread &operator=(const VirtualThread &) = delete;
VirtualThread(const pid_t pid, const std::vector<std::unique_ptr<SymbolsFile>> &symbolsFiles)
: pid_(pid),
tid_(pid),
symbolsFiles_(symbolsFiles),
processMemMaps_(),
memMaps_(processMemMaps_),
vaddr4kPageCache_(vaddr4kPageCacheOfProc_),
memMapsIndexs_(processMemMapsIndexs_),
parent_(*this),
isContainerProcess_(IsContainerProcess(pid)) {}
VirtualThread(const pid_t pid, const pid_t tid, VirtualThread &thread,
const std::vector<std::unique_ptr<SymbolsFile>> &symbolsFiles)
: pid_(pid),
tid_(tid),
symbolsFiles_(symbolsFiles),
processMemMaps_(),
memMaps_(thread.processMemMaps_),
vaddr4kPageCache_(thread.vaddr4kPageCacheOfProc_),
memMapsIndexs_(thread.processMemMapsIndexs_),
parent_(thread),
isContainerProcess_(thread.isContainerProcess_)
{
HLOG_ASSERT(pid != tid);
HLOGV("%d %d map from parent size is %zu", pid, tid, memMaps_.size());
};
pid_t pid_ = -1;
pid_t tid_ = -1;
std::string name_;
const std::vector<std::shared_ptr<DfxMap>> &GetMaps() const
{
return memMaps_;
}
void ParseMap();
void FixHMBundleMap();
void FixContainerMap();
void ParseServiceMap(const std::string &filename);
void ParseDevhostMap(const pid_t devhost);
std::shared_ptr<DfxMap> CreateMapItem(const std::string &filename, const uint64_t begin,
const uint64_t len, const uint64_t offset, const uint32_t prot = 0);
std::shared_ptr<DfxMap> FindMapByAddr(const uint64_t addr) const;
std::shared_ptr<DfxMap> FindMapByFileInfo(const std::string name, const uint64_t offset) const;
int64_t FindMapIndexByAddr(const uint64_t addr) const;
SymbolsFile *FindSymbolsFileByMap(std::shared_ptr<DfxMap> map) const;
bool ReadRoMemory(const uint64_t vaddr, uint8_t *data, const size_t size) const;
#ifdef HIPERF_DEBUG
void ReportVaddrMapMiss(const uint64_t vaddr) const;
#endif
private:
void SortMemMaps();
void ParseDevhostMapEachLine(std::string &filename, std::istringstream &iStringstream, std::string &line);
VirtualThread& GetParent()
{
return parent_;
}
#ifdef DEBUG_TIME
bool IsSorted() const;
#endif
const std::vector<std::unique_ptr<SymbolsFile>> &symbolsFiles_;
std::vector<std::shared_ptr<DfxMap>> processMemMaps_;
std::unordered_map<uint64_t, uint64_t> vaddr4kPageCacheOfProc_;
std::vector<std::shared_ptr<DfxMap>> &memMaps_;
std::unordered_map<uint64_t, uint64_t> &vaddr4kPageCache_;
std::vector<int> processMemMapsIndexs_;
std::vector<int> &memMapsIndexs_;
VirtualThread &parent_;
uint64_t adltLoadBase = static_cast<uint64_t>(-1);
bool getLoadBaseFlag = false;
bool isContainerProcess_ = false;
#ifdef HIPERF_DEBUG
mutable std::unordered_set<uint64_t> missedRuntimeVaddr_;
#endif
#ifdef DEBUG_MISS_SYMBOL
mutable std::vector<std::string> missedSymbolFile_;
#endif
};
}
}
}
#endif