ERESTART_RESTARTBLOCK and restart_syscall confusion - linux-kernel

It would appear from the source of nanosleep() in kernel/time/hrtimer.c and the manpage of restart_syscall() that to enable nanosleep() to be restarted with the correct timeout after a signal, it saves some state into current_thread_info()->restart_block, returns ERESTART_RESTARTBLOCK and that the signal delivery code would arrange for restart_syscall() to be called after the signal handler returns to do this. However:
There is only space in current_thread_info()->restart_block for one syscall, so what happens in case of recursive signals?
The ARM and x86 signal delivery code resets current_thread_info()->restart_block before a signal handler is called.
The ARM signal delivery code does not arrange for restart_syscall() to be called, instead it sets the return code to -EINTR.
Where is my mistake in the purpose or functioning of this code?

I've worked out that this it to allow a debugger attached using ptrace examine signals and alter the state of the process, and such syscalls return EINTR when interuppted by a signal handler.

Related

Detect when my Mac app is crashing, then go ahead and crash normally

Normally, when a Mac app gets a crashing signal such as SIGSEGV or SIGILL, the process stops and a few seconds later the OS somehow creates a crash report file and tells the user about it. But if I intercept the signal with a sigaction handler, that normal behavior does not happen. What I would like to do is detect when the crash is happening, do a little work using the few functions that are documented as safe to call in a signal handler, but then go ahead and crash in the normal way. Is there a way to do that? I tried re-raising the signal within the signal handler, but that didn't do the right thing.
I was able to get pretty much the behavior I wanted by ending the signal handler like so, re-sending the signal with default handling:
signal( inSignal, SIG_DFL );
pthread_kill( pthread_self(), inSignal );
usleep( 10000 ); /* give time for signal to happen */
Looking at Apple's source code for abort() help me figure this out.

Interrupt a kernel module when a user process terminates/receives a signal?

I am working on a kernel module where I need to be "aware" that a given process has crashed.
Right now my approach is to set up a periodic timer interrupt in the kernel module; on every timer interrupt, I check the task_struct.state and task_struct.exitstate values for that process.
I am wondering if there's a way to set up an interrupt in the kernel module that would go off when the process terminates, or, when the process receives a given signal (e.g., SIGINT or SIGHUP).
Thanks!
EDIT: A catch here is that I can't modify the user application. Or at least, it would be a much tougher sell to the customer if I place additional requirements/constraints on s/w from another vendor...
You could have your module create a character device node and then open that node from your userspace process. It's only about a dozen lines of boilerplate to register a simple cdev in your module. Your cdev's open method will get called when the process opens the device node and the release method will be called when the device node is closed. If a process exits, either intentionally or because of a signal, all open file descriptors are closed by the kernel. So you can be certain that release will be called. This avoids any need to poll the process status and you can avoid modifying any kernel code outside of your module.
You could also setup a watchdog style system, where your process must write one byte to the device every so often. Have the write method of the cdev reset a timer. If too much time passes without a write and the timer expires, it is assumed the process has somehow failed, even if it hasn't crashed and terminated. For instance a programming bug that allowed for a mutex deadlock or placed the process into an infinite loop.
There is a point in the kernel code where signals are delivered to user processes. You could patch that, check the process name, and signal a condition variable if it matches. This would just catch signals, not intentional process exits. IMHO, this is much uglier and you'll need to deal with maintaining a kernel patch. But it's not that hard, there's a single point, I don't recall what function, sorry, where one can insert the necessary code and it will catch all signals.

catch SIGKILL in MacOS driver

I'm currently debugging my daemon that supposedly die due to SIGKILL.
I'd like to catch that signal that is intended for my process and add a printout that this process got .
I'm aware that SIGKILL cannot be caught in process level signal handler, so I've decided to use kext.
I've looked in xnu source code and saw that psignal is the method that passes the signal to the target process. However, so I've tried to use trampoline to patch it, but this method is only calls another static method named psignal_internal that is static, and it's probably eliminated by compiler optimization.
perhaps there are other ways to get some sort of mechanism that may help catching this event of sigkill and maybe provide option to set a proper callback function in this case?
thanks

How does not disabling local interrupts in interrupt handler(which acquire lock) could lead to double-acquire deadlock?

In Linux Kernel Development book (Robert Love), It is mentioned that :
we must disable local interrupts before obtaining spinlock in
interrupt handler. Otherwise it is possible for an interrupt handler
to interrupt kernel code while the lock is held and attempt to
re-acquire the lock. Which finally can lead to double-acquire
deadlock.
Now my doubt is:
In general, doesn't do_IRQ() disables local interrupt ?
And if lock is acquire, it means thatpreempt_count variable is not zero, which makes that no other handler should get chance, as kernel is not preempt_safe. So how other interrupt handler can work in this situation ?
First, the do_IRQ() function dosn't disable the local interrupt, but some function written in assembly language does, which is the interrupt entrance. And later, before executing the interrupt function registering by request_irq(), in function handle_IRQ_event() a flag which also pass by request_irq() is compare with IRQF_DISABLED to determine whether we should enable the local interrupt when executing the interrupt function. So the answer to your question one is depending on the flags that you pass to the request_irq() function.
Second, preempt_count just means for kernel preemption in process context, but not for interrupt. To avoid interrupt handlers be executed in UP, the only way is involving the irqs_disable(). When the preempt_count is zero, it's said that the kernel can safely does the process switch, otherwise not.

What is the difference between interrupt and exception context?

Is there any major difference between the two? Is there anything that can be done in one and not the other? Do I need to take more care when modifying, for example, the page fault handler than a timer handler?
Interrupt is one of the classes of exception. There are four classes of exception: interrupt, trap, fault and abort. Interrupt occurs asynchronously and it is triggered by signal which is from I/O device that are external by processor. After exception handler finish handling this interrupt(exception processing), handler will always return to next instruction.
Interrupts and exceptions both alter the program flow. The
difference
between the two is that interrupts are used to handle
external events
(serial ports, keyboard) and exceptions are used to handle
instruction
faults, (division by zero, undefined opcode).
Interrupts are handled by the processor after finishing the
current
instruction. If it finds a signal on its interrupt pin, it
will look up
the address of the interrupt handler in the interrupt table
and pass
that routine control. After returning from the interrupt
handler
routine, it will resume program execution at the
instruction after the
interrupted instruction.
Exceptions on the other hand are divided into three kinds.
These are
Faults, Traps and Aborts. Faults are detected and serviced
by the
processor before the faulting instructions. Traps are
serviced after
the instruction causing the trap. User defined interrupts
go into this
category and can be said to be traps; this includes the MS-
DOS INT 21h
software interrupt, for example. Aborts are used only to
signal severe
system problems, when operation is no longer possible.
Research at: https://www.allinterview.com/showanswers/14289/distinguish-between-interrupts-and-exceptions.html

Resources