Building a Linux Debugger C - c

Trying to build a debugger in C for fuzzing.
Basically in linux, I just want to start a process via fork and then execve(), then monitor this process to see if it crashes after 1 second.
On linux, is this done via creating the process then monitoring the SIGNALs it generates for anything that looks like a crash? Or is it about monitoring the application and? I'm not sure.

Use the ptrace(2) system call:
While being traced, the child will stop each time a signal is
delivered, even if the signal is being ignored. (The exception is
SIGKILL, which has its usual effect.) The parent will be notified at
its next wait(2) and may inspect and modify the child process while it
is stopped. The parent then causes the child to continue, optionally
ignoring the delivered signal (or even delivering a different signal
instead).
The signals you should be interested in, regarding to the process having crashed are SIGSEGV (restricted memory access), SIGBUS (unaligned data access), SIGILL (illegal instruction), SIGFPE (illegal floating-point operation), etc.

Related

Re-propagate a Caught Signal in Linux

I am trying to use sigwait() for SIGSEGV and other signals and then do something (says writing the timestamp to a file). Then, I would like the program to behave as if the signal were never caught (e.g. a coredump is generated when SIGSEGV happens -- assuming the system is configured for coredump).
I read through couple manpages, and I don't see an obvious way to do so.
Any suggestion?
Thanks in advance!
You can register a signal handler that won't cause the program to crash. Once you receive the signal, you'll enter the signal handler, and after executing the signal handler (write to file you said), you'll reenter the program where you left off.
If you want a core dump, you can use the linux core(5) command and it will create a core dump in your signal handler without ending your process.
http://www.alexonlinux.com/signal-handling-in-linux#signal_masks
I believe you can not handle few signals the way you want to for example
SIGKILL
SIGSEGV
as manual itself states The signals SIGKILL and SIGSTOP cannot be caught or ignored
check below links
SIGNAL(7) and SIGNAL(2) These links should provide good enough details on signal handling in linux
You can however register a signal handler to handle few other signals
to list signals in operating system like linux you can use below command
kill -l
and as far as generating core dump is conserned its generated by operating system click here for more info
check the example code here

is SIGSEGV delivered to each thread?

