mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 16:07:47 +00:00
Kernel+Profiler: Improve profiling subsystem
This turns the perfcore format into more a log than it was before, which lets us properly log process, thread and region creation/destruction. This also makes it unnecessary to dump the process' regions every time it is scheduled like we did before. Incidentally this also fixes 'profile -c' because we previously ended up incorrectly dumping the parent's region map into the profile data. Log-based mmap support enables profiling shared libraries which are loaded at runtime, e.g. via dlopen(). This enables profiling both the parent and child process for programs which use execve(). Previously we'd discard the profiling data for the old process. The Profiler tool has been updated to not treat thread IDs as process IDs anymore. This enables support for processes with more than one thread. Also, there's a new widget to filter which process should be displayed.
This commit is contained in:
parent
f57c57966b
commit
eb798d5538
26 changed files with 658 additions and 292 deletions
|
@ -23,25 +23,61 @@ struct [[gnu::packed]] FreePerformanceEvent {
|
|||
FlatPtr ptr;
|
||||
};
|
||||
|
||||
struct [[gnu::packed]] MmapPerformanceEvent {
|
||||
size_t size;
|
||||
FlatPtr ptr;
|
||||
char name[64];
|
||||
};
|
||||
|
||||
struct [[gnu::packed]] MunmapPerformanceEvent {
|
||||
size_t size;
|
||||
FlatPtr ptr;
|
||||
};
|
||||
|
||||
struct [[gnu::packed]] ProcessCreatePerformanceEvent {
|
||||
pid_t parent_pid;
|
||||
char executable[64];
|
||||
};
|
||||
|
||||
struct [[gnu::packed]] ProcessExecPerformanceEvent {
|
||||
char executable[64];
|
||||
};
|
||||
|
||||
struct [[gnu::packed]] ThreadCreatePerformanceEvent {
|
||||
pid_t parent_tid;
|
||||
};
|
||||
|
||||
struct [[gnu::packed]] PerformanceEvent {
|
||||
u8 type { 0 };
|
||||
u8 stack_size { 0 };
|
||||
u32 pid { 0 };
|
||||
u32 tid { 0 };
|
||||
u64 timestamp;
|
||||
union {
|
||||
MallocPerformanceEvent malloc;
|
||||
FreePerformanceEvent free;
|
||||
MmapPerformanceEvent mmap;
|
||||
MunmapPerformanceEvent munmap;
|
||||
ProcessCreatePerformanceEvent process_create;
|
||||
ProcessExecPerformanceEvent process_exec;
|
||||
ThreadCreatePerformanceEvent thread_create;
|
||||
} data;
|
||||
static constexpr size_t max_stack_frame_count = 64;
|
||||
FlatPtr stack[max_stack_frame_count];
|
||||
};
|
||||
|
||||
enum class ProcessEventType {
|
||||
Create,
|
||||
Exec
|
||||
};
|
||||
|
||||
class PerformanceEventBuffer {
|
||||
public:
|
||||
static OwnPtr<PerformanceEventBuffer> try_create_with_size(size_t buffer_size);
|
||||
|
||||
KResult append(int type, FlatPtr arg1, FlatPtr arg2);
|
||||
KResult append_with_eip_and_ebp(u32 eip, u32 ebp, int type, FlatPtr arg1, FlatPtr arg2);
|
||||
KResult append(int type, FlatPtr arg1, FlatPtr arg2, const StringView& arg3);
|
||||
KResult append_with_eip_and_ebp(ProcessID pid, ThreadID tid, u32 eip, u32 ebp,
|
||||
int type, FlatPtr arg1, FlatPtr arg2, const StringView& arg3);
|
||||
|
||||
void clear()
|
||||
{
|
||||
|
@ -57,23 +93,11 @@ public:
|
|||
|
||||
bool to_json(KBufferBuilder&) const;
|
||||
|
||||
void add_process(const Process&);
|
||||
void add_process(const Process&, ProcessEventType event_type);
|
||||
|
||||
private:
|
||||
explicit PerformanceEventBuffer(NonnullOwnPtr<KBuffer>);
|
||||
|
||||
struct SampledProcess {
|
||||
ProcessID pid;
|
||||
String executable;
|
||||
HashTable<ThreadID> threads;
|
||||
|
||||
struct Region {
|
||||
String name;
|
||||
Range range;
|
||||
};
|
||||
Vector<Region> regions;
|
||||
};
|
||||
|
||||
template<typename Serializer>
|
||||
bool to_json_impl(Serializer&) const;
|
||||
|
||||
|
@ -81,8 +105,9 @@ private:
|
|||
|
||||
size_t m_count { 0 };
|
||||
NonnullOwnPtr<KBuffer> m_buffer;
|
||||
|
||||
HashMap<ProcessID, NonnullOwnPtr<SampledProcess>> m_processes;
|
||||
};
|
||||
|
||||
extern bool g_profiling_all_threads;
|
||||
extern PerformanceEventBuffer* g_global_perf_events;
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue