The communication between kernel helper thread and Kernel level code - linux

I'm studying Linux kernel and I'm wondering if I can do like below assuming a helper kernel thread already created.
A code was inserted in a sys_call(ex. in sys_execv()).
I would make the code in the sys_call send a signal to the kernel thread, and the code "shall wait or stop" until receive a completion event from the helper thread.
How the code can do this?
Thank you for your help in advance.
//DAUM

Signals are meant for user space processes. Although it is possible to allow certain signals (like SIGKILL) to a kernel thread but we cannot have signal handlers in kernel threads. So the signal based approach will not work.
It is better to explore other approaches based on work queues to achieve the same thing.

Related

How to detect if a linux thread is crashed

I've this problem, I need to understand if a Linux thread is running or not due to crash and not for normal exit. The reason to do that is try to restart the thread without reset\restart all system.
The pthread_join() seems not a good option because I've several thread to monitoring and the function return on specific thread, It doesn't work in "parallel". At moment I've a keeep live signal from thread to main but I'm looking for some system call or thread attribute to understand the state
Any suggestion?
P
Thread "crashes"
How to detect if a linux thread is crashed
if (0) //...
That is, the only way that a pthreads thread can terminate abnormally while other threads in the process continue to run is via thread cancellation,* which is not well described as a "crash". In particular, if a signal is received whose effect is abnormal termination then the whole process terminates, not just the thread that handled the signal. Other kinds of errors do not cause threads to terminate.
On the other hand, if by "crash" you mean normal termination in response to the thread detecting an error condition, then you have no limitation on what the thread can do prior to terminating to communicate about its state. For example,
it could update a shared object that tracks information about your threads
it could write to a pipe designated for the purpose
it could raise a signal
If you like, you can use pthread_cleanup_push() to register thread cleanup handlers to help with that.
On the third hand, if you're asking about detecting live threads that are failing to make progress -- because they are deadlocked, for example -- then your best bet is probably to implement some form of heartbeat monitor. That would involve each thread you want to monitor periodically updating a shared object that tracks the time of each thread's last update. If a thread goes too long between beats then you can guess that it may be stalled. This requires you to instrument all the threads you want to monitor.
Thread cancellation
You should not use thread cancellation. But if you did, and if you include termination because of cancellation in your definition of "crash", then you still have all the options above available to you, but you must engage them by registering one or more cleanup handlers.
GNU-specific options
The main issues with using pthread_join() to check thread state are
it doesn't work for daemon threads, and
pthread_join() blocks until the specified thread terminates.
For daemon threads, you need one of the approaches already discussed, but for ordinary threads on GNU/Linux, Glibc provides non-standard pthread_tryjoin_np(), which performs a non-blocking attempt to join a thread, and also pthread_timedjoin_np(), which performs a join attempt with a timeout. If you are willing to rely on Glibc-specific functions then one of these might serve your purpose.
Linux-specific options
The Linux kernel makes per-process thread status information available via the /proc filesystem. See How to check the state of Linux threads?, for example. Do be aware, however, that the details vary a bit from one kernel version to another. And if you're planning to do this a lot, then also be aware that even though /proc is a virtual filesystem (so no physical disk is involved), you still access it via slow-ish I/O interfaces.
Any of the other alternatives is probably better than reading files in /proc. I mention it only for completeness.
Overall
I'm looking for some system call or thread attribute to understand the state
The pthreads API does not provide a "have you terminated?" function or any other such state-inquiry function, unless you count pthread_join(). If you want that then you need to roll your own, which you can do by means of some of the facilities already discussed.
*Do not use thread cancellation.

Does the kernel or the thread execute a signal/interrupt handler?

I have read that the interrupts/signal handlers are handled in the kernel context. Does this mean that the kernel is executing the code in the signal handler? I find this hard to visualize and was hoping for some clarity regarding the same.

stopping an attached thread asynchrously using ptrace - linux

after attaching a pthread using its pid and manipulating the content of its debug registers, while waiting using waitpid(-1, &status, __WALL) ; I would like to be able to stop that thread and make additional manipulations (defining another breakpoint etc).
when I try sending a signal using kill() and waiting for the thread to be ready for additional ptrace requests, for just one target thread, it works fine. on the other hand, when the number of traced threads increase, i got stuck within waitpid() call and never get unblocked.
is there a safe and fast mechanism to stop an attached thread that is running for additional modifications?
cheers.
When sending a signal to a thread, do not use the pid. Sending a signal to a process (which is what you are doing) sends it to some random thread within that process, which is almost certainly not what you would like to do. The tool to send threads signals is ptrhread_kill.
That's where things become a little more hairy. The ptrace interface uses "thread ID" (or tid). These are framed in the same context as process IDs, i.e. - integers. pthread_kill, on the other hand, uses the pthread_t type, which is an opaque, and is not the same thing.
Since using ptrace means you are in dark magic land already, the simplest solution is to use tgkill. Just place your tid and pid in the relevant fields, and you're golden.
Of course, tgkill is not an exported function. You'll need to wrap it in syscall in order to invoke it.