I have a program in Linux which is multithreaded. There are certain memory areas in which I'm interested to see if they have been written within a certain time period. For that I give only read access to those memory pages and install a signal handler for SIGSEGV. Now my question is, will each thread call the signal handler for itself. Say Thread 1 writes to some forbidden memory area, will it be the one to execute the signal handler?
First of all
Signal dispositions are process-wide;
all threads in a process share the
same disposition for each signal. If
one thread uses sigaction() to
establish a handler for, say, SIGINT,
then that handler may be invoked from
any thread to which the SIGINT is
delivered.
But read on
A signal may be directed to either the
process as a whole or to a specific
thread. A signal is thread-directed if
it is generated as the direct result
of the execution of a specific
hardware instruction within the
context of the thread (SIGBUS, SIGFPE, SIGILL, and SIGSEGV)
I am quoting from TLPI.
No, per the question title.
To the question body: For the particular signal that you are asking for, yes (otherwise: it depends). The thread causing a segfault will receive the signal.
See signal(7):
A signal may be generated (and thus pending) for a process as a whole (e.g.,
when sent using kill(2)) or for a specific thread (e.g., certain signals, such
as SIGSEGV and SIGFPE, generated as a consequence of executing a specific
machine-language instruction are thread directed [...].

Ctrl + C: does it kill threads too along with main process?

While running a thread program and repeatedly killing the main program using Ctrl + C, i see unexpected results in the program in second run. However, if i let the program run and voluntarily exit, there are no issues.
So, my doubt is, does Ctrl + C, kill threads also along with the main process?
Thanks in advance.
In multithreaded programming, signals are delivered to a single thread (usually chosen unpredictably among the threads that don't have that particular signal blocked). However, this does not mean that a signal whose default action is to kill the process only terminates one thread. In fact, there is no way to kill a single thread without killing the whole process.
As long as you leave SIGINT with its default action of terminating the process, it will do so as long as at least one thread leaves SIGINT unblocked. It doesn't matter which thread has it unblocked as long as at least one does, so library code creating threads behind the application's back should always block all signals before calling pthread_create and restore the signal mask in the calling thread afterwards.
Well, the only thing that Ctrl + C does is sending SIGINT to one thread in the process that is not masking the signal. Signals can be handled or ignored.
If the program does handle Ctrl+C, the usual behavior is self-termination, but once again, it could be used for anything else.
In your case, SIGINT is being received by one thread, which probably does kill itself, but does not kill the others.
Under Linux 2.6 using NPTL threads: I am assuming that the process uses the default signal handler, or calls exit() in it: Yes it does. The C library exit() call maps to the exit_group system call which exits all the threads immediately; the default signal handler calls this or something similar.
Under Linux 2.4 using Linuxthreads (or using 2.6 if your app still uses Linuxthreads for some weird reason): Not necessarily.
The Linuxthreads library implements threads using clone(), creating a new process which happens to share its address-space with the parent. This does not necessarily die when the parent dies. To fix this, there is a "master thread" which pthreads creates. This master thread does various things, one of them is to try to ensure that all the threads get killed when the process exits (for whatever reason).
It does not necessarily succeed
If it does succeed, it is not necessarily immediate, particularly if there are a large number of threads.
So if you're using Linuxthreads, possibly not.
The other threads might not exit immediately, or indeed at all.
However, no matter what thread library you use, forked child processes will continue (they might receive the signal if they are still in the same process-group, but can freely ignore it)

How do unix signals work?

How do signals work in unix? I went through W.R. Stevens but was unable to understand. Please help me.
The explanation below is not exact, and several aspects of how this works differ between different systems (and maybe even the same OS on different hardware for some portions), but I think that it is generally good enough for you to satisfy your curiosity enough to use them. Most people start using signals in programming without even this level of understanding, but before I got comfortable using them I wanted to understand them.
signal delivery
The OS kernel has a data structure called a process control block for each process running which has data about that process. This can be looked up by the process id (PID) and included a table of signal actions and pending signals.
When a signal is sent to a process the OS kernel will look up that process's process control block and examines the signal action table to locate the action for the particular signal being sent. If the signal action value is SIG_IGN then the new signal is forgotten about by the kernel. If the signal action value is SIG_DFL then the kernel looks up the default signal handling action for that signal in another table and preforms that action. If the values are anything else then that is assumed to be a function address within the process that the signal is being sent to which should be called. The values for SIG_IGN and SIG_DFL are numbers cast to function pointers whose values are not valid addresses within a process's address space (such as 0 and 1, which are both in page 0, which is never mapped into a process).
If a signal handling function were registered by the process (the signal action value was neither SIG_IGN or SIG_DFL) then an entry in the pending signal table is made for that signal and that process is marked as ready to RUN (it may have been waiting on something, like data to become available for a call to read, waiting for a signal, or several other things).
Now the next time that the process is run the OS kernel will first add some data to the stack and changes the instruction pointer for that process so that it looks almost like the process itself has just called the signal handler. This is not entirely correct and actually deviates enough from what actually happens that I'll talk about it more in a little bit.
The signal handler function can do whatever it does (it is part of the process that it was called on behalf of, so it was written with knowledge about what that program should do with that signal). When the signal handler returns then the regular code for the process begins executing again. (again, not accurate, but more on that next)
Ok, the above should have given you a pretty good idea of how signals are delivered to a process. I think that this pretty good idea version is needed before you can grasp the full idea, which includes some more complicated stuff.
Very often the OS kernel needs to know when a signal handler returns. This is because signal handlers take an argument (which may require stack space), you can block the same signal from being delivered twice during the execution of the signal handler, and/or have system calls restarted after a signal is delivered. To accomplish this a little bit more than stack and instruction pointer changes.
What has to happen is that the kernel needs to make the process tell it that it has finished executing the signal handler function. This may be done by mapping a section of RAM into the process's address space which contains code to make this system call and making the return address for the signal handler function (the top value on the stack when this function started running) be the address of this code. I think that this is how it is done in Linux (at least newer versions). Another way to accomplish this (I don't know if this is done, but it could be) would be do make the return address for the signal handler function be an invalid address (such as NULL) which would cause an interrupt on most systems, which would give the OS kernel control again. It doesn't matter a whole lot how this happens, but the kernel has to get control again to fix up the stack and know that the signal handler has completed.
WHILE LOOKING INTO ANOTHER QUESTION I LEARNED
that the Linux kernel does map a page into the process for this, but that the actual system call for registering signal handlers (what sigaction calls ) takes a parameter sa_restore parameter, which is an address that should be used as the return address from the signal handler, and the kernel just makes sure that it is put there. The code at this address issues the I'm done system call (sigreturn)and the kernel knows that the signal handler has finished.
signal generation
I'm mostly assuming that you know how signals are generated in the first place. The OS can generate them on behalf of a process due to something happening, like a timer expiring, a child process dying, accessing memory that it should not be accessing, or issuing an instruction that it should not (either an instruction that does not exist or one that is privileged), or many other things. The timer case is functionally a little different from the others because it may occur when the process is not running, and so is more like the signals sent with the kill system call. For the non-timer related signals sent on behalf of the current process these are generated when an interrupt occurs because the current process is doing something wrong. This interrupt gives the kernel control (just like a system call) and the kernel generates the signal to be delivered to the current process.
Some issues that are not addressed in all of the above statements are multi core, running in kernel space while receiving a signal, sleeping in kernel space while receiving a signal, system call restarting and signal handler latency.
Here are a couple of issues to consider:
What if the kernel knows that a signal needs to be delivered to process X which is running on CPU_X, but the kernel learns about it while running on CPU_Y (CPU_X!=CPU_Y). So the kernel needs to stop the process from running on a different core.
What if the process is running in kernel space while receiving a signal? Every time a process makes a system call it enters kernel space and tinkers with data structures and memory allocations in kernel space. Does all of this hacking take place in kernel space too?
What if the process is sleeping in kernel space waiting for some other event? (read, write, signal, poll, mutex are just some options).
Answers:
If the process is running on another CPU the kernel, via cross CPU communication, will deliver an interrupt to the other CPU and a message for it. The other CPU will, in hardware, save state and jump to the kernel on the other CPU and then will do the delivery of the signal on the other CPU. This is all a part of trying not to execute the signal handler of the process on another CPU which will break cache locality.
If the process is running in kernel space it is not interrupted. Instead it is recorded that this process has received a signal. When the process exits kernel space (at the end of each system call), the kernel will setup the trampoline to execute the signal handler.
If the process, while running in kernel space, after having received a signal, reaches a sleep function, then that sleep function (and this is common to all sleep functions within the kernel) will check if the process has a signal pending. If it is so, it will not put the process to sleep and instead will cancel all that has been done while coming down into the kernel, and will exit to user space while setting up a trampoline to execute the signal handler and then restart the system call. You can actually control which signals you want to interrupt system calls and which you do not using the siginterrupt(2) system call. You can decide if you want system calls restartable for a certain signal when you register the signal using sigaction(2) with the SA_RESTART flag. If a system call is issued and is cut off by a signal and is not restarted automatically you will get an EINTR (interrupted) return value and you must handle that value. You can also look at the restart_syscall(2) system call for more details.
If the process is already sleeping/waiting in kernel space (actually all sleeping/waiting is always in kernel space) it is woken from the sleep, kernel code cleans up after itself and jump to signal handler on return to user space after which the system call is automatically restarted if the user so desired (very similar to previous explanation of what happens if the process is running in kernel space).
A few notes about why all of this is so complex:
You cannot just stop a process running in kernel space since the kernel developer allocates memory, does things to data structures and more. If you just take the control away you will corrupt the kernel state and cause a machine hang. The kernel code must be notified in a controlled way that it must stop its running, return to user space and allow user space to handle the signal. This is done via the return value of all (well, almost all) sleeping functions in the kernel. And kernel programmers are expected to treat those return values with respect and act accordingly.
Signals are asynchronous. This means that they should be delivered as soon as possible. Imagine a process that has only one thread, went to sleep for hour, and is delivered a signal. Sleep is inside the kernel. So you except the kernel code to wake up, clean up after itself, return to user space and execute the signal handler, possibly restarting the system call after the signal handler finished. You certainly do not expect that process to only execute the signal handler an hour later. Then you expect the sleep to resume. Great trouble is taken by the user space and kernel people to allow just that.
All in all signals are like interrupt handlers but for user space. This is a good analogy but not perfect. While interrupt handlers are generated by hardware some signal handlers originate from hardware but most are just software (signal about a child process dying, signal from another process using the kill(2) syscall and more).
So what is the latency of signal handling?
If when you get a signal some other process is running then it up to the kernel scheduler to decide if to let the other process finish its time slice and only then deliver the signal or not. If you are on a regular Linux/Unix system this means that you could be delayed by 1 or more time slices before you get the signal (which means milliseconds which are equivalent to eternity).
When you get a signal, if your process is high-priority or other processes already got their time slice you will get the signal quite fast. If you are running in user space you will get it "immediately", if you are running in kernel space you will shortly reach a sleep function or return from kernel in which case when you return to user space your signal handler will be called. That is usually a short time since not a lot of time is spent in the kernel.
If you are sleeping in the kernel, and nothing else is above your priority or needs to run, the kernel thread handling your system call is woken up, cleans up after all the stuff it did on the way down into the kernel, goes back to user space and executes your signal. This doesn't take too long (were talking microseconds here).
If you are running a real time version of Linux and your process has the highest real time priority then you will get the signal very soon after it is triggered. Were talking 50 microseconds or even better (depends on other factors that I cannot go into).
Think of the signal facility as interrupts, implemented by the OS (instead of in hardware).
As your program merrily traverses its locus of execution rooted in main(), these interrupts can occur, cause the program to be dispatched to a vector (handler), run the code there, and then return to the location where it got interrupted.
These interrupts (signals) can originate from a variety of sources e.g. hardware errors like accessing bad or misaligned addresses, death of a child process, user generated signals using the kill command, or from other processes using the kill system call. The way you consume signals is by designating handlers for them, which are dispatched by the OS when the signals occur. Note that some of these signals cannot be handled, and result in the process simply dying.
But those that can be handled, can be quite useful. You can use them for inter process communication i.e. one process sends a signal to another process, which handles it, and in the handler does something useful. Many daemons will do useful things like reread the configuration file if you send them the right signal.
Signal are nothing but an interrupt in the execution of the process. A process can signal itself or it can cause a signal to be passed to another process. Maybe a parent can send a signal to its child in order to terminate it, etc..
Check the following link to understand.
https://unix.stackexchange.com/questions/80044/how-signals-work-internally
http://www.linuxjournal.com/article/3985
http://www.linuxprogrammingblog.com/all-about-linux-signals?page=show

How does a "kill" work? And especically how does a "kill" work on blocked proces?

Who in the kernel is responsible for killing a process.
What if a "kill" comes, and the process is in the blocked state. Does the kill waits until the process comes to running state to clean himself.
If someone can answer more in terms of kernel, like when a SIGINT from the kill command is generated, what all is invoked by the kernel until the TCBs (task control blocks) are cleared in the end.
I presume you are talking about SIGKILL, so I will confine the discussion to that signal only.
When a process raises a SIGKILL on another process, SIGKILL is added as a pending signal on the victim process, and any pending SIGSTOP, SIGTSTP, SIGTTOU or SIGTTIN signals are cleared. The victim is woken up (made runnable) if it is stopped or in an interruptible sleep state.
When the victim process next attempts to go from Kernel mode to User mode, the pending signals are checked. This is where the pending SIGKILL is found, and the Kernel calls do_exit() instead of going back to User mode.
The transition from Kernel mode to User mode will be when the process is next scheduled (unless it was in an uninterruptible sleep - this is the infamous D state). If it's in an uninterrutible sleep, the process won't try to go back to User mode until its woken.
Killing it with a signal other than SIGKILL, just causes a signal to be sent. This can be masked or ignored, but assuming it isn't (or after it's unmasked), then it interrupts the normal running of the program.
If an IPC-type system call is in progress (e.g. reading from a socket, select(), poll(), sleep() etc), then it will be interrupted and fail with EINTR in errno. A properly written application will re-issue the call after handling the signal.
The process then immediately executes a call to the signal handler, which may return to allow processing to continue, or it could call longjmp (in C), or it could exit the process, which is normally the default.
SIGKILL is completely different, none of the above happens. Instead it just quits the system call (which would presumably leave EINTR in errno, if the process was allowed to read it), then causes the task to exit immediately with no possibility to handle it.
But either of them I think waits for a "D" "uninterruptable sleep" state to finish. This would normally be something like a blocking disc read, page fault demand-load or something.
Running kill simply sends a signal to the process (TERM) asking it nicely to terminate. If it won't respond that's it's business. However, you can choose to send any one of several different signals commanding it to go away. What you may be interested in is kill -9 (SIGKILL) which kills it without giving it a choice in the matter.
(Edit: As was pointed out in the comments, TERM is the default)
Killing (rather than interrupting) is usually performed by the SIGKILL signal in UNIX systems (CTRL-C sends SIGINT).
These systems usually provide a method of interrupting blocking system calls by a signal, which allows the signal handler to execute without waiting on a system call to complete (This is where the EINTR error comes into play). So normally, the call is just cancelled, without waiting for it to complete.
Each process can recieve many types of signal, which it can ignore to handle but few aren't delivered to process but "Proceess scheduler" terminates the process....
see this for more explanation
http://www.linux-tutorial.info/modules.php?name=MContent&pageid=289

Resources