1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 07:58:11 +00:00

Kernel+Profiler: Make profiling per-process and without core dumps

This patch merges the profiling functionality in the kernel with the
performance events mechanism. A profiler sample is now just another
perf event, rather than a dedicated thing.

Since perf events were already per-process, this now makes profiling
per-process as well.

Processes with perf events would already write out a perfcore.PID file
to the current directory on death, but since we may want to profile
a process and then let it continue running, recorded perf events can
now be accessed at any time via /proc/PID/perf_events.

This patch also adds information about process memory regions to the
perfcore JSON format. This removes the need to supply a core dump to
the Profiler app for symbolication, and so the "profiler coredump"
mechanism is removed entirely.

There's still a hard limit of 4MB worth of perf events per process,
so this is by no means a perfect final design, but it's a nice step
forward for both simplicity and stability.

Fixes #4848
Fixes #4849
This commit is contained in:
Andreas Kling 2021-01-11 09:52:18 +01:00
parent f259d96871
commit 5dafb72370
20 changed files with 195 additions and 310 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -50,7 +50,7 @@
#include <stdio.h>
#include <string.h>
static bool generate_profile(pid_t specified_pid);
static bool generate_profile(pid_t& pid);
int main(int argc, char** argv)
{
@ -62,11 +62,11 @@ int main(int argc, char** argv)
auto app = GUI::Application::construct(argc, argv);
auto app_icon = GUI::Icon::default_icon("app-profiler");
const char* path = nullptr;
String path;
if (argc != 2) {
if (!generate_profile(pid))
return 0;
path = "/proc/profile";
path = String::formatted("/proc/{}/perf_events", pid);
} else {
path = argv[1];
}
@ -182,7 +182,7 @@ static bool prompt_to_stop_profiling(pid_t pid, const String& process_name)
return GUI::Application::the()->exec() == 0;
}
bool generate_profile(pid_t pid)
bool generate_profile(pid_t& pid)
{
if (!pid) {
auto process_chooser = GUI::ProcessChooser::construct("Profiler", "Profile", Gfx::Bitmap::load_from_file("/res/icons/16x16/app-profiler.png"));