Repository: SerenityOS/serenity
File: Kernel/Tasks/Thread.cpp (C++)

Code before:
    if (previous_state == Thread::State::Runnable) {
        Scheduler::dequeue_runnable_thread(*this);
    } else if (previous_state == Thread::State::Stopped) {
        auto& process = this->process();
        if (process.set_stopped(false)) {
            process.for_each_thread([&](auto& thread) {
                if (&thread == this)
                    return;
                if (!thread.is_stopped())
                    return;
                dbgln_if(THREAD_DEBUG, "Resuming peer thread {}", thread);
                thread.resume_from_stopped();
            });
            process.unblock_waiters(Thread::WaitBlocker::UnblockFlags::Continued);
            // Tell the parent process (if any) about this change.
            if (auto parent = Process::from_pid_ignoring_process_lists(process.ppid())) {
                [[maybe_unused]] auto result = parent->send_signal(SIGCHLD, &process);
            }
        }
    }

    if (m_state == Thread::State::Runnable) {
        Scheduler::enqueue_runnable_thread(*this);
        Processor::smp_wake_n_idle_processors(1);
    } else if (m_state == Thread::State::Stopped) {
        if (previous_state != Thread::State::Running && previous_state != Thread::State::Runnable)
            PANIC("Attempting to stop with invalid thread state - {}", state_string(previous_state));

        auto& process = this->process();
        if (!process.set_stopped(true)) {
            // Note that we don't explicitly stop peer threads, we let them stop on their own the next time they
            // enter/exit a syscall, or once their current time slice runs out.
            process.unblock_waiters(Thread::WaitBlocker::UnblockFlags::Stopped, stop_signal);
            // Tell the parent process (if any) about this change.
            if (auto parent = Process::from_pid_ignoring_process_lists(process.ppid())) {
                [[maybe_unused]] auto result = parent->send_signal(SIGCHLD, &process);
            }
        }
    } else if (m_state == Thread::State::Dying) {
        VERIFY(previous_state != Thread::State::Blocked);
        if (this != Thread::current() && is_finalizable()) {
            // Some other thread set this thread to Dying, notify the
            // finalizer right away as it can be cleaned up now
            Scheduler::notify_finalizer();
        }
    }
}

struct RecognizedSymbol {
    FlatPtr address;
    KernelSymbol const* symbol { nullptr };

Review comment (suggestion):
I actually can't think of a way for this to be `Runnable` now. I kind of recall seeing that happen for some vaguely understandable reason, but I can't remember the details and couldn't get that to happen anymore. (so this now only accepts `Running`).

Code after:
                dbgln_if(THREAD_DEBUG, "Resuming peer thread {}", thread);
                thread.resume_from_stopped();
            });
            process.unblock_waiters(Thread::WaitBlocker::UnblockFlags::Continued);
            // Tell the parent process (if any) about this change.
            if (auto parent = Process::from_pid_ignoring_process_lists(process.ppid())) {
                [[maybe_unused]] auto result = parent->send_signal(SIGCHLD, &process);
            }
        }
    }

    if (m_state == Thread::State::Runnable) {
        Scheduler::enqueue_runnable_thread(*this);
        Processor::smp_wake_n_idle_processors(1);
    } else if (m_state == Thread::State::Stopped) {
        if (previous_state != Thread::State::Running)
            PANIC("Attempting to stop with invalid thread state - {}", state_string(previous_state));

        auto& process = this->process();
        if (!process.set_stopped(true)) {
            // Note that we don't explicitly stop peer threads, we let them stop on their own the next time they
            // enter/exit a syscall, or once their current time slice runs out.
            process.unblock_waiters(Thread::WaitBlocker::UnblockFlags::Stopped, stop_signal);
            // Tell the parent process (if any) about this change.
            if (auto parent = Process::from_pid_ignoring_process_lists(process.ppid())) {
                [[maybe_unused]] auto result = parent->send_signal(SIGCHLD, &process);
            }
        }
    } else if (m_state == Thread::State::Dying) {
        VERIFY(previous_state != Thread::State::Blocked);
        if (this != Thread::current() && is_finalizable()) {
            // Some other thread set this thread to Dying, notify the
            // finalizer right away as it can be cleaned up now
            Scheduler::notify_finalizer();
        }
    }
}

struct RecognizedSymbol {
    FlatPtr address;
    KernelSymbol const* symbol { nullptr };
};

static ErrorOr<bool> symbolicate(RecognizedSymbol const& symbol, Process& process, StringBuilder& builder)
{
    if (symbol.address == 0)
        return false;

    auto credentials = process.credentials();
    bool mask_kernel_addresses = !credentials->is_superuser();
    if (!symbol.symbol) {