diff options
author | Ali Mohammad Pur <ali.mpfard@gmail.com> | 2021-08-08 15:28:07 +0430 |
---|---|---|
committer | Ali Mohammad Pur <Ali.mpfard@gmail.com> | 2021-08-10 05:13:44 +0430 |
commit | 369e3da6a2ed81c217cc579ccc13a7952afcf87f (patch) | |
tree | 9bd989ab6d113da3048e98e9d7bb3370ee3b1f3f /Userland | |
parent | 2128ae4ab06c0e323f32c0d8490020732b89f3c0 (diff) | |
download | serenity-369e3da6a2ed81c217cc579ccc13a7952afcf87f.zip |
UserspaceEmulator: Move all the profiling details into the Emulator
Them being in the global namespace doesn't have a lot of fans, it seems.
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/DevTools/UserspaceEmulator/Emulator.cpp | 19 | ||||
-rw-r--r-- | Userland/DevTools/UserspaceEmulator/Emulator.h | 23 | ||||
-rw-r--r-- | Userland/DevTools/UserspaceEmulator/Emulator_syscalls.cpp | 18 | ||||
-rw-r--r-- | Userland/DevTools/UserspaceEmulator/main.cpp | 37 |
4 files changed, 55 insertions, 42 deletions
diff --git a/Userland/DevTools/UserspaceEmulator/Emulator.cpp b/Userland/DevTools/UserspaceEmulator/Emulator.cpp index 3be16183ed..255ddf2ded 100644 --- a/Userland/DevTools/UserspaceEmulator/Emulator.cpp +++ b/Userland/DevTools/UserspaceEmulator/Emulator.cpp @@ -27,11 +27,6 @@ # pragma GCC optimize("O3") #endif -extern bool g_dump_profile; -extern unsigned g_profile_instruction_interval; -extern Optional<OutputFileStream> g_profile_stream; -extern bool g_in_region_of_interest; - namespace UserspaceEmulator { static constexpr u32 stack_location = 0x10000000; @@ -224,9 +219,9 @@ int Emulator::exec() constexpr bool trace = false; - size_t instructions_until_next_profile_dump = g_profile_instruction_interval; - if (g_dump_profile && m_loader_text_size.has_value()) - emit_profile_event(*g_profile_stream, "mmap", String::formatted(R"("ptr": {}, "size": {}, "name": "/usr/lib/Loader.so")", *m_loader_text_base, *m_loader_text_size)); + size_t instructions_until_next_profile_dump = profile_instruction_interval(); + if (is_profiling() && m_loader_text_size.has_value()) + emit_profile_event(profile_stream(), "mmap", String::formatted(R"("ptr": {}, "size": {}, "name": "/usr/lib/Loader.so")", *m_loader_text_base, *m_loader_text_size)); while (!m_shutdown) { if (m_steps_til_pause) [[likely]] { @@ -239,10 +234,10 @@ int Emulator::exec() (m_cpu.*insn.handler())(insn); - if (g_dump_profile) { + if (is_profiling()) { if (instructions_until_next_profile_dump == 0) { - instructions_until_next_profile_dump = g_profile_instruction_interval; - emit_profile_sample(*g_profile_stream); + instructions_until_next_profile_dump = profile_instruction_interval(); + emit_profile_sample(profile_stream()); } else { --instructions_until_next_profile_dump; } @@ -474,7 +469,7 @@ void Emulator::dump_backtrace() void Emulator::emit_profile_sample(AK::OutputStream& output) { - if (!g_in_region_of_interest) + if (!is_in_region_of_interest()) return; StringBuilder builder; timeval tv {}; diff --git a/Userland/DevTools/UserspaceEmulator/Emulator.h b/Userland/DevTools/UserspaceEmulator/Emulator.h index 74662c91cf..c61f055899 100644 --- a/Userland/DevTools/UserspaceEmulator/Emulator.h +++ b/Userland/DevTools/UserspaceEmulator/Emulator.h @@ -12,6 +12,7 @@ #include "Report.h" #include "SoftCPU.h" #include "SoftMMU.h" +#include <AK/FileStream.h> #include <AK/MappedFile.h> #include <AK/Types.h> #include <LibDebug/DebugInfo.h> @@ -32,6 +33,23 @@ public: Emulator(String const& executable_path, Vector<String> const& arguments, Vector<String> const& environment); + void set_profiling_details(bool should_dump_profile, size_t instruction_interval, OutputFileStream* profile_stream) + { + m_is_profiling = should_dump_profile; + m_profile_instruction_interval = instruction_interval; + m_profile_stream = profile_stream; + } + + void set_in_region_of_interest(bool value) + { + m_is_in_region_of_interest = value; + } + + OutputFileStream& profile_stream() { return *m_profile_stream; } + bool is_profiling() const { return m_is_profiling; } + bool is_in_region_of_interest() const { return m_is_in_region_of_interest; } + size_t profile_instruction_interval() const { return m_profile_instruction_interval; } + bool load_elf(); void dump_backtrace(); void dump_backtrace(Vector<FlatPtr> const&); @@ -271,6 +289,11 @@ private: HashMap<String, CachedELF> m_dynamic_library_cache; RangeAllocator m_range_allocator; + + OutputFileStream* m_profile_stream { nullptr }; + bool m_is_profiling { false }; + size_t m_profile_instruction_interval { 0 }; + bool m_is_in_region_of_interest { false }; }; ALWAYS_INLINE bool Emulator::is_in_libc() const diff --git a/Userland/DevTools/UserspaceEmulator/Emulator_syscalls.cpp b/Userland/DevTools/UserspaceEmulator/Emulator_syscalls.cpp index e99082112d..9ccc4b99ac 100644 --- a/Userland/DevTools/UserspaceEmulator/Emulator_syscalls.cpp +++ b/Userland/DevTools/UserspaceEmulator/Emulator_syscalls.cpp @@ -28,10 +28,6 @@ # pragma GCC optimize("O3") #endif -extern bool g_dump_profile; -extern Optional<OutputFileStream> g_profile_stream; -extern bool g_in_region_of_interest; - namespace UserspaceEmulator { u32 Emulator::virt_syscall(u32 function, u32 arg1, u32 arg2, u32 arg3) @@ -817,8 +813,8 @@ static void round_to_page_size(FlatPtr& address, size_t& size) u32 Emulator::virt$munmap(FlatPtr address, size_t size) { - if (g_dump_profile) - emit_profile_event(*g_profile_stream, "munmap", String::formatted("\"ptr\": {}, \"size\": {}", address, size)); + if (is_profiling()) + emit_profile_event(profile_stream(), "munmap", String::formatted("\"ptr\": {}, \"size\": {}", address, size)); round_to_page_size(address, size); Vector<Region*, 4> marked_for_deletion; bool has_non_mmap_region = false; @@ -877,8 +873,8 @@ u32 Emulator::virt$mmap(u32 params_addr) name_str = { name.data(), name.size() }; } - if (g_dump_profile) - emit_profile_event(*g_profile_stream, "mmap", String::formatted(R"("ptr": {}, "size": {}, "name": "{}")", final_address, final_size, name_str)); + if (is_profiling()) + emit_profile_event(profile_stream(), "mmap", String::formatted(R"("ptr": {}, "size": {}, "name": "{}")", final_address, final_size, name_str)); if (params.flags & MAP_ANONYMOUS) { mmu().add_region(MmapRegion::create_anonymous(final_address, final_size, params.prot, move(name_str))); @@ -1135,12 +1131,12 @@ int Emulator::virt$emuctl(FlatPtr arg1, FlatPtr arg2, FlatPtr arg3) tracer->target_did_change_chunk_size({}, arg3, arg2); return 0; case 5: // mark ROI start - if (g_in_region_of_interest) + if (is_in_region_of_interest()) return -EINVAL; - g_in_region_of_interest = true; + m_is_in_region_of_interest = true; return 0; case 6: // mark ROI end - g_in_region_of_interest = false; + m_is_in_region_of_interest = false; return 0; default: return -EINVAL; diff --git a/Userland/DevTools/UserspaceEmulator/main.cpp b/Userland/DevTools/UserspaceEmulator/main.cpp index 38f348c8a7..f697cdafa0 100644 --- a/Userland/DevTools/UserspaceEmulator/main.cpp +++ b/Userland/DevTools/UserspaceEmulator/main.cpp @@ -18,10 +18,6 @@ #include <string.h> bool g_report_to_debug = false; -bool g_in_region_of_interest = true; -bool g_dump_profile = false; -unsigned g_profile_instruction_interval = 0; -Optional<OutputFileStream> g_profile_stream; int main(int argc, char** argv, char** env) { @@ -30,13 +26,15 @@ int main(int argc, char** argv, char** env) String profile_dump_path; FILE* profile_output_file { nullptr }; bool enable_roi_mode { false }; + bool dump_profile { false }; + unsigned profile_instruction_interval { 0 }; Core::ArgsParser parser; parser.set_stop_on_first_non_option(true); parser.add_option(g_report_to_debug, "Write reports to the debug log", "report-to-debug", 0); parser.add_option(pause_on_startup, "Pause on startup", "pause", 'p'); - parser.add_option(g_dump_profile, "Generate a ProfileViewer-compatible profile", "profile", 0); - parser.add_option(g_profile_instruction_interval, "Set the profile instruction capture interval, 128 by default", "profile-interval", 'i', "#instructions"); + parser.add_option(dump_profile, "Generate a ProfileViewer-compatible profile", "profile", 0); + parser.add_option(profile_instruction_interval, "Set the profile instruction capture interval, 128 by default", "profile-interval", 'i', "#instructions"); parser.add_option(profile_dump_path, "File path for profile dump", "profile-file", 0, "path"); parser.add_option(enable_roi_mode, "Enable Region-of-Interest mode for profiling", "roi", 0); @@ -44,11 +42,8 @@ int main(int argc, char** argv, char** env) parser.parse(argc, argv); - if (g_dump_profile && g_profile_instruction_interval == 0) - g_profile_instruction_interval = 128; - - if (enable_roi_mode) - g_in_region_of_interest = false; + if (dump_profile && profile_instruction_interval == 0) + profile_instruction_interval = 128; String executable_path; if (arguments[0].contains("/"sv)) @@ -60,22 +55,23 @@ int main(int argc, char** argv, char** env) return 1; } - if (g_dump_profile && profile_dump_path.is_empty()) + if (dump_profile && profile_dump_path.is_empty()) profile_dump_path = String::formatted("{}.{}.profile", executable_path, getpid()); - if (g_dump_profile) { + OwnPtr<OutputFileStream> profile_stream; + if (dump_profile) { profile_output_file = fopen(profile_dump_path.characters(), "w+"); if (profile_output_file == nullptr) { auto error_string = strerror(errno); warnln("Failed to open '{}' for writing: {}", profile_dump_path, error_string); return 1; } - g_profile_stream = OutputFileStream { profile_output_file }; + profile_stream = make<OutputFileStream>(profile_output_file); - g_profile_stream->write_or_error(R"({"events":[)"sv.bytes()); + profile_stream->write_or_error(R"({"events":[)"sv.bytes()); timeval tv {}; gettimeofday(&tv, nullptr); - g_profile_stream->write_or_error( + profile_stream->write_or_error( String::formatted( R"~({{"type": "process_create", "parent_pid": 1, "executable": "{}", "pid": {}, "tid": {}, "timestamp": {}, "lost_samples": 0, "stack": []}})~", executable_path, getpid(), gettid(), tv.tv_sec * 1000 + tv.tv_usec / 1000) @@ -89,6 +85,9 @@ int main(int argc, char** argv, char** env) // FIXME: It might be nice to tear down the emulator properly. auto& emulator = *new UserspaceEmulator::Emulator(executable_path, arguments, environment); + emulator.set_profiling_details(dump_profile, profile_instruction_interval, profile_stream); + emulator.set_in_region_of_interest(!enable_roi_mode); + if (!emulator.load_elf()) return 1; @@ -110,8 +109,8 @@ int main(int argc, char** argv, char** env) rc = emulator.exec(); - if (g_dump_profile) { - g_profile_stream->write_or_error(R"(]})"sv.bytes()); - } + if (dump_profile) + emulator.profile_stream().write_or_error(R"(]})"sv.bytes()); + return rc; } |