diff options
author | Andreas Kling <kling@serenityos.org> | 2020-02-22 10:05:03 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-02-22 10:09:54 +0100 |
commit | 983b4bd9f244d8e31d8315e6f3c8e24a8210dbd9 (patch) | |
tree | 43f754b3d859f5d41878c78b9e260e2e343ab8e8 /Kernel | |
parent | 94652fd2fbf8cc79dc8446ea38b366c0464d6d98 (diff) | |
download | serenity-983b4bd9f244d8e31d8315e6f3c8e24a8210dbd9.zip |
Kernel+ProfileViewer: Move symbolication to userspace for time profiles
This makes the time profiles look like the memory profiles so we can
use the userspace symbolication code in ProfileViewer.
Diffstat (limited to 'Kernel')
-rw-r--r-- | Kernel/FileSystem/ProcFS.cpp | 18 | ||||
-rw-r--r-- | Kernel/PerformanceEventBuffer.cpp | 1 | ||||
-rw-r--r-- | Kernel/Profiling.cpp | 62 | ||||
-rw-r--r-- | Kernel/Profiling.h | 5 |
4 files changed, 31 insertions, 55 deletions
diff --git a/Kernel/FileSystem/ProcFS.cpp b/Kernel/FileSystem/ProcFS.cpp index a13c63942c..5cc71e654c 100644 --- a/Kernel/FileSystem/ProcFS.cpp +++ b/Kernel/FileSystem/ProcFS.cpp @@ -398,29 +398,31 @@ Optional<KBuffer> procfs$profile(InodeIdentifier) { InterruptDisabler disabler; KBufferBuilder builder; - JsonArraySerializer array(builder); + + JsonObjectSerializer object(builder); + object.add("pid", Profiling::pid()); + object.add("executable", Profiling::executable_path()); + + auto array = object.add_array("events"); bool mask_kernel_addresses = !Process::current->is_superuser(); Profiling::for_each_sample([&](auto& sample) { auto object = array.add_object(); - object.add("pid", sample.pid); + object.add("type", "sample"); object.add("tid", sample.tid); object.add("timestamp", sample.timestamp); - auto frames_array = object.add_array("frames"); + auto frames_array = object.add_array("stack"); for (size_t i = 0; i < Profiling::max_stack_frame_count; ++i) { if (sample.frames[i] == 0) break; - auto frame_object = frames_array.add_object(); u32 address = (u32)sample.frames[i]; if (mask_kernel_addresses && !is_user_address(VirtualAddress(address))) address = 0xdeadc0de; - frame_object.add("address", address); - frame_object.add("symbol", sample.symbolicated_frames[i]); - frame_object.add("offset", JsonValue((u32)sample.offsets[i])); - frame_object.finish(); + frames_array.add(address); } frames_array.finish(); }); array.finish(); + object.finish(); return builder.build(); } diff --git a/Kernel/PerformanceEventBuffer.cpp b/Kernel/PerformanceEventBuffer.cpp index 1adc92f88c..db322521a7 100644 --- a/Kernel/PerformanceEventBuffer.cpp +++ b/Kernel/PerformanceEventBuffer.cpp @@ -26,6 +26,7 @@ #include <AK/JsonArraySerializer.h> #include <AK/JsonObjectSerializer.h> +#include <AK/JsonObject.h> #include <Kernel/KBufferBuilder.h> #include <Kernel/PerformanceEventBuffer.h> diff --git a/Kernel/Profiling.cpp b/Kernel/Profiling.cpp index 23db4ffe96..90cc9fa2d2 100644 --- a/Kernel/Profiling.cpp +++ b/Kernel/Profiling.cpp @@ -41,11 +41,28 @@ static KBufferImpl* s_profiling_buffer; static size_t s_slot_count; static size_t s_next_slot_index; static Process* s_process; +static u32 s_pid; + +String& executable_path() +{ + static String* path; + if (!path) + path = new String; + return *path; +} + +u32 pid() +{ + return s_pid; +} void start(Process& process) { s_process = &process; + executable_path() = process.executable()->absolute_path().impl(); + s_pid = process.pid(); + if (!s_profiling_buffer) { s_profiling_buffer = RefPtr<KBufferImpl>(KBuffer::create_with_size(8 * MB).impl()).leak_ref(); s_profiling_buffer->region().commit(); @@ -68,53 +85,8 @@ Sample& next_sample_slot() return slot; } -static void symbolicate(Sample& stack) -{ - auto& process = *s_process; - ProcessPagingScope paging_scope(process); - struct RecognizedSymbol { - u32 address; - const KSym* ksym; - }; - Vector<RecognizedSymbol, max_stack_frame_count> recognized_symbols; - for (size_t i = 1; i < max_stack_frame_count; ++i) { - if (stack.frames[i] == 0) - break; - recognized_symbols.append({ stack.frames[i], ksymbolicate(stack.frames[i]) }); - } - - size_t i = 1; - for (auto& symbol : recognized_symbols) { - if (!symbol.address) - break; - 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 = process.elf_loader()->symbolicate(symbol.address, &offset_slot); - else - symbol_string_slot = String::empty(); - continue; - } - u32 offset = symbol.address - symbol.ksym->address; - if (symbol.ksym->address == ksym_highest_address && offset > 4096) { - symbol_string_slot = String::empty(); - offset_slot = 0; - } else { - symbol_string_slot = demangle(symbol.ksym->name); - offset_slot = offset; - } - } -} - void stop() { - for (size_t i = 0; i < s_next_slot_index; ++i) { - auto& stack = sample_slot(i); - symbolicate(stack); - } - s_process = nullptr; } diff --git a/Kernel/Profiling.h b/Kernel/Profiling.h index d2539e7b62..d94c81ece0 100644 --- a/Kernel/Profiling.h +++ b/Kernel/Profiling.h @@ -43,10 +43,11 @@ 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]; }; +extern u32 pid(); +extern String& executable_path(); + Sample& next_sample_slot(); void start(Process&); void stop(); |