1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2026-01-15 23:50:59 +00:00
serenity/Userland/DevTools/Profiler/Process.h
Daniel Bertalan ac1cac286b Profiler: Fix disassembling objects with a non-zero .text vaddr
Previously, we assumed that the `.text` segment was loaded at vaddr 0 in
shared object, which is not the case with `-z separate-code` enabled.
Because we didn't do the right calculations to translate an address from
a performance event into its value within the ELF file, Profiler would
try to disassemble out-of-bounds memory locations, leading to a crash.

This commit also changes `LibraryMetadata` to apply to a loaded library
as a whole, not just to one of its segments (like .text or .data). This
lets us simplify the interface, as we no longer have to worry about
`text_base`.

Fixes #10628
2021-10-25 12:14:26 +02:00

73 lines
1.7 KiB
C++

/*
* Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include "EventSerialNumber.h"
#include <AK/HashMap.h>
#include <AK/MappedFile.h>
#include <AK/OwnPtr.h>
#include <AK/Vector.h>
#include <LibELF/Image.h>
namespace Profiler {
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;
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, NonnullOwnPtr<Library>> m_libraries;
};
struct Thread {
pid_t tid;
EventSerialNumber start_valid;
EventSerialNumber end_valid;
bool valid_at(EventSerialNumber serial) const
{
return serial >= start_valid && (end_valid == EventSerialNumber {} || serial <= end_valid);
}
};
struct Process {
pid_t pid {};
String executable;
String basename;
HashMap<int, Vector<Thread>> threads {};
LibraryMetadata library_metadata {};
EventSerialNumber start_valid;
EventSerialNumber end_valid;
Thread* find_thread(pid_t tid, EventSerialNumber serial);
void handle_thread_create(pid_t tid, EventSerialNumber serial);
void handle_thread_exit(pid_t tid, EventSerialNumber serial);
bool valid_at(EventSerialNumber serial) const
{
return serial >= start_valid && (end_valid == EventSerialNumber {} || serial <= end_valid);
}
};
}