mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 11:08:11 +00:00

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.
68 lines
1.5 KiB
C++
68 lines
1.5 KiB
C++
/*
|
|
* Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <AK/HashMap.h>
|
|
#include <AK/MappedFile.h>
|
|
#include <AK/OwnPtr.h>
|
|
#include <AK/Vector.h>
|
|
#include <LibELF/Image.h>
|
|
|
|
struct MappedObject {
|
|
NonnullRefPtr<MappedFile> file;
|
|
ELF::Image elf;
|
|
};
|
|
|
|
extern HashMap<String, OwnPtr<MappedObject>> g_mapped_object_cache;
|
|
|
|
class LibraryMetadata {
|
|
public:
|
|
struct Library {
|
|
FlatPtr base;
|
|
size_t size;
|
|
String name;
|
|
FlatPtr text_base;
|
|
MappedObject* object { nullptr };
|
|
|
|
String symbolicate(FlatPtr, u32* offset) const;
|
|
};
|
|
|
|
void handle_mmap(FlatPtr base, size_t size, const String& name);
|
|
const Library* library_containing(FlatPtr) const;
|
|
|
|
private:
|
|
mutable HashMap<String, OwnPtr<Library>> m_libraries;
|
|
};
|
|
|
|
struct Thread {
|
|
pid_t tid;
|
|
u64 start_valid;
|
|
u64 end_valid { 0 };
|
|
|
|
bool valid_at(u64 timestamp) const
|
|
{
|
|
return timestamp >= start_valid && (end_valid == 0 || timestamp <= end_valid);
|
|
}
|
|
};
|
|
|
|
struct Process {
|
|
pid_t pid {};
|
|
String executable;
|
|
HashMap<int, Vector<Thread>> threads {};
|
|
LibraryMetadata library_metadata {};
|
|
u64 start_valid;
|
|
u64 end_valid { 0 };
|
|
|
|
Thread* find_thread(pid_t tid, u64 timestamp);
|
|
void handle_thread_create(pid_t tid, u64 timestamp);
|
|
void handle_thread_exit(pid_t tid, u64 timestamp);
|
|
|
|
bool valid_at(u64 timestamp) const
|
|
{
|
|
return timestamp >= start_valid && (end_valid == 0 || timestamp <= end_valid);
|
|
}
|
|
};
|