summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
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();