summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-02-22 10:05:03 +0100
committerAndreas Kling <kling@serenityos.org>2020-02-22 10:09:54 +0100
commit983b4bd9f244d8e31d8315e6f3c8e24a8210dbd9 (patch)
tree43f754b3d859f5d41878c78b9e260e2e343ab8e8 /Kernel
parent94652fd2fbf8cc79dc8446ea38b366c0464d6d98 (diff)
downloadserenity-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.cpp18
-rw-r--r--Kernel/PerformanceEventBuffer.cpp1
-rw-r--r--Kernel/Profiling.cpp62
-rw-r--r--Kernel/Profiling.h5
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();