Page 1 of 1

Is killing a thread harmful?

Posted: Fri May 22, 2020 7:51 am
by AndrewAPrice
In my opinion, yes.

It seems such a trivial function for a kernel to provide - unschedule a running thread and release its stack.

But, what if a thread was holding onto user space locks, or owned allocated memory?

Even a thread trying to kill itself at some arbitrary point would be dangerous because it doesn't walk up the stack and release required resources.

So, I've come to the conclusion that the only safe time you can kill a thread is when it finishes executing (reaches the end of the entry point function) and doesn't interrupt any in-progress code.

What are your thoughts?

Re: Is killing a thread harmful?

Posted: Fri May 22, 2020 8:02 am
by Octocontrabass
There's no guarantee a thread will release its locks or deallocate its memory even if you let it finish executing.

Re: Is killing a thread harmful?

Posted: Fri May 22, 2020 10:16 am
by PeterX
But I think on the other hand, sometimes it is crucial to stop a program fast. For example if you have made a mistake on the shell or in a script. Or if a tool does something harmful which you didn't expect.

Greetings
Peter

Re: Is killing a thread harmful?

Posted: Fri May 22, 2020 10:17 am
by xenos
My approach would be that resources (locks, memory) are not owned by threads (streams of execution, with a register state and user mode stack), but by processes (groups of threads, executable image, user space code and data). Killing a thread would not have any immediate consequence on resource allocation, since those are managed at the process level. If the last thread of a process finishes or gets killed, all resources owned by the process are freed.

Re: Is killing a thread harmful?

Posted: Sat May 23, 2020 12:28 am
by Korona
Resource allocation/deallocation on thread termination is not an issue for capability-based systems (as soon as there is one handle to a resource left, it stays alive).

Regarding deadlocks: there is no free lunch here. Sometimes you have to kill threads, e.g., due to OOM: let's be real, outside of very small and heavily constrained applications, there is no hope that all allocation failures can be handled gracefully.

Note that Linux has "robust locks" that can detect whether a lock holder died: http://man7.org/linux/man-pages/man2/ge ... ist.2.html.

Re: Is killing a thread harmful?

Posted: Sat May 23, 2020 6:47 am
by nexos
Big operating systems put protections in place to prevent it from being harmful. For example, all file descriptors and locks and heap memory should be stored in the thread control block. When terminating a thread, the kernel closes resources. Also note that the kernel may be forced to suddenly kill a thread (i.e., an exception). This one part of OSDev that is quite tricky. Side note, generally the heap is per process, not per thread.

Re: Is killing a thread harmful?

Posted: Sun May 24, 2020 10:17 pm
by nullplan
POSIX has thread cancellation for precisely that reason. Instead of just terminating a thread, it is sent a signal, and can then act on the signal by running various cleanup handlers (pthread_cleanup_push()/pthread_cleanup_pop()). Now, most software is not written to deal with this correctly, and the interactions between thread cancellation and C++ are undefined (glibc makes thread cancellation an asynchronous C++ exception, but this behavior is not guaranteed, and musl for example does not do this), and so destructors can be left unexecuted. But the functionality is there.
AndrewAPrice wrote:It seems such a trivial function for a kernel to provide - unschedule a running thread and release its stack.

But, what if a thread was holding onto user space locks, or owned allocated memory?
First of all, how does the kernel know where the stack of a thread is? In my OS, the thread stack is only given to the kernel as pointer to the top in the clone() system call. But the kernel doesn't know how long it is. Even if it did know at creation time, it cannot know how large it is later on when the thread finishes (someone might have enlarged it). Besides that, memory is not the only kind of resource a thread can obtain. Files and sockets are another big one.
Korona wrote:Resource allocation/deallocation on thread termination is not an issue for capability-based systems (as soon as there is one handle to a resource left, it stays alive).
And do you auto-close the resources when a thread is terminated? Then they are not sharable. But at the very least, you cannot do that for memory, because sharing memory is what threads are all about, and so dead memory will be left around after killing a thread.
PeterX wrote:But I think on the other hand, sometimes it is crucial to stop a program fast. For example if you have made a mistake on the shell or in a script. Or if a tool does something harmful which you didn't expect.
That is what killing a process is for. Killing a thread can leave a process in an unstable state, and the vast majority of programs is not written to cope. Killing a process just ends the entire thing, and then the resource collection on end of process can happen, and then a lot of the resources can get released. Not SysV shared memory, but then, whoever uses that has only themselves to blame, right?

Re: Is killing a thread harmful?

Posted: Mon May 25, 2020 9:21 am
by AndrewAPrice
My OS has a microkernel so the kernel itself doesn't know about file descriptors. The plan is for my VFS to say "this file descriptor is owned by process 1234" and tells the kernel "I'm interested in being alerted when process 1234 dies". This makes killing a process safe.

Threads are less safe, because they share memory and may want share other resources such as file descriptors, but I could imagine you could implement a resource system in user space, where you keep track of locked resources, and as long as you use the resource system's method to kill a thread, it could release all resources it tracks.

If you have to forcefully kill a thread, wouldn't this be a sign that all hope is lost for this process? If you wanted some kind of protection (e.g. your program wants to dynamically load plugins that may be faulty) it would be better for the plugins to run as their own processes?

Re: Is killing a thread harmful?

Posted: Mon May 25, 2020 9:48 am
by Korona
nullplan wrote:And do you auto-close the resources when a thread is terminated? Then they are not sharable. But at the very least, you cannot do that for memory, because sharing memory is what threads are all about, and so dead memory will be left around after killing a thread.
No, nothing is auto-closed. Threads own descriptors (e.g., a descriptor to their address space). Descriptors are also reference counted, so they are closed when the last thread closes them or terminates.

Re: Is killing a thread harmful?

Posted: Mon May 25, 2020 4:33 pm
by OSwhatever
AndrewAPrice wrote:In my opinion, yes.

It seems such a trivial function for a kernel to provide - unschedule a running thread and release its stack.

But, what if a thread was holding onto user space locks, or owned allocated memory?

Even a thread trying to kill itself at some arbitrary point would be dangerous because it doesn't walk up the stack and release required resources.

So, I've come to the conclusion that the only safe time you can kill a thread is when it finishes executing (reaches the end of the entry point function) and doesn't interrupt any in-progress code.

What are your thoughts?
Well, yes. There are many libraries out there that explicitly write in the documentation that the programmer is responsible for ending the threads in a orderly manner. That usually means that the thread function exits and the underlying library takes over. If the thread is in a lock or similar, one way to deal with this is to wake the thread and the lock implementation sees this and exits the thread.