diff --git a/DevTools/ProfileViewer/main.cpp b/DevTools/ProfileViewer/main.cpp index 6e88a0c04cc..92d0b4e6883 100644 --- a/DevTools/ProfileViewer/main.cpp +++ b/DevTools/ProfileViewer/main.cpp @@ -44,13 +44,7 @@ int main(int argc, char** argv) } const char* path = argv[1]; - OwnPtr profile; - - if (!strcmp(path, "perfcore")) { - profile = Profile::load_from_perfcore_file(path); - } else { - profile = Profile::load_from_file(path); - } + auto profile = Profile::load_from_perfcore_file(path); if (!profile) { fprintf(stderr, "Unable to load profile '%s'\n", path); diff --git a/Kernel/FileSystem/ProcFS.cpp b/Kernel/FileSystem/ProcFS.cpp index a13c63942c7..5cc71e654cf 100644 --- a/Kernel/FileSystem/ProcFS.cpp +++ b/Kernel/FileSystem/ProcFS.cpp @@ -398,29 +398,31 @@ Optional 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 1adc92f88c7..db322521a70 100644 --- a/Kernel/PerformanceEventBuffer.cpp +++ b/Kernel/PerformanceEventBuffer.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include diff --git a/Kernel/Profiling.cpp b/Kernel/Profiling.cpp index 23db4ffe963..90cc9fa2d28 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(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 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 d2539e7b621..d94c81ece0d 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();