mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-21 12:05:15 +00:00
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.
This commit is contained in:
parent
875ab0cf10
commit
9058962712
Notes:
sideshowbarker
2024-07-19 10:55:50 +09:00
Author: https://github.com/ADKaster Commit: https://github.com/SerenityOS/serenity/commit/90589627122 Pull-request: https://github.com/SerenityOS/serenity/pull/857
6 changed files with 78 additions and 2 deletions
|
@ -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());
|
||||
|
|
|
@ -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;
|
||||
});
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 };
|
||||
|
|
Loading…
Add table
Reference in a new issue