When does OS check signals?

For simplicity,let's suppose it's on a single core architecture.
OS' main responsibility is to assign CPU time to different processes.
When does it check signals?
My bet is that it checks it when switching context(hang proc A and wait B) ,but I don't have any proof..
The answer, sadly, depends on the OS. On most, if not all, OS signals are event-driven entities. For example, in the case of a hardware interrupt, the hardware sends the signal to the interrupt handler, which then does its stuff, usually upon a context-switch (like you suggested).
It depends on the OS exactly, but in the case of a signal sent from a specific program, it usually happens when you context-switch a process to be executed. Signals are then checked. In the case of kill, the kill command is "tied" to the process, and the OS' interrupt handler takes care of it.
Operating systems have interrupt handlers that deal with that kind of thing. They periodically check, but it realy depends on the OS. In the specific case of kill PID (I use this example because you used it in an above comment), it will check the next time PID is scheduled for continued execution.
Short but unsatisfying answer: it depends on the signal and on the OS.
Hope this helps!
N.S.
Sources: I've programmed operating systems before, and I've taken multiple concurrency classes.
It doesn't poll for them if that's what you mean. When someone asks the kernel to send a signal, it interrupts the program to handle it.
Segfaults are triggered by hardware interrupts. The interrupt handler asks the kernel to pass the message along. Timeouts are similar.
It's all event-driven. Although some of the events quickly and simply leave messages around to be collected later for later - mouse movements etc. What happens next is very system-dependent but it's not a signal anymore.

How does a process come to know that it has received a signal

Please correct me if i am wrong. Here is my understanding about signals:
As far as i know, signal generation
and signal delivery are 2 different
things. In order to generate a signal,
the OS simply sets a bit in a bitarray
maintained in the Process Control
Block(PCB) of the process. Each bit
corresponds to a particular signal,
and when a bit is set, it means the
signal corresponding to the bit is
pending.
Delivery: Before transferring control
back to a process in user mode, the
Kernel always checks the pending
signals for this process. This check
must happen in Kernel space because
some signals can never be ignored by a
process – namely SIGSTOP and SIGKILL.
So does this mean that signals can only be delivered to a process when the kernel is scheduling that process i.e allocating it CPU ? Can a process get a signal when it is actually executing on the CPU ? If so, how is it possible i.e how the process comes to know that a signal is pending for it (since it is executing in User mode and cannot access the PCB)
Say there is multi processor machine and so there is real parallelism i.e multiple processes are executing at the same time. Process P1 is executing on cpu 1 and process P2 is executing on cpu2 and now process P2(having sufficient privileges) sends a signal to process P1. Will this signal be delivered to P1 right now or will it be delivered after P1 relinquishes the CPU for some reason and is again rescheduled at some later time by the Kernel and then this signal is delivered to process P1.
Please don't say this question is implementation dependent. If you find that the right answer is implementation defined then i am looking for answers in Linux, FreeBSD or any *nix platform for which you have knowledge of.
Thanks a lot for your help and patience :)
Regards
lali
The answer is implementation dependent :). On Mac OS X (and FreeBSD), signals are handled asynchronously - the kernel finds a thread which is not blocking the signal, and sets an Asynchronous System Trap flag on that thread. The next time the kernel schedules that thread, it handles the trap (quitting the process, ignoring the trap, or invoking the signal-handler in user space as appropriate) rather than arranging the usual continuation of the thread in user-space.
On Solaris, the implementation is somewhat similar, although it also offers synchronous signals based on hardware traps - synchronous signals are delivered to the thread that raised the trap, while asynchronous signals work in the way described above.
Linux does something similar to Solaris (I'm not sure how the conclusion in that reference follows from the discussion, but it's the discussion that is useful).
Posix.4 also defines real-time signals, but I haven't worked with those.
The short answer is - yes, process get knowledge of a signal only on the next scheduled CPU timeslice.
How to know the process has received a signal - it may call sigprocmask(2).
Process P1 is executing on cpu 1 and process P2 is executing on cpu2 and now process P2(having sufficient privileges) sends a signal to process P1. Will this signal be delivered to P1 right now or will it be delivered after P1 relinquishes the CPU for some reason and is again rescheduled at some later time by the Kernel and then this signal is delivered to process P1.
As far as i know on last linux kernels execution of P1 may be paused when P2 emit signal and signal will be delivered immediately. May be this true only for real-time signals
If I remember correctly, the interrupt arrival bit is checked during the last T state of an 8085 instruction. So there has to be a way to either generate a real interrupt on signal arrival, or there has to be a (constant?)code slice before the signal bit is checked.
Unfortunately, it appears that the only way to answer some kernel behaviour related questions is to go through the source code, because they are so "implementation dependent". Programming the computer really is nothing short of harassment - what a profession to choose!
Just try to be perfect, and hope this website helps.

Resources