Jelajahi Sumber

Kernel: Make sure we only log profiling events when m_profiling is true

Previously the process' m_profiling flag was ignored for all event
types other than CPU samples.

The kfree tracing code relies on temporarily disabling tracing during
exec. This didn't work for per-process profiles and would instead
panic.

This updates the profiling code so that the m_profiling flag isn't
ignored.
Gunnar Beutner 4 tahun lalu
induk
melakukan
0688e02339

+ 2 - 12
Kernel/PerformanceManager.h

@@ -54,18 +54,8 @@ public:
 
     inline static void add_cpu_sample_event(Thread& current_thread, const RegisterState& regs, u32 lost_time)
     {
-        PerformanceEventBuffer* perf_events = nullptr;
-
-        if (g_profiling_all_threads) {
-            VERIFY(g_global_perf_events);
-            perf_events = g_global_perf_events;
-        } else if (current_thread.process().is_profiling()) {
-            VERIFY(current_thread.process().perf_events());
-            perf_events = current_thread.process().perf_events();
-        }
-
-        if (perf_events) {
-            [[maybe_unused]] auto rc = perf_events->append_with_eip_and_ebp(
+        if (auto* event_buffer = current_thread.process().current_perf_events_buffer()) {
+            [[maybe_unused]] auto rc = event_buffer->append_with_eip_and_ebp(
                 current_thread.pid(), current_thread.tid(),
                 regs.eip, regs.ebp, PERF_EVENT_SAMPLE, lost_time, 0, 0, nullptr);
         }

+ 6 - 1
Kernel/Process.h

@@ -559,7 +559,12 @@ private:
 
     inline PerformanceEventBuffer* current_perf_events_buffer()
     {
-        return g_profiling_all_threads ? g_global_perf_events : m_perf_event_buffer.ptr();
+        if (g_profiling_all_threads)
+            return g_global_perf_events;
+        else if (m_profiling)
+            return m_perf_event_buffer.ptr();
+        else
+            return nullptr;
     }
 
     Process* m_prev { nullptr };

+ 5 - 1
Kernel/Syscalls/execve.cpp

@@ -506,6 +506,7 @@ KResult Process::do_exec(NonnullRefPtr<FileDescription> main_program_description
     Locker ptrace_locker(ptrace_lock());
 
     // Disable profiling temporarily in case it's running on this process.
+    auto was_profiling = m_profiling;
     TemporaryChange profiling_disabler(m_profiling, false);
 
     kill_threads_except_self();
@@ -645,7 +646,10 @@ KResult Process::do_exec(NonnullRefPtr<FileDescription> main_program_description
     tss.cr3 = space().page_directory().cr3();
     tss.ss2 = pid().value();
 
-    PerformanceManager::add_process_exec_event(*this);
+    {
+        TemporaryChange profiling_disabler(m_profiling, was_profiling);
+        PerformanceManager::add_process_exec_event(*this);
+    }
 
     {
         ScopedSpinLock lock(g_scheduler_lock);

+ 2 - 2
Kernel/Syscalls/profiling.cpp

@@ -51,12 +51,12 @@ KResultOr<int> Process::sys$profiling_enable(pid_t pid, u64 event_mask)
         return ESRCH;
     if (!is_superuser() && process->uid() != euid())
         return EPERM;
+    g_profiling_event_mask = event_mask;
+    process->set_profiling(true);
     if (!process->create_perf_events_buffer_if_needed())
         return ENOMEM;
     if (!TimeManagement::the().enable_profile_timer())
         return ENOTSUP;
-    g_profiling_event_mask = event_mask;
-    process->set_profiling(true);
     return 0;
 }