Is killing a thread harmful?

Discussions on more advanced topics such as monolithic vs micro-kernels, transactional memory models, and paging vs segmentation should go here. Use this forum to expand and improve the wiki!
Post Reply
User avatar
AndrewAPrice
Member
Member
Posts: 2299
Joined: Mon Jun 05, 2006 11:00 pm
Location: USA (and Australia)

Is killing a thread harmful?

Post 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?
My OS is Perception.
Octocontrabass
Member
Member
Posts: 5512
Joined: Mon Mar 25, 2013 7:01 pm

Re: Is killing a thread harmful?

Post by Octocontrabass »

There's no guarantee a thread will release its locks or deallocate its memory even if you let it finish executing.
PeterX
Member
Member
Posts: 590
Joined: Fri Nov 22, 2019 5:46 am

Re: Is killing a thread harmful?

Post 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
User avatar
xenos
Member
Member
Posts: 1118
Joined: Thu Aug 11, 2005 11:00 pm
Libera.chat IRC: xenos1984
Location: Tartu, Estonia
Contact:

Re: Is killing a thread harmful?

Post 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.
Programmers' Hardware Database // GitHub user: xenos1984; OS project: NOS
Korona
Member
Member
Posts: 1000
Joined: Thu May 17, 2007 1:27 pm
Contact:

Re: Is killing a thread harmful?

Post 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.
managarm: Microkernel-based OS capable of running a Wayland desktop (Discord: https://discord.gg/7WB6Ur3). My OS-dev projects: [mlibc: Portable C library for managarm, qword, Linux, Sigma, ...] [LAI: AML interpreter] [xbstrap: Build system for OS distributions].
nexos
Member
Member
Posts: 1078
Joined: Tue Feb 18, 2020 3:29 pm
Libera.chat IRC: nexos

Re: Is killing a thread harmful?

Post 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.
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg
nullplan
Member
Member
Posts: 1766
Joined: Wed Aug 30, 2017 8:24 am

Re: Is killing a thread harmful?

Post 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?
Carpe diem!
User avatar
AndrewAPrice
Member
Member
Posts: 2299
Joined: Mon Jun 05, 2006 11:00 pm
Location: USA (and Australia)

Re: Is killing a thread harmful?

Post 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?
My OS is Perception.
Korona
Member
Member
Posts: 1000
Joined: Thu May 17, 2007 1:27 pm
Contact:

Re: Is killing a thread harmful?

Post 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.
managarm: Microkernel-based OS capable of running a Wayland desktop (Discord: https://discord.gg/7WB6Ur3). My OS-dev projects: [mlibc: Portable C library for managarm, qword, Linux, Sigma, ...] [LAI: AML interpreter] [xbstrap: Build system for OS distributions].
OSwhatever
Member
Member
Posts: 595
Joined: Mon Jul 05, 2010 4:15 pm

Re: Is killing a thread harmful?

Post 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.
Post Reply