diff options
author | Andrew Kaster <andrewdkaster@gmail.com> | 2019-12-07 12:45:26 -0700 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-12-08 14:09:29 +0100 |
commit | 9058962712201336ec5e20638137d3828951950e (patch) | |
tree | 7cdd32c7d2e6c62fc9273fc6ac394eb1695b463e /Kernel | |
parent | 875ab0cf107894cf7311ea6d779cdae980e88627 (diff) | |
download | serenity-9058962712201336ec5e20638137d3828951950e.zip |
Kernel: Allow setting thread names
The main thread of each kernel/user process will take the name of
the process. Extra threads will get a fancy new name
"ProcessName[<tid>]".
Thread backtraces now list the thread name in addtion to tid.
Add the thread name to /proc/all (should it get its own proc
file?).
Add two new syscalls, set_thread_name and get_thread_name.
Diffstat (limited to 'Kernel')
-rw-r--r-- | Kernel/FileSystem/ProcFS.cpp | 1 | ||||
-rw-r--r-- | Kernel/Process.cpp | 68 | ||||
-rw-r--r-- | Kernel/Process.h | 2 | ||||
-rw-r--r-- | Kernel/Syscall.h | 4 | ||||
-rw-r--r-- | Kernel/Thread.cpp | 1 | ||||
-rw-r--r-- | Kernel/Thread.h | 4 |
6 files changed, 78 insertions, 2 deletions
diff --git a/Kernel/FileSystem/ProcFS.cpp b/Kernel/FileSystem/ProcFS.cpp index 2d8ac68288..768e8beade 100644 --- a/Kernel/FileSystem/ProcFS.cpp +++ b/Kernel/FileSystem/ProcFS.cpp @@ -721,6 +721,7 @@ Optional<KBuffer> procfs$all(InodeIdentifier) process.for_each_thread([&](const Thread& thread) { auto thread_object = thread_array.add_object(); thread_object.add("tid", thread.tid()); + thread_object.add("name", thread.name()); thread_object.add("times_scheduled", thread.times_scheduled()); thread_object.add("ticks", thread.ticks()); thread_object.add("state", thread.state_string()); diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index be12cef937..0fb8073832 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -542,6 +542,7 @@ int Process::do_exec(String path, Vector<String> arguments, Vector<String> envir Scheduler::prepare_to_modify_tss(main_thread()); m_name = parts.take_last(); + main_thread().set_name(m_name); // ss0 sp!!!!!!!!! u32 old_esp0 = main_thread().m_tss.esp0; @@ -2882,6 +2883,14 @@ int Process::sys$create_thread(void* (*entry)(void*), void* argument, const Sysc auto* thread = new Thread(*this); + // We know this thread is not the main_thread, + // So give it a unique name until the user calls $set_thread_name on it + // length + 4 to give space for our extra junk at the end + StringBuilder builder(m_name.length() + 4); + builder.append(m_name); + builder.appendf("[%d]", thread->tid()); + thread->set_name(builder.to_string()); + thread->set_priority(requested_thread_priority); thread->set_joinable(is_thread_joinable); @@ -2980,6 +2989,63 @@ int Process::sys$join_thread(int tid, void** exit_value) return 0; } +int Process::sys$set_thread_name(int tid, const char* buffer, int buffer_size) +{ + if (!validate_read(buffer, buffer_size)) + return -EFAULT; + + const size_t max_thread_name_size = 64; + if (strnlen(buffer, buffer_size) > max_thread_name_size) + return -EINVAL; + + Thread* thread = nullptr; + for_each_thread([&](auto& child_thread) { + if (child_thread.tid() == tid) { + thread = &child_thread; + return IterationDecision::Break; + } + return IterationDecision::Continue; + }); + + if (!thread) + return -ESRCH; + + // Forbid renaming the main thread of a process + // That guy should always be named after the process + if (thread == ¤t->process().main_thread()) + return -EINVAL; + + thread->set_name({buffer, buffer_size}); + + return 0; +} +int Process::sys$get_thread_name(int tid, char* buffer, int buffer_size) +{ + if (buffer_size <= 0) + return -EINVAL; + + if (!validate_write(buffer, buffer_size)) + return -EFAULT; + + Thread* thread = nullptr; + for_each_thread([&](auto& child_thread) { + if (child_thread.tid() == tid) { + thread = &child_thread; + return IterationDecision::Break; + } + return IterationDecision::Continue; + }); + + if (!thread) + return -ESRCH; + + if (thread->name().length() >= buffer_size) + return -ENAMETOOLONG; + + strncpy(buffer, thread->name().characters(), buffer_size); + return 0; +} + int Process::sys$gettid() { return current->tid(); @@ -3241,7 +3307,7 @@ KBuffer Process::backtrace(ProcessInspectionHandle& handle) const { KBufferBuilder builder; for_each_thread([&](Thread& thread) { - builder.appendf("Thread %d:\n", thread.tid()); + builder.appendf("Thread %d (%s):\n", thread.tid(), thread.name().characters()); builder.append(thread.backtrace(handle)); return IterationDecision::Continue; }); diff --git a/Kernel/Process.h b/Kernel/Process.h index bfa31ee58d..ee1c935c28 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -205,6 +205,8 @@ public: void sys$exit_thread(void*); int sys$join_thread(int tid, void** exit_value); int sys$detach_thread(int tid); + int sys$set_thread_name(int tid, const char* buffer, int buffer_size); + int sys$get_thread_name(int tid, char* buffer, int buffer_size); int sys$rename(const char* oldpath, const char* newpath); int sys$systrace(pid_t); int sys$mknod(const char* pathname, mode_t, dev_t); diff --git a/Kernel/Syscall.h b/Kernel/Syscall.h index dcafa120e2..aa70ab1699 100644 --- a/Kernel/Syscall.h +++ b/Kernel/Syscall.h @@ -142,7 +142,9 @@ typedef u32 socklen_t; __ENUMERATE_SYSCALL(join_thread) \ __ENUMERATE_SYSCALL(module_load) \ __ENUMERATE_SYSCALL(module_unload) \ - __ENUMERATE_SYSCALL(detach_thread) + __ENUMERATE_SYSCALL(detach_thread) \ + __ENUMERATE_SYSCALL(set_thread_name) \ + __ENUMERATE_SYSCALL(get_thread_name) namespace Syscall { diff --git a/Kernel/Thread.cpp b/Kernel/Thread.cpp index bdef8c15f4..dbf30bb9eb 100644 --- a/Kernel/Thread.cpp +++ b/Kernel/Thread.cpp @@ -44,6 +44,7 @@ HashTable<Thread*>& thread_table() Thread::Thread(Process& process) : m_process(process) , m_tid(process.m_next_tid++) + , m_name(process.name()) { dbgprintf("Thread{%p}: New thread TID=%u in %s(%u)\n", this, m_tid, process.name().characters(), process.pid()); set_default_signal_dispositions(); diff --git a/Kernel/Thread.h b/Kernel/Thread.h index a682a56c4b..afc7de0c0f 100644 --- a/Kernel/Thread.h +++ b/Kernel/Thread.h @@ -73,6 +73,9 @@ public: String backtrace(ProcessInspectionHandle&) const; + const String& name() const { return m_name; } + void set_name(StringView s) { m_name = s; } + void finalize(); enum State : u8 { @@ -463,6 +466,7 @@ private: FPUState* m_fpu_state { nullptr }; State m_state { Invalid }; + String m_name; ThreadPriority m_priority { ThreadPriority::Normal }; bool m_has_used_fpu { false }; bool m_dump_backtrace_on_finalization { false }; |