summaryrefslogtreecommitdiff
path: root/simpleperf/thread_tree.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'simpleperf/thread_tree.cpp')
-rw-r--r--simpleperf/thread_tree.cpp140
1 files changed, 35 insertions, 105 deletions
diff --git a/simpleperf/thread_tree.cpp b/simpleperf/thread_tree.cpp
index 28987222..6babf8cc 100644
--- a/simpleperf/thread_tree.cpp
+++ b/simpleperf/thread_tree.cpp
@@ -22,29 +22,17 @@
#include <android-base/logging.h>
#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
#include "perf_event.h"
#include "record.h"
-#include "record_file.h"
-#include "utils.h"
namespace simpleperf {
-namespace {
-
-// Real map file path depends on where the process can create files.
-// For example, app can create files only in its data directory.
-// Use normalized name inherited from pid instead.
-std::string GetSymbolMapDsoName(int pid) {
- return android::base::StringPrintf("perf-%d.map", pid);
-}
-
-} // namespace
void ThreadTree::SetThreadName(int pid, int tid, const std::string& comm) {
ThreadEntry* thread = FindThreadOrNew(pid, tid);
if (comm != thread->comm) {
- thread_comm_storage_.push_back(std::unique_ptr<std::string>(new std::string(comm)));
+ thread_comm_storage_.push_back(
+ std::unique_ptr<std::string>(new std::string(comm)));
thread->comm = thread_comm_storage_.back()->c_str();
}
}
@@ -66,7 +54,7 @@ void ThreadTree::ForkThread(int pid, int tid, int ppid, int ptid) {
}
}
-ThreadEntry* ThreadTree::FindThread(int tid) const {
+ThreadEntry* ThreadTree::FindThread(int tid) {
if (auto it = thread_tree_.find(tid); it != thread_tree_.end()) {
return it->second.get();
}
@@ -97,21 +85,12 @@ ThreadEntry* ThreadTree::CreateThread(int pid, int tid) {
maps = process->maps;
}
ThreadEntry* thread = new ThreadEntry{
- pid,
- tid,
- comm,
- maps,
+ pid, tid,
+ comm,
+ maps,
};
auto pair = thread_tree_.insert(std::make_pair(tid, std::unique_ptr<ThreadEntry>(thread)));
CHECK(pair.second);
- if (pid == tid) {
- // If there is a symbol map dso for the process, add maps for the symbols.
- auto name = GetSymbolMapDsoName(pid);
- auto it = user_dso_tree_.find(name);
- if (it != user_dso_tree_.end()) {
- AddThreadMapsForDsoSymbols(thread, it->second.get());
- }
- }
return thread;
}
@@ -128,69 +107,30 @@ void ThreadTree::AddKernelMap(uint64_t start_addr, uint64_t len, uint64_t pgoff,
if (len == 0) {
return;
}
- Dso* dso;
- if (android::base::StartsWith(filename, DEFAULT_KERNEL_MMAP_NAME)) {
- dso = FindKernelDsoOrNew();
- } else {
- dso = FindKernelModuleDsoOrNew(filename, start_addr, start_addr + len);
- }
+ Dso* dso = FindKernelDsoOrNew(filename);
InsertMap(kernel_maps_, MapEntry(start_addr, len, pgoff, dso, true));
}
-Dso* ThreadTree::FindKernelDsoOrNew() {
- if (!kernel_dso_) {
- kernel_dso_ = Dso::CreateDso(DSO_KERNEL, DEFAULT_KERNEL_MMAP_NAME);
+Dso* ThreadTree::FindKernelDsoOrNew(const std::string& filename) {
+ if (filename == DEFAULT_KERNEL_MMAP_NAME ||
+ filename == DEFAULT_KERNEL_MMAP_NAME_PERF) {
+ return kernel_dso_.get();
}
- return kernel_dso_.get();
-}
-
-Dso* ThreadTree::FindKernelModuleDsoOrNew(const std::string& filename, uint64_t memory_start,
- uint64_t memory_end) {
auto it = module_dso_tree_.find(filename);
if (it == module_dso_tree_.end()) {
- module_dso_tree_[filename] =
- Dso::CreateKernelModuleDso(filename, memory_start, memory_end, FindKernelDsoOrNew());
+ module_dso_tree_[filename] = Dso::CreateDso(DSO_KERNEL_MODULE, filename);
it = module_dso_tree_.find(filename);
}
return it->second.get();
}
-void ThreadTree::AddThreadMap(int pid, int tid, uint64_t start_addr, uint64_t len, uint64_t pgoff,
- const std::string& filename, uint32_t flags) {
+void ThreadTree::AddThreadMap(int pid, int tid, uint64_t start_addr, uint64_t len,
+ uint64_t pgoff, const std::string& filename, uint32_t flags) {
ThreadEntry* thread = FindThreadOrNew(pid, tid);
Dso* dso = FindUserDsoOrNew(filename, start_addr);
InsertMap(*thread->maps, MapEntry(start_addr, len, pgoff, dso, false, flags));
}
-void ThreadTree::AddThreadMapsForDsoSymbols(ThreadEntry* thread, Dso* dso) {
- const uint64_t page_size = GetPageSize();
-
- auto maps = thread->maps;
-
- uint64_t map_start = 0;
- uint64_t map_end = 0;
-
- // Dso symbols are sorted by address. Walk and calculate containing pages.
- for (const auto& sym : dso->GetSymbols()) {
- uint64_t sym_map_start = AlignDown(sym.addr, page_size);
- uint64_t sym_map_end = Align(sym.addr + sym.len, page_size);
-
- if (map_end < sym_map_start) {
- if (map_start < map_end) {
- InsertMap(*maps, MapEntry(map_start, map_end - map_start, map_start, dso, false, 0));
- }
- map_start = sym_map_start;
- }
- if (map_end < sym_map_end) {
- map_end = sym_map_end;
- }
- }
-
- if (map_start < map_end) {
- InsertMap(*maps, MapEntry(map_start, map_end - map_start, map_start, dso, false, 0));
- }
-}
-
Dso* ThreadTree::FindUserDsoOrNew(const std::string& filename, uint64_t start_addr,
DsoType dso_type) {
auto it = user_dso_tree_.find(filename);
@@ -204,16 +144,6 @@ Dso* ThreadTree::FindUserDsoOrNew(const std::string& filename, uint64_t start_ad
return it->second.get();
}
-void ThreadTree::AddSymbolsForProcess(int pid, std::vector<Symbol>* symbols) {
- auto name = GetSymbolMapDsoName(pid);
-
- auto dso = FindUserDsoOrNew(name, 0, DSO_SYMBOL_MAP_FILE);
- dso->SetSymbols(symbols);
-
- auto thread = FindThreadOrNew(pid, pid);
- AddThreadMapsForDsoSymbols(thread, dso);
-}
-
const MapEntry* ThreadTree::AllocateMap(const MapEntry& entry) {
map_storage_.emplace_back(new MapEntry(entry));
return map_storage_.back().get();
@@ -295,8 +225,8 @@ const MapEntry* ThreadTree::FindMap(const ThreadEntry* thread, uint64_t ip) {
return result != nullptr ? result : &unknown_map_;
}
-const Symbol* ThreadTree::FindSymbol(const MapEntry* map, uint64_t ip, uint64_t* pvaddr_in_file,
- Dso** pdso) {
+const Symbol* ThreadTree::FindSymbol(const MapEntry* map, uint64_t ip,
+ uint64_t* pvaddr_in_file, Dso** pdso) {
uint64_t vaddr_in_file = 0;
const Symbol* symbol = nullptr;
Dso* dso = map->dso;
@@ -310,15 +240,15 @@ const Symbol* ThreadTree::FindSymbol(const MapEntry* map, uint64_t ip, uint64_t*
// If the ip address hits the vmlinux, or hits a kernel module, but we can't find its symbol
// in the kernel module file, then find its symbol in /proc/kallsyms or vmlinux.
vaddr_in_file = ip;
- dso = FindKernelDsoOrNew();
+ dso = kernel_dso_.get();
symbol = dso->FindSymbol(vaddr_in_file);
}
if (symbol == nullptr) {
if (show_ip_for_unknown_symbol_) {
- std::string name = android::base::StringPrintf("%s%s[+%" PRIx64 "]",
- (show_mark_for_unknown_symbol_ ? "*" : ""),
- dso->FileName().c_str(), vaddr_in_file);
+ std::string name = android::base::StringPrintf(
+ "%s%s[+%" PRIx64 "]", (show_mark_for_unknown_symbol_ ? "*" : ""),
+ dso->FileName().c_str(), vaddr_in_file);
dso->AddUnknownSymbol(vaddr_in_file, name);
symbol = dso->FindSymbol(vaddr_in_file);
CHECK(symbol != nullptr);
@@ -347,19 +277,20 @@ void ThreadTree::ClearThreadAndMap() {
map_storage_.clear();
}
-void ThreadTree::AddDsoInfo(FileFeature& file) {
- DsoType dso_type = file.type;
+void ThreadTree::AddDsoInfo(const std::string& file_path, uint32_t file_type,
+ uint64_t min_vaddr, uint64_t file_offset_of_min_vaddr,
+ std::vector<Symbol>* symbols,
+ const std::vector<uint64_t>& dex_file_offsets) {
+ DsoType dso_type = static_cast<DsoType>(file_type);
Dso* dso = nullptr;
- if (dso_type == DSO_KERNEL) {
- dso = FindKernelDsoOrNew();
- } else if (dso_type == DSO_KERNEL_MODULE) {
- dso = FindKernelModuleDsoOrNew(file.path, 0, 0);
+ if (dso_type == DSO_KERNEL || dso_type == DSO_KERNEL_MODULE) {
+ dso = FindKernelDsoOrNew(file_path);
} else {
- dso = FindUserDsoOrNew(file.path, 0, dso_type);
+ dso = FindUserDsoOrNew(file_path, 0, dso_type);
}
- dso->SetMinExecutableVaddr(file.min_vaddr, file.file_offset_of_min_vaddr);
- dso->SetSymbols(&file.symbols);
- for (uint64_t offset : file.dex_file_offsets) {
+ dso->SetMinExecutableVaddr(min_vaddr, file_offset_of_min_vaddr);
+ dso->SetSymbols(symbols);
+ for (uint64_t offset : dex_file_offsets) {
dso->AddDexFileOffset(offset);
}
}
@@ -382,8 +313,9 @@ void ThreadTree::Update(const Record& record) {
if (r.InKernel()) {
AddKernelMap(r.data->addr, r.data->len, r.data->pgoff, r.filename);
} else {
- std::string filename =
- (r.filename == DEFAULT_EXECNAME_FOR_THREAD_MMAP) ? "[unknown]" : r.filename;
+ std::string filename = (r.filename == DEFAULT_EXECNAME_FOR_THREAD_MMAP)
+ ? "[unknown]"
+ : r.filename;
AddThreadMap(r.data->pid, r.data->tid, r.data->addr, r.data->len, r.data->pgoff, filename,
r.data->prot);
}
@@ -404,9 +336,7 @@ void ThreadTree::Update(const Record& record) {
std::vector<Dso*> ThreadTree::GetAllDsos() const {
std::vector<Dso*> result;
- if (kernel_dso_) {
- result.push_back(kernel_dso_.get());
- }
+ result.push_back(kernel_dso_.get());
for (auto& p : module_dso_tree_) {
result.push_back(p.second.get());
}