diff options
author | Ben Wiederhake <BenWiederhake.GitHub@gmx.de> | 2020-08-08 17:32:34 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-08-10 11:51:45 +0200 |
commit | f5744a6f2f63ba9f881132227514b9b3f9496b63 (patch) | |
tree | 0d8eb80d2df75f42ec76c3a8cad17d4aeaccea68 | |
parent | f22532118411c675e5bd1d2487331e27a872a981 (diff) | |
download | serenity-f5744a6f2f63ba9f881132227514b9b3f9496b63.zip |
Kernel: PID/TID typing
This compiles, and contains exactly the same bugs as before.
The regex 'FIXME: PID/' should reveal all markers that I left behind, including:
- Incomplete conversion
- Issues or things that look fishy
- Actual bugs that will go wrong during runtime
-rw-r--r-- | Kernel/FileSystem/ProcFS.cpp | 22 | ||||
-rw-r--r-- | Kernel/Net/Socket.cpp | 4 | ||||
-rw-r--r-- | Kernel/PerformanceEventBuffer.cpp | 4 | ||||
-rw-r--r-- | Kernel/PerformanceEventBuffer.h | 2 | ||||
-rw-r--r-- | Kernel/Process.cpp | 29 | ||||
-rw-r--r-- | Kernel/Process.h | 41 | ||||
-rw-r--r-- | Kernel/Profiling.cpp | 2 | ||||
-rw-r--r-- | Kernel/Ptrace.cpp | 2 | ||||
-rw-r--r-- | Kernel/Scheduler.cpp | 16 | ||||
-rw-r--r-- | Kernel/SharedBuffer.cpp | 8 | ||||
-rw-r--r-- | Kernel/SharedBuffer.h | 10 | ||||
-rw-r--r-- | Kernel/Syscalls/disown.cpp | 2 | ||||
-rw-r--r-- | Kernel/Syscalls/execve.cpp | 5 | ||||
-rw-r--r-- | Kernel/Syscalls/fork.cpp | 2 | ||||
-rw-r--r-- | Kernel/Syscalls/kill.cpp | 21 | ||||
-rw-r--r-- | Kernel/Syscalls/process.cpp | 4 | ||||
-rw-r--r-- | Kernel/Syscalls/ptrace.cpp | 5 | ||||
-rw-r--r-- | Kernel/Syscalls/setpgid.cpp | 12 | ||||
-rw-r--r-- | Kernel/Syscalls/shbuf.cpp | 2 | ||||
-rw-r--r-- | Kernel/Syscalls/thread.cpp | 4 | ||||
-rw-r--r-- | Kernel/Syscalls/waitid.cpp | 10 | ||||
-rw-r--r-- | Kernel/Thread.cpp | 10 | ||||
-rw-r--r-- | Kernel/Thread.h | 14 | ||||
-rw-r--r-- | Kernel/ThreadTracer.cpp | 2 | ||||
-rw-r--r-- | Kernel/ThreadTracer.h | 8 | ||||
-rw-r--r-- | Kernel/UnixTypes.h | 6 |
26 files changed, 136 insertions, 111 deletions
diff --git a/Kernel/FileSystem/ProcFS.cpp b/Kernel/FileSystem/ProcFS.cpp index 3fea02b45c..37da0d35a9 100644 --- a/Kernel/FileSystem/ProcFS.cpp +++ b/Kernel/FileSystem/ProcFS.cpp @@ -123,7 +123,7 @@ enum ProcFileType { FI_MaxStaticFileIndex, }; -static inline pid_t to_pid(const InodeIdentifier& identifier) +static inline ProcessID to_pid(const InodeIdentifier& identifier) { #ifdef PROCFS_DEBUG dbg() << "to_pid, index=" << String::format("%08x", identifier.index()) << " -> " << (identifier.index() >> 16); @@ -154,14 +154,14 @@ static inline size_t to_sys_index(const InodeIdentifier& identifier) return identifier.index() >> 16u; } -static inline InodeIdentifier to_identifier(unsigned fsid, ProcParentDirectory parent, pid_t pid, ProcFileType proc_file_type) +static inline InodeIdentifier to_identifier(unsigned fsid, ProcParentDirectory parent, ProcessID pid, ProcFileType proc_file_type) { - return { fsid, ((unsigned)parent << 12u) | ((unsigned)pid << 16u) | (unsigned)proc_file_type }; + return { fsid, ((unsigned)parent << 12u) | ((unsigned)pid.value() << 16u) | (unsigned)proc_file_type }; } -static inline InodeIdentifier to_identifier_with_fd(unsigned fsid, pid_t pid, int fd) +static inline InodeIdentifier to_identifier_with_fd(unsigned fsid, ProcessID pid, int fd) { - return { fsid, (PDI_PID_fd << 12u) | ((unsigned)pid << 16u) | (FI_MaxStaticFileIndex + fd) }; + return { fsid, (PDI_PID_fd << 12u) | ((unsigned)pid.value() << 16u) | (FI_MaxStaticFileIndex + fd) }; } static inline InodeIdentifier sys_var_to_identifier(unsigned fsid, unsigned index) @@ -663,7 +663,7 @@ Optional<KBuffer> procfs$pid_root(InodeIdentifier identifier) Optional<KBuffer> procfs$self(InodeIdentifier) { char buffer[16]; - sprintf(buffer, "%u", Process::current()->pid()); + sprintf(buffer, "%d", Process::current()->pid().value()); return KBuffer::copy((const u8*)buffer, strlen(buffer)); } @@ -821,13 +821,13 @@ Optional<KBuffer> procfs$all(InodeIdentifier) break; } - process_object.add("pid", process.pid()); + process_object.add("pid", process.pid().value()); process_object.add("pgid", process.tty() ? process.tty()->pgid() : 0); process_object.add("pgp", process.pgid()); process_object.add("sid", process.sid()); process_object.add("uid", process.uid()); process_object.add("gid", process.gid()); - process_object.add("ppid", process.ppid()); + process_object.add("ppid", process.ppid().value()); process_object.add("nfds", process.number_of_open_file_descriptors()); process_object.add("name", process.name()); process_object.add("tty", process.tty() ? process.tty()->tty_name() : "notty"); @@ -842,7 +842,7 @@ Optional<KBuffer> procfs$all(InodeIdentifier) auto thread_array = process_object.add_array("threads"); process.for_each_thread([&](const Thread& thread) { auto thread_object = thread_array.add_object(); - thread_object.add("tid", thread.tid()); + thread_object.add("tid", thread.tid().value()); thread_object.add("name", thread.name()); thread_object.add("times_scheduled", thread.times_scheduled()); thread_object.add("ticks", thread.ticks()); @@ -1227,7 +1227,7 @@ KResult ProcFSInode::traverse_as_directory(Function<bool(const FS::DirectoryEntr } for (auto pid_child : Process::all_pids()) { char name[16]; - size_t name_length = (size_t)sprintf(name, "%u", pid_child); + size_t name_length = (size_t)sprintf(name, "%d", pid_child.value()); callback({ name, name_length, to_identifier(fsid(), PDI_Root, pid_child, FI_PID), 0 }); } break; @@ -1270,7 +1270,7 @@ KResult ProcFSInode::traverse_as_directory(Function<bool(const FS::DirectoryEntr if (!description) continue; char name[16]; - size_t name_length = (size_t)sprintf(name, "%u", i); + size_t name_length = (size_t)sprintf(name, "%d", i); callback({ name, name_length, to_identifier_with_fd(fsid(), pid, i), 0 }); } } break; diff --git a/Kernel/Net/Socket.cpp b/Kernel/Net/Socket.cpp index a021b80658..9114b8eb4a 100644 --- a/Kernel/Net/Socket.cpp +++ b/Kernel/Net/Socket.cpp @@ -56,7 +56,7 @@ Socket::Socket(int domain, int type, int protocol) , m_protocol(protocol) { auto& process = *Process::current(); - m_origin = { process.pid(), process.uid(), process.gid() }; + m_origin = { process.pid().value(), process.uid(), process.gid() }; } Socket::~Socket() @@ -83,7 +83,7 @@ RefPtr<Socket> Socket::accept() auto client = m_pending.take_first(); ASSERT(!client->is_connected()); auto& process = *Process::current(); - client->m_acceptor = { process.pid(), process.uid(), process.gid() }; + client->m_acceptor = { process.pid().value(), process.uid(), process.gid() }; client->m_connected = true; client->m_role = Role::Accepted; return client; diff --git a/Kernel/PerformanceEventBuffer.cpp b/Kernel/PerformanceEventBuffer.cpp index d11c337087..5492f00eaf 100644 --- a/Kernel/PerformanceEventBuffer.cpp +++ b/Kernel/PerformanceEventBuffer.cpp @@ -94,12 +94,12 @@ PerformanceEvent& PerformanceEventBuffer::at(size_t index) return events[index]; } -KBuffer PerformanceEventBuffer::to_json(pid_t pid, const String& executable_path) const +KBuffer PerformanceEventBuffer::to_json(ProcessID pid, const String& executable_path) const { KBufferBuilder builder; JsonObjectSerializer object(builder); - object.add("pid", pid); + object.add("pid", pid.value()); object.add("executable", executable_path); auto array = object.add_array("events"); diff --git a/Kernel/PerformanceEventBuffer.h b/Kernel/PerformanceEventBuffer.h index f83d6f361b..6ad6b5eeb6 100644 --- a/Kernel/PerformanceEventBuffer.h +++ b/Kernel/PerformanceEventBuffer.h @@ -68,7 +68,7 @@ public: return const_cast<PerformanceEventBuffer&>(*this).at(index); } - KBuffer to_json(pid_t, const String& executable_path) const; + KBuffer to_json(ProcessID, const String& executable_path) const; private: PerformanceEvent& at(size_t index); diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 9cd084175a..e281bfc364 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -95,8 +95,12 @@ Lock* g_hostname_lock; VirtualAddress g_return_to_ring3_from_signal_trampoline; HashMap<String, OwnPtr<Module>>* g_modules; -pid_t Process::allocate_pid() +ProcessID Process::allocate_pid() { + // Overflow is UB, and negative PIDs wreck havoc. + // TODO: Handle PID overflow + // For example: Use an Atomic<u32>, mask the most significant bit, + // retry if PID is already taken as a PID, taken as a TID, or zero. return next_pid.fetch_add(1, AK::MemoryOrder::memory_order_acq_rel); } @@ -112,9 +116,9 @@ void Process::initialize() create_signal_trampolines(); } -Vector<pid_t> Process::all_pids() +Vector<ProcessID> Process::all_pids() { - Vector<pid_t> pids; + Vector<ProcessID> pids; ScopedSpinLock lock(g_processes_lock); pids.ensure_capacity((int)g_processes->size_slow()); for (auto& process : *g_processes) @@ -286,7 +290,7 @@ void Process::kill_all_threads() }); } -RefPtr<Process> Process::create_user_process(Thread*& first_thread, const String& path, uid_t uid, gid_t gid, pid_t parent_pid, int& error, Vector<String>&& arguments, Vector<String>&& environment, TTY* tty) +RefPtr<Process> Process::create_user_process(Thread*& first_thread, const String& path, uid_t uid, gid_t gid, ProcessID parent_pid, int& error, Vector<String>&& arguments, Vector<String>&& environment, TTY* tty) { auto parts = path.split('/'); if (arguments.is_empty()) { @@ -334,7 +338,7 @@ RefPtr<Process> Process::create_user_process(Thread*& first_thread, const String NonnullRefPtr<Process> Process::create_kernel_process(Thread*& first_thread, String&& name, void (*e)(), u32 affinity) { - auto process = adopt(*new Process(first_thread, move(name), (uid_t)0, (gid_t)0, (pid_t)0, Ring0)); + auto process = adopt(*new Process(first_thread, move(name), (uid_t)0, (gid_t)0, ProcessID(0), Ring0)); first_thread->tss().eip = (FlatPtr)e; if (process->pid() != 0) { @@ -348,7 +352,7 @@ NonnullRefPtr<Process> Process::create_kernel_process(Thread*& first_thread, Str return process; } -Process::Process(Thread*& first_thread, const String& name, uid_t uid, gid_t gid, pid_t ppid, RingLevel ring, RefPtr<Custody> cwd, RefPtr<Custody> executable, TTY* tty, Process* fork_parent) +Process::Process(Thread*& first_thread, const String& name, uid_t uid, gid_t gid, ProcessID ppid, RingLevel ring, RefPtr<Custody> cwd, RefPtr<Custody> executable, TTY* tty, Process* fork_parent) : m_name(move(name)) , m_pid(allocate_pid()) , m_euid(uid) @@ -473,10 +477,11 @@ void Process::crash(int signal, u32 eip, bool out_of_memory) ASSERT_NOT_REACHED(); } -RefPtr<Process> Process::from_pid(pid_t pid) +RefPtr<Process> Process::from_pid(ProcessID pid) { ScopedSpinLock lock(g_processes_lock); for (auto& process : *g_processes) { + process.pid(); if (process.pid() == pid) return &process; } @@ -553,7 +558,7 @@ siginfo_t Process::reap(Process& process) siginfo_t siginfo; memset(&siginfo, 0, sizeof(siginfo)); siginfo.si_signo = SIGCHLD; - siginfo.si_pid = process.pid(); + siginfo.si_pid = process.pid().value(); siginfo.si_uid = process.uid(); if (process.m_termination_signal) { @@ -566,7 +571,7 @@ siginfo_t Process::reap(Process& process) ASSERT(g_processes_lock.is_locked()); - if (process.ppid()) { + if (!!process.ppid()) { auto parent = Process::from_pid(process.ppid()); if (parent) { parent->m_ticks_in_user_for_dead_children += process.m_ticks_in_user + process.m_ticks_in_user_for_dead_children; @@ -654,7 +659,8 @@ void Process::finalize() disown_all_shared_buffers(); { InterruptDisabler disabler; - if (auto* parent_thread = Thread::from_tid(m_ppid)) { + // FIXME: PID/TID BUG + if (auto* parent_thread = Thread::from_tid(m_ppid.value())) { if (parent_thread->m_signal_action_data[SIGCHLD].flags & SA_NOCLDWAIT) { // NOTE: If the parent doesn't care about this process, let it go. m_ppid = 0; @@ -783,7 +789,8 @@ void Process::terminate_due_to_signal(u8 signal) KResult Process::send_signal(u8 signal, Process* sender) { InterruptDisabler disabler; - if (auto* thread = Thread::from_tid(m_pid)) { + // FIXME: PID/TID BUG + if (auto* thread = Thread::from_tid(m_pid.value())) { thread->send_signal(signal, sender); return KSuccess; } diff --git a/Kernel/Process.h b/Kernel/Process.h index 61ae6b41e4..d024e629ab 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -126,10 +126,10 @@ public: } static NonnullRefPtr<Process> create_kernel_process(Thread*& first_thread, String&& name, void (*entry)(), u32 affinity = THREAD_AFFINITY_DEFAULT); - static RefPtr<Process> create_user_process(Thread*& first_thread, const String& path, uid_t, gid_t, pid_t ppid, int& error, Vector<String>&& arguments = Vector<String>(), Vector<String>&& environment = Vector<String>(), TTY* = nullptr); + static RefPtr<Process> create_user_process(Thread*& first_thread, const String& path, uid_t, gid_t, ProcessID ppid, int& error, Vector<String>&& arguments = Vector<String>(), Vector<String>&& environment = Vector<String>(), TTY* = nullptr); ~Process(); - static Vector<pid_t> all_pids(); + static Vector<ProcessID> all_pids(); static AK::NonnullRefPtrVector<Process> all_processes(); Thread* create_kernel_thread(void (*entry)(), u32 priority, const String& name, u32 affinity = THREAD_AFFINITY_DEFAULT, bool joinable = true); @@ -152,10 +152,10 @@ public: PageDirectory& page_directory() { return *m_page_directory; } const PageDirectory& page_directory() const { return *m_page_directory; } - static RefPtr<Process> from_pid(pid_t); + static RefPtr<Process> from_pid(ProcessID); const String& name() const { return m_name; } - pid_t pid() const { return m_pid; } + ProcessID pid() const { return m_pid; } pid_t sid() const { return m_sid; } pid_t pgid() const { return m_pgid; } const FixedArray<gid_t>& extra_gids() const { return m_extra_gids; } @@ -165,9 +165,9 @@ public: gid_t gid() const { return m_gid; } uid_t suid() const { return m_suid; } gid_t sgid() const { return m_sgid; } - pid_t ppid() const { return m_ppid; } + ProcessID ppid() const { return m_ppid; } - pid_t exec_tid() const { return m_exec_tid; } + ThreadID exec_tid() const { return m_exec_tid; } mode_t umask() const { return m_umask; } @@ -224,7 +224,7 @@ public: int sys$fstat(int fd, stat*); int sys$stat(Userspace<const Syscall::SC_stat_params*>); int sys$lseek(int fd, off_t, int whence); - int sys$kill(pid_t pid, int sig); + int sys$kill(pid_t pid_or_pgid, int sig); [[noreturn]] void sys$exit(int status); int sys$sigreturn(RegisterState& registers); pid_t sys$waitid(Userspace<const Syscall::SC_waitid_params*>); @@ -263,7 +263,7 @@ public: int sys$getgroups(ssize_t, gid_t*); int sys$setgroups(ssize_t, const gid_t*); int sys$pipe(int pipefd[2], int flags); - int sys$killpg(int pgrp, int sig); + int sys$killpg(pid_t pgrp, int sig); int sys$seteuid(uid_t); int sys$setegid(gid_t); int sys$setuid(uid_t); @@ -338,7 +338,7 @@ public: int sys$sendfd(int sockfd, int fd); int sys$recvfd(int sockfd); long sys$sysconf(int name); - int sys$disown(pid_t); + int sys$disown(ProcessID); template<bool sockname, typename Params> int get_sock_or_peer_name(const Params&); @@ -574,8 +574,8 @@ private: friend class Scheduler; friend class Region; - Process(Thread*& first_thread, const String& name, uid_t, gid_t, pid_t ppid, RingLevel, RefPtr<Custody> cwd = nullptr, RefPtr<Custody> executable = nullptr, TTY* = nullptr, Process* fork_parent = nullptr); - static pid_t allocate_pid(); + Process(Thread*& first_thread, const String& name, uid_t, gid_t, ProcessID ppid, RingLevel, RefPtr<Custody> cwd = nullptr, RefPtr<Custody> executable = nullptr, TTY* = nullptr, Process* fork_parent = nullptr); + static ProcessID allocate_pid(); Range allocate_range(VirtualAddress, size_t, size_t alignment = PAGE_SIZE); @@ -607,7 +607,7 @@ private: } KResultOr<String> get_syscall_path_argument(const Syscall::StringArgument&) const; - bool has_tracee_thread(int tracer_pid) const; + bool has_tracee_thread(ProcessID tracer_pid) const; RefPtr<PageDirectory> m_page_directory; @@ -616,7 +616,7 @@ private: String m_name; - pid_t m_pid { 0 }; + ProcessID m_pid { 0 }; pid_t m_sid { 0 }; pid_t m_pgid { 0 }; @@ -627,7 +627,7 @@ private: uid_t m_suid { 0 }; gid_t m_sgid { 0 }; - pid_t m_exec_tid { 0 }; + ThreadID m_exec_tid { 0 }; FlatPtr m_load_offset { 0U }; FlatPtr m_entry_eip { 0U }; @@ -677,7 +677,7 @@ private: }; RegionLookupCache m_region_lookup_cache; - pid_t m_ppid { 0 }; + ProcessID m_ppid { 0 }; mode_t m_umask { 022 }; FixedArray<gid_t> m_extra_gids; @@ -732,11 +732,12 @@ template<typename Callback> inline void Process::for_each_child(Callback callback) { ASSERT_INTERRUPTS_DISABLED(); - pid_t my_pid = pid(); + ProcessID my_pid = pid(); ScopedSpinLock lock(g_processes_lock); for (auto* process = g_processes->head(); process;) { auto* next_process = process->next(); - if (process->ppid() == my_pid || process->has_tracee_thread(m_pid)) { + // FIXME: PID/TID BUG + if (process->ppid() == my_pid || process->has_tracee_thread(m_pid.value())) { if (callback(*process) == IterationDecision::Break) break; } @@ -748,7 +749,7 @@ template<typename Callback> inline void Process::for_each_thread(Callback callback) const { InterruptDisabler disabler; - pid_t my_pid = pid(); + ProcessID my_pid = pid(); if (my_pid == 0) { // NOTE: Special case the colonel process, since its main thread is not in the global thread table. @@ -800,14 +801,14 @@ inline bool InodeMetadata::may_execute(const Process& process) const return may_execute(process.euid(), process.egid(), process.extra_gids()); } -inline int Thread::pid() const +inline ProcessID Thread::pid() const { return m_process->pid(); } inline const LogStream& operator<<(const LogStream& stream, const Process& process) { - return stream << process.name() << '(' << process.pid() << ')'; + return stream << process.name() << '(' << process.pid().value() << ')'; } inline u32 Thread::effective_priority() const diff --git a/Kernel/Profiling.cpp b/Kernel/Profiling.cpp index f7e247f529..ca817afa19 100644 --- a/Kernel/Profiling.cpp +++ b/Kernel/Profiling.cpp @@ -61,7 +61,7 @@ void start(Process& process) executable_path() = process.executable()->absolute_path().impl(); else executable_path() = {}; - s_pid = process.pid(); + s_pid = process.pid().value(); // FIXME: PID/TID INCOMPLETE if (!s_profiling_buffer) { s_profiling_buffer = RefPtr<KBufferImpl>(KBuffer::create_with_size(8 * MB).impl()).leak_ref(); diff --git a/Kernel/Ptrace.cpp b/Kernel/Ptrace.cpp index d13c8a59d2..2e38b48c00 100644 --- a/Kernel/Ptrace.cpp +++ b/Kernel/Ptrace.cpp @@ -43,7 +43,7 @@ KResultOr<u32> handle_syscall(const Kernel::Syscall::SC_ptrace_params& params, P return KSuccess; } - if (params.pid == caller.pid()) + if (params.pid == caller.pid().value()) return KResult(-EINVAL); Thread* peer = nullptr; diff --git a/Kernel/Scheduler.cpp b/Kernel/Scheduler.cpp index 976a8f18ca..bf84598b7a 100644 --- a/Kernel/Scheduler.cpp +++ b/Kernel/Scheduler.cpp @@ -136,7 +136,7 @@ Thread::WriteBlocker::WriteBlocker(const FileDescription& description) timespec* Thread::WriteBlocker::override_timeout(timespec* timeout) { - auto& description = blocked_description(); + auto& description = blocked_description(); if (description.is_socket()) { auto& socket = *description.socket(); if (socket.has_send_timeout()) { @@ -227,7 +227,7 @@ bool Thread::SelectBlocker::should_unblock(Thread& thread) return false; } -Thread::WaitBlocker::WaitBlocker(int wait_options, pid_t& waitee_pid) +Thread::WaitBlocker::WaitBlocker(int wait_options, ProcessID& waitee_pid) : m_wait_options(wait_options) , m_waitee_pid(waitee_pid) { @@ -296,8 +296,7 @@ void Thread::consider_unblock(time_t now_sec, long now_usec) case Thread::Dying: /* don't know, don't care */ return; - case Thread::Blocked: - { + case Thread::Blocked: { ASSERT(m_blocker != nullptr); timespec now; now.tv_sec = now_sec, @@ -378,7 +377,7 @@ bool Scheduler::pick_next() auto name = process.name(); auto pid = process.pid(); auto exit_status = Process::reap(process); - dbg() << "Scheduler[" << Processor::current().id() << "]: Reaped unparented process " << name << "(" << pid << "), exit status: " << exit_status.si_status; + dbg() << "Scheduler[" << Processor::current().id() << "]: Reaped unparented process " << name << "(" << pid.value() << "), exit status: " << exit_status.si_status; } return IterationDecision::Continue; } @@ -496,7 +495,7 @@ bool Scheduler::yield() bool Scheduler::donate_to(Thread* beneficiary, const char* reason) { ASSERT(beneficiary); - + // Set the m_in_scheduler flag before acquiring the spinlock. This // prevents a recursive call into Scheduler::invoke_async upon // leaving the scheduler lock. @@ -685,8 +684,9 @@ void Scheduler::timer_tick(const RegisterState& regs) SmapDisabler disabler; auto backtrace = current_thread->raw_backtrace(regs.ebp, regs.eip); auto& sample = Profiling::next_sample_slot(); - sample.pid = current_thread->process().pid(); - sample.tid = current_thread->tid(); + // FIXME: PID/TID INCOMPLETE + sample.pid = current_thread->process().pid().value(); + sample.tid = current_thread->tid().value(); sample.timestamp = g_uptime; for (size_t i = 0; i < min(backtrace.size(), Profiling::max_stack_frame_count); ++i) { sample.frames[i] = backtrace[i]; diff --git a/Kernel/SharedBuffer.cpp b/Kernel/SharedBuffer.cpp index c87fb705c6..1989c892db 100644 --- a/Kernel/SharedBuffer.cpp +++ b/Kernel/SharedBuffer.cpp @@ -48,13 +48,13 @@ void SharedBuffer::sanity_check(const char* what) if (found_refs != m_total_refs) { dbg() << what << " sanity -- SharedBuffer{" << this << "} id: " << m_shbuf_id << " has total refs " << m_total_refs << " but we found " << found_refs; for (const auto& ref : m_refs) { - dbg() << " ref from pid " << ref.pid << ": refcnt " << ref.count; + dbg() << " ref from pid " << ref.pid.value() << ": refcnt " << ref.count; } ASSERT_NOT_REACHED(); } } -bool SharedBuffer::is_shared_with(pid_t peer_pid) const +bool SharedBuffer::is_shared_with(ProcessID peer_pid) const { LOCKER(shared_buffers().lock(), Lock::Mode::Shared); if (m_global) @@ -102,7 +102,7 @@ void* SharedBuffer::ref_for_process_and_get_address(Process& process) ASSERT_NOT_REACHED(); } -void SharedBuffer::share_with(pid_t peer_pid) +void SharedBuffer::share_with(ProcessID peer_pid) { LOCKER(shared_buffers().lock()); if (m_global) @@ -146,7 +146,7 @@ void SharedBuffer::deref_for_process(Process& process) ASSERT_NOT_REACHED(); } -void SharedBuffer::disown(pid_t pid) +void SharedBuffer::disown(ProcessID pid) { LOCKER(shared_buffers().lock()); for (size_t i = 0; i < m_refs.size(); ++i) { diff --git a/Kernel/SharedBuffer.h b/Kernel/SharedBuffer.h index b7fd269a77..f54a7ca7fe 100644 --- a/Kernel/SharedBuffer.h +++ b/Kernel/SharedBuffer.h @@ -36,12 +36,12 @@ namespace Kernel { class SharedBuffer { private: struct Reference { - Reference(pid_t pid) + Reference(ProcessID pid) : pid(pid) { } - pid_t pid; + ProcessID pid; unsigned count { 0 }; WeakPtr<Region> region; }; @@ -64,12 +64,12 @@ public: } void sanity_check(const char* what); - bool is_shared_with(pid_t peer_pid) const; + bool is_shared_with(ProcessID peer_pid) const; void* ref_for_process_and_get_address(Process& process); - void share_with(pid_t peer_pid); + void share_with(ProcessID peer_pid); void share_globally() { m_global = true; } void deref_for_process(Process& process); - void disown(pid_t pid); + void disown(ProcessID pid); size_t size() const { return m_vmobject->size(); } void destroy_if_unused(); void seal(); diff --git a/Kernel/Syscalls/disown.cpp b/Kernel/Syscalls/disown.cpp index f92c8f3b83..6c6368aecd 100644 --- a/Kernel/Syscalls/disown.cpp +++ b/Kernel/Syscalls/disown.cpp @@ -28,7 +28,7 @@ namespace Kernel { -int Process::sys$disown(pid_t pid) +int Process::sys$disown(ProcessID pid) { REQUIRE_PROMISE(proc); auto process = Process::from_pid(pid); diff --git a/Kernel/Syscalls/execve.cpp b/Kernel/Syscalls/execve.cpp index a74dd301e4..16ff3f231a 100644 --- a/Kernel/Syscalls/execve.cpp +++ b/Kernel/Syscalls/execve.cpp @@ -282,7 +282,8 @@ int Process::do_exec(NonnullRefPtr<FileDescription> main_program_description, Ve m_master_tls_size = master_tls_size; m_master_tls_alignment = master_tls_alignment; - m_pid = new_main_thread->tid(); + // FIXME: PID/TID BUG + m_pid = new_main_thread->tid().value(); new_main_thread->make_thread_specific_region({}); new_main_thread->reset_fpu_state(); @@ -296,7 +297,7 @@ int Process::do_exec(NonnullRefPtr<FileDescription> main_program_description, Ve tss.eip = m_entry_eip; tss.esp = new_userspace_esp; tss.cr3 = m_page_directory->cr3(); - tss.ss2 = m_pid; + tss.ss2 = m_pid.value(); if (was_profiling) Profiling::did_exec(path); diff --git a/Kernel/Syscalls/fork.cpp b/Kernel/Syscalls/fork.cpp index 43e4f76158..a66d772287 100644 --- a/Kernel/Syscalls/fork.cpp +++ b/Kernel/Syscalls/fork.cpp @@ -95,7 +95,7 @@ pid_t Process::sys$fork(RegisterState& regs) } child_first_thread->set_state(Thread::State::Skip1SchedulerPass); - return child->pid(); + return child->pid().value(); } } diff --git a/Kernel/Syscalls/kill.cpp b/Kernel/Syscalls/kill.cpp index 0b05c28e56..2ac7dd712f 100644 --- a/Kernel/Syscalls/kill.cpp +++ b/Kernel/Syscalls/kill.cpp @@ -35,7 +35,7 @@ KResult Process::do_kill(Process& process, int signal) if (!is_superuser() && m_euid != process.m_uid && m_uid != process.m_uid) return KResult(-EPERM); if (process.is_ring0() && signal == SIGKILL) { - klog() << "attempted to send SIGKILL to ring 0 process " << process.name().characters() << "(" << process.pid() << ")"; + klog() << "attempted to send SIGKILL to ring 0 process " << process.name().characters() << "(" << process.pid().value() << ")"; return KResult(-EPERM); } if (signal != 0) @@ -119,33 +119,34 @@ KResult Process::do_killself(int signal) return KSuccess; } -int Process::sys$kill(pid_t pid, int signal) +int Process::sys$kill(pid_t pid_or_pgid, int signal) { - if (pid == m_pid) + if (pid_or_pgid == m_pid.value()) REQUIRE_PROMISE(stdio); else REQUIRE_PROMISE(proc); if (signal < 0 || signal >= 32) return -EINVAL; - if (pid < -1) { - if (pid == NumericLimits<i32>::min()) + if (pid_or_pgid < -1) { + if (pid_or_pgid == NumericLimits<i32>::min()) return -EINVAL; - return do_killpg(-pid, signal); + return do_killpg(-pid_or_pgid, signal); } - if (pid == -1) + if (pid_or_pgid == -1) return do_killall(signal); - if (pid == m_pid) { + if (pid_or_pgid == m_pid.value()) { return do_killself(signal); } + ASSERT(pid_or_pgid >= 0); ScopedSpinLock lock(g_processes_lock); - auto peer = Process::from_pid(pid); + auto peer = Process::from_pid(pid_or_pgid); if (!peer) return -ESRCH; return do_kill(*peer, signal); } -int Process::sys$killpg(int pgrp, int signum) +int Process::sys$killpg(pid_t pgrp, int signum) { REQUIRE_PROMISE(proc); if (signum < 1 || signum >= 32) diff --git a/Kernel/Syscalls/process.cpp b/Kernel/Syscalls/process.cpp index c081756785..6a58ee3388 100644 --- a/Kernel/Syscalls/process.cpp +++ b/Kernel/Syscalls/process.cpp @@ -32,13 +32,13 @@ namespace Kernel { pid_t Process::sys$getpid() { REQUIRE_PROMISE(stdio); - return m_pid; + return m_pid.value(); } pid_t Process::sys$getppid() { REQUIRE_PROMISE(stdio); - return m_ppid; + return m_ppid.value(); } int Process::sys$set_process_icon(int icon_id) diff --git a/Kernel/Syscalls/ptrace.cpp b/Kernel/Syscalls/ptrace.cpp index 061d391be0..2f19df3056 100644 --- a/Kernel/Syscalls/ptrace.cpp +++ b/Kernel/Syscalls/ptrace.cpp @@ -44,7 +44,10 @@ int Process::sys$ptrace(Userspace<const Syscall::SC_ptrace_params*> user_params) return result.is_error() ? result.error() : result.value(); } -bool Process::has_tracee_thread(int tracer_pid) const +/** + * "Does this process have a thread that is currently being traced by the provided process?" + */ +bool Process::has_tracee_thread(ProcessID tracer_pid) const { bool has_tracee = false; diff --git a/Kernel/Syscalls/setpgid.cpp b/Kernel/Syscalls/setpgid.cpp index 9cfb32c200..5561131fbb 100644 --- a/Kernel/Syscalls/setpgid.cpp +++ b/Kernel/Syscalls/setpgid.cpp @@ -48,14 +48,15 @@ pid_t Process::sys$setsid() REQUIRE_PROMISE(proc); InterruptDisabler disabler; bool found_process_with_same_pgid_as_my_pid = false; - Process::for_each_in_pgrp(pid(), [&](auto&) { + // FIXME: PID/PGID ISSUE? + Process::for_each_in_pgrp(pid().value(), [&](auto&) { found_process_with_same_pgid_as_my_pid = true; return IterationDecision::Break; }); if (found_process_with_same_pgid_as_my_pid) return -EPERM; - m_sid = m_pid; - m_pgid = m_pid; + m_sid = m_pid.value(); + m_pgid = m_pid.value(); m_tty = nullptr; return m_sid; } @@ -91,7 +92,7 @@ int Process::sys$setpgid(pid_t specified_pid, pid_t specified_pgid) { REQUIRE_PROMISE(proc); ScopedSpinLock lock(g_processes_lock); // FIXME: Use a ProcessHandle - pid_t pid = specified_pid ? specified_pid : m_pid; + ProcessID pid = specified_pid ? ProcessID(specified_pid) : m_pid; if (specified_pgid < 0) { // The value of the pgid argument is less than 0, or is not a value supported by the implementation. return -EINVAL; @@ -115,7 +116,8 @@ int Process::sys$setpgid(pid_t specified_pid, pid_t specified_pgid) return -EPERM; } - pid_t new_pgid = specified_pgid ? specified_pgid : process->m_pid; + // FIXME: PID/PGID INCOMPLETE + pid_t new_pgid = specified_pgid ? specified_pgid : process->m_pid.value(); pid_t current_sid = get_sid_from_pgid(process->m_pgid); pid_t new_sid = get_sid_from_pgid(new_pgid); if (current_sid != new_sid) { diff --git a/Kernel/Syscalls/shbuf.cpp b/Kernel/Syscalls/shbuf.cpp index 8f9e7d8115..166569d40d 100644 --- a/Kernel/Syscalls/shbuf.cpp +++ b/Kernel/Syscalls/shbuf.cpp @@ -70,7 +70,7 @@ int Process::sys$shbuf_create(int size, void** buffer) int Process::sys$shbuf_allow_pid(int shbuf_id, pid_t peer_pid) { REQUIRE_PROMISE(shared_buffer); - if (!peer_pid || peer_pid < 0 || peer_pid == m_pid) + if (!peer_pid || peer_pid < 0 || ProcessID(peer_pid) == m_pid) return -EINVAL; LOCKER(shared_buffers().lock()); auto it = shared_buffers().resource().find(shbuf_id); diff --git a/Kernel/Syscalls/thread.cpp b/Kernel/Syscalls/thread.cpp index 572d67495d..1fe2d77192 100644 --- a/Kernel/Syscalls/thread.cpp +++ b/Kernel/Syscalls/thread.cpp @@ -87,7 +87,7 @@ int Process::sys$create_thread(void* (*entry)(void*), Userspace<const Syscall::S thread->make_thread_specific_region({}); thread->set_state(Thread::State::Runnable); - return thread->tid(); + return thread->tid().value(); } void Process::sys$exit_thread(void* exit_value) @@ -212,7 +212,7 @@ int Process::sys$get_thread_name(int tid, char* buffer, size_t buffer_size) int Process::sys$gettid() { REQUIRE_PROMISE(stdio); - return Thread::current()->tid(); + return Thread::current()->tid().value(); } } diff --git a/Kernel/Syscalls/waitid.cpp b/Kernel/Syscalls/waitid.cpp index 2650680b5f..1d4c69ca48 100644 --- a/Kernel/Syscalls/waitid.cpp +++ b/Kernel/Syscalls/waitid.cpp @@ -34,9 +34,12 @@ KResultOr<siginfo_t> Process::do_waitid(idtype_t idtype, int id, int options) ScopedSpinLock lock(g_processes_lock); if (idtype == P_PID && !Process::from_pid(id)) return KResult(-ECHILD); + // FIXME: Race: After 'lock' releases, the 'id' process might vanish. + // If that is not a problem, why check for it? + // If it is a problem, let's fix it! (Eventually.) } - pid_t waitee_pid; + ProcessID waitee_pid { 0 }; // FIXME: WaitBlocker should support idtype/id specs directly. if (idtype == P_ALL) { @@ -62,14 +65,15 @@ KResultOr<siginfo_t> Process::do_waitid(idtype_t idtype, int id, int options) if (waitee_process->is_dead()) { return reap(*waitee_process); } else { - auto* waitee_thread = Thread::from_tid(waitee_pid); + // FIXME: PID/TID BUG + auto* waitee_thread = Thread::from_tid(waitee_pid.value()); if (!waitee_thread) return KResult(-ECHILD); ASSERT((options & WNOHANG) || waitee_thread->state() == Thread::State::Stopped); siginfo_t siginfo; memset(&siginfo, 0, sizeof(siginfo)); siginfo.si_signo = SIGCHLD; - siginfo.si_pid = waitee_process->pid(); + siginfo.si_pid = waitee_process->pid().value(); siginfo.si_uid = waitee_process->uid(); switch (waitee_thread->state()) { diff --git a/Kernel/Thread.cpp b/Kernel/Thread.cpp index f5ebfac327..d04a4dcc1d 100644 --- a/Kernel/Thread.cpp +++ b/Kernel/Thread.cpp @@ -52,9 +52,10 @@ Thread::Thread(NonnullRefPtr<Process> process) { if (m_process->m_thread_count.fetch_add(1, AK::MemoryOrder::memory_order_acq_rel) == 0) { // First thread gets TID == PID - m_tid = m_process->pid(); + m_tid = m_process->pid().value(); } else { - m_tid = Process::allocate_pid(); + // TODO: Use separate counter? + m_tid = Process::allocate_pid().value(); } #ifdef THREAD_DEBUG dbg() << "Created new thread " << m_process->name() << "(" << m_process->pid() << ":" << m_tid << ")"; @@ -721,7 +722,6 @@ void Thread::set_state(State new_state) m_wait_queue->dequeue(*this); m_wait_queue = nullptr; } - if (this != Thread::current() && is_finalizable()) { // Some other thread set this thread to Dying, notify the @@ -859,7 +859,7 @@ void Thread::make_thread_specific_region(Badge<Process>) const LogStream& operator<<(const LogStream& stream, const Thread& value) { - return stream << value.process().name() << "(" << value.pid() << ":" << value.tid() << ")"; + return stream << value.process().name() << "(" << value.pid().value() << ":" << value.tid().value() << ")"; } Thread::BlockResult Thread::wait_on(WaitQueue& queue, const char* reason, timeval* timeout, Atomic<bool>* lock, Thread* beneficiary) @@ -982,7 +982,7 @@ void Thread::reset_fpu_state() memcpy(m_fpu_state, &Processor::current().clean_fpu_state(), sizeof(FPUState)); } -void Thread::start_tracing_from(pid_t tracer) +void Thread::start_tracing_from(ProcessID tracer) { m_tracer = ThreadTracer::create(tracer); } diff --git a/Kernel/Thread.h b/Kernel/Thread.h index d06ed100fd..d869eac70c 100644 --- a/Kernel/Thread.h +++ b/Kernel/Thread.h @@ -82,11 +82,11 @@ public: explicit Thread(NonnullRefPtr<Process>); ~Thread(); - static Thread* from_tid(int); + static Thread* from_tid(pid_t); static void finalize_dying_threads(); - int tid() const { return m_tid; } - int pid() const; + ThreadID tid() const { return m_tid; } + ProcessID pid() const; void set_priority(u32 p) { m_priority = p; } u32 priority() const { return m_priority; } @@ -236,13 +236,13 @@ public: class WaitBlocker final : public Blocker { public: - WaitBlocker(int wait_options, pid_t& waitee_pid); + WaitBlocker(int wait_options, ProcessID& waitee_pid); virtual bool should_unblock(Thread&) override; virtual const char* state_string() const override { return "Waiting"; } private: int m_wait_options { 0 }; - pid_t& m_waitee_pid; + ProcessID& m_waitee_pid; }; class SemiPermanentBlocker final : public Blocker { @@ -512,7 +512,7 @@ public: static constexpr u32 default_userspace_stack_size = 4 * MB; ThreadTracer* tracer() { return m_tracer.ptr(); } - void start_tracing_from(pid_t tracer); + void start_tracing_from(ProcessID tracer); void stop_tracing(); void tracer_trap(const RegisterState&); @@ -533,7 +533,7 @@ private: mutable RecursiveSpinLock m_lock; NonnullRefPtr<Process> m_process; - int m_tid { -1 }; + ThreadID m_tid { -1 }; TSS32 m_tss; Atomic<u32> m_cpu { 0 }; u32 m_cpu_affinity { THREAD_AFFINITY_DEFAULT }; diff --git a/Kernel/ThreadTracer.cpp b/Kernel/ThreadTracer.cpp index c58e354d0a..ded4a812f4 100644 --- a/Kernel/ThreadTracer.cpp +++ b/Kernel/ThreadTracer.cpp @@ -32,7 +32,7 @@ namespace Kernel { -ThreadTracer::ThreadTracer(pid_t tracer_pid) +ThreadTracer::ThreadTracer(ProcessID tracer_pid) : m_tracer_pid(tracer_pid) { } diff --git a/Kernel/ThreadTracer.h b/Kernel/ThreadTracer.h index 1ac492d868..63ae7303ae 100644 --- a/Kernel/ThreadTracer.h +++ b/Kernel/ThreadTracer.h @@ -35,9 +35,9 @@ namespace Kernel { class ThreadTracer { public: - static NonnullOwnPtr<ThreadTracer> create(pid_t tracer) { return make<ThreadTracer>(tracer); } + static NonnullOwnPtr<ThreadTracer> create(ProcessID tracer) { return make<ThreadTracer>(tracer); } - pid_t tracer_pid() const { return m_tracer_pid; } + ProcessID tracer_pid() const { return m_tracer_pid; } bool has_pending_signal(u32 signal) const { return m_pending_signals & (1 << (signal - 1)); } void set_signal(u32 signal) { m_pending_signals |= (1 << (signal - 1)); } void unset_signal(u32 signal) { m_pending_signals &= ~(1 << (signal - 1)); } @@ -54,10 +54,10 @@ public: return m_regs.value(); } - explicit ThreadTracer(pid_t); + explicit ThreadTracer(ProcessID); private: - pid_t m_tracer_pid { -1 }; + ProcessID m_tracer_pid { -1 }; // This is a bitmap for signals that are sent from the tracer to the tracee // TODO: Since we do not currently support sending signals diff --git a/Kernel/UnixTypes.h b/Kernel/UnixTypes.h index 19a9f742f4..9c2b568076 100644 --- a/Kernel/UnixTypes.h +++ b/Kernel/UnixTypes.h @@ -26,6 +26,7 @@ #pragma once +#include <AK/DistinctNumeric.h> #include <AK/Types.h> #define O_RDONLY (1 << 0) @@ -320,6 +321,11 @@ typedef u32 gid_t; typedef u32 clock_t; typedef u32 socklen_t; typedef int pid_t; +// Avoid interference with AK/Types.h and LibC/sys/types.h by defining *separate* names: +TYPEDEF_DISTINCT_ORDERED_ID(pid_t, ProcessID); +TYPEDEF_DISTINCT_ORDERED_ID(pid_t, ThreadID); +TYPEDEF_DISTINCT_ORDERED_ID(pid_t, SessionID); +TYPEDEF_DISTINCT_ORDERED_ID(pid_t, ProcessGroupID); struct tms { clock_t tms_utime; |