From 0f393148da8c462a142b60b68fd7fd1f024a1787 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Thu, 12 Dec 2019 21:59:47 +0100 Subject: [PATCH] Kernel: Separate out the symbol offsets in profile output Instead of saying "main +39" and "main +57" etc, we now have a separate field in /proc/profile for the offset-into-the-symbol. --- Kernel/FileSystem/ProcFS.cpp | 1 + Kernel/Profiling.cpp | 17 +++++++++++------ Kernel/Profiling.h | 1 + Libraries/LibELF/ELFLoader.cpp | 6 +++++- Libraries/LibELF/ELFLoader.h | 2 +- 5 files changed, 19 insertions(+), 8 deletions(-) diff --git a/Kernel/FileSystem/ProcFS.cpp b/Kernel/FileSystem/ProcFS.cpp index 3037985589..07598e419a 100644 --- a/Kernel/FileSystem/ProcFS.cpp +++ b/Kernel/FileSystem/ProcFS.cpp @@ -372,6 +372,7 @@ Optional procfs$profile(InodeIdentifier) auto frame_object = frames_array.add_object(); frame_object.add("address", JsonValue((u32)sample.frames[i])); frame_object.add("symbol", sample.symbolicated_frames[i]); + frame_object.add("offset", JsonValue((u32)sample.offsets[i])); frame_object.finish(); } frames_array.finish(); diff --git a/Kernel/Profiling.cpp b/Kernel/Profiling.cpp index 44834220fe..2a26162cdd 100644 --- a/Kernel/Profiling.cpp +++ b/Kernel/Profiling.cpp @@ -57,19 +57,24 @@ static void symbolicate(Sample& stack) for (auto& symbol : recognized_symbols) { if (!symbol.address) break; - auto& symbol_string_slot = stack.symbolicated_frames[i++]; + auto& symbol_string_slot = stack.symbolicated_frames[i]; + auto& offset_slot = stack.offsets[i]; + ++i; if (!symbol.ksym) { if (!Scheduler::is_active() && process.elf_loader() && process.elf_loader()->has_symbols()) - symbol_string_slot = String::format("%s", process.elf_loader()->symbolicate(symbol.address).characters()); + symbol_string_slot = process.elf_loader()->symbolicate(symbol.address, &offset_slot); else symbol_string_slot = String::empty(); continue; } - unsigned offset = symbol.address - symbol.ksym->address; - if (symbol.ksym->address == ksym_highest_address && offset > 4096) + u32 offset = symbol.address - symbol.ksym->address; + if (symbol.ksym->address == ksym_highest_address && offset > 4096) { symbol_string_slot = String::empty(); - else - symbol_string_slot = String::format("%s +%u", demangle(symbol.ksym->name).characters(), offset); + offset_slot = 0; + } else { + symbol_string_slot = demangle(symbol.ksym->name); + offset_slot = offset; + } } } diff --git a/Kernel/Profiling.h b/Kernel/Profiling.h index 54cb7a0cc8..ba0b684762 100644 --- a/Kernel/Profiling.h +++ b/Kernel/Profiling.h @@ -15,6 +15,7 @@ struct Sample { i32 tid; u64 timestamp; u32 frames[max_stack_frame_count]; + u32 offsets[max_stack_frame_count]; String symbolicated_frames[max_stack_frame_count]; }; diff --git a/Libraries/LibELF/ELFLoader.cpp b/Libraries/LibELF/ELFLoader.cpp index 8f50d08ff5..363590a377 100644 --- a/Libraries/LibELF/ELFLoader.cpp +++ b/Libraries/LibELF/ELFLoader.cpp @@ -102,7 +102,7 @@ char* ELFLoader::symbol_ptr(const char* name) return found_ptr; } -String ELFLoader::symbolicate(u32 address) const +String ELFLoader::symbolicate(u32 address, u32* out_offset) const { SortedSymbol* sorted_symbols = nullptr; #ifdef KERNEL @@ -139,6 +139,10 @@ String ELFLoader::symbolicate(u32 address) const if (i == 0) return "!!"; auto& symbol = sorted_symbols[i - 1]; + if (out_offset) { + *out_offset = address - symbol.address; + return demangle(symbol.name); + } return String::format("%s +%u", demangle(symbol.name).characters(), address - symbol.address); } } diff --git a/Libraries/LibELF/ELFLoader.h b/Libraries/LibELF/ELFLoader.h index ab607c10ad..6d80fd31b1 100644 --- a/Libraries/LibELF/ELFLoader.h +++ b/Libraries/LibELF/ELFLoader.h @@ -27,7 +27,7 @@ public: bool has_symbols() const { return m_image.symbol_count(); } - String symbolicate(u32 address) const; + String symbolicate(u32 address, u32* offset = nullptr) const; private: bool layout();