In a debugging session, when the deugger wants to set a breakpoint, it replaces an instruction by int3. When the Target process reach this instruction, the process stops. I have read that a signal is send at this time. But i did not manage to capture this signal (i wrote my own mini debugger for testing). Who send this signal ? The kernel? And who is the receiver?
I had to put a wait() fonction juste after the ptrace_cont. Do you think this is this wait function that catch the signal in order to notify the debugger that the process reach a break point ?
When the Target process reach this instruction, the process stops.
That's not quite accurate. When the trap instruction (0xCC on x86) is executed, the processor notifies the OS. On UNIX, the OS checks to see whether the process is being ptraced by somebody.
If no, the SIGTRAP signal is delivered to the application, which usually results in process being killed (but you can catch and handle the signal in the application).
If there is a ptraceer (usually a debugger), then the signal is not delivered to the application. Instead, debugger's wait is unblocked to notify the debugger that the inferior has changed state. The debugger then looks at where the inferior process stopped, discovers that it did so because of a breakpoint, and handles the situation as appropriate (let's you examine the inferior, or resumes it if the breakpoint is conditional and current conditions don't match, etc.)
Related
I have written a C++ program and I am executing in the gnome terminal (I am on Ubuntu). I press Ctrl + Z, which suspends the process. Later on, I execute % on the same terminal, which resumes execution.
From what I've read, Ctrl+Z sends a TSTP signals to the process, which tells it to stop execution. But TSTP is polite, in the sense that the process is allowed to continue until it decides it can stop. In my C++ program code, I didn't do anything to explicitly deal with TSTP signals. So, my question is, what things inside my C++ code will continue running in spite of the TSTP signal? For example, if I have a file stream open, will it wait until it is closed? I expect an overall answer, not too deep or covering all the details. I just want an idea of how this happens.
Your program continues running while the SIGTSTP handler executes. Since you haven't set one up, you get the default signal handling behavior, which is for the process to be stopped.
While your process is stopped, it simply isn't scheduled for execution. Files don't get closed, nor is stopping delayed until files get closed (unless done in the signal handler).
This website looks like it has a helpful explanation of how a handler can be installed to perform some tasks and then have the default stopping behavior:
http://man7.org/tlpi/code/online/dist/pgsjc/handling_SIGTSTP.c.html
I have a multithreaded application under Windows 7.
I need to correctly finish jobs in threads which have an open descriptors, connections and so on when a user presses 'X' in the corner of command line, 'Ctrl+C', shuts down OS and so on.
I've set a handler for SetConsoleHandler which sets appropriate flags for other threads to correctly finish their job. But all of them are interrupted and the y exit with code 0xc000013a. SOmetimes even my handler doesn't have time to set flag.
The same problem remains when I try to do the same operations in atexit handler.
Why are all threads stopped even during interruption handler? How can I avoid this and let all my threads finish their job?
sets appropriate flags for other threads to correctly finish their job
Usually it's not enough. You also must wait the threads to finish (thread.join(), or WaitForMultipleObjects, or something similar).
The problem in my case was that some of child-children thread used timed-waiting on system resources so each of them needed to wake from waiting to join thread. And all of them were stopping consecutively so they required too much time to stop.
I am just trying to understand the concept of signal handling with respective from kernel and user mode for the running process.
PROCESS-1 --------------------> PROCESS-3
(parent process) <-------------------
^ process-3 sending signals(SIGPIPE-for communication) or
|| SIGSTOP or SIGKILL to process-1
||
||
||process-1 waiting for child process-2
|| using waitpid command.
||
v
PROCESS-2(waiting for resource, page fault happened, etc)
(child process)
I want to know how kernel sends the signal from process-3 to process-1 knowing that process-1 is waiting for process-2 to finish. Would like to know more about the user and kernel communication during the signal handling scenario(PCB,resources,open file descriptors etc.). Please explain related to this context..
Any help given is thankful..!!!
The kernel doesn't really care that process-1 is "waiting for process-2 to finish" (in particular it's not interested in "why" it's in the state it is, merely that it is in some state: in this case, idling in the kernel waiting for some event). For typical1 caught signals, the signal-sender essentially just sets some bit(s) in the signal-receiver's process/thread state, and then if appropriate, schedules that process/thread to run so that it can see those bits. If the receiver is idling in the kernel waiting for some event, that's one of the "schedule to run" cases. (Other common situations include: the receiver is in STOP state, where it stays stopped except for SIGCONT signals; or, the receiver is running in user mode, where it is set up to transition to kernel mode so as to notice the pending signals.)
Both SIGKILL and SIGSTOP cannot be caught or ignored, so, no, you cannot provide a handler for these. (Normally processes are put into stop state via SIGTSTP, SIGTTIN, or SIGTTOU, all of which can be caught or ignored.)
If system calls are set to restart after a user signal handler returns (via the SA_RESTART flag of sigaction()), this is achieved by setting up the "return address" for the sigreturn() operation to, in fact, make the system call over again. That is, if process-1 is in waitpid(), the sequence of operations (from process-1's point of view) from the point of the initial waitpid(), through receiving a caught signal s, and back to more waiting, is:
system call: waitpid()
put self to sleep waiting for an event
awakened: check for awakening event
event is signal and signal is caught, so:
set new signal mask per sigaction() settings (see sigaction())
push signal frame on a stack (see SA_ONSTACK and sigaltstack())
set up for user code (program counter) to enter at "signal trampoline"
return to user code (into trampoline)
(At this point process-1 is back in user mode. The remaining steps are not numbered because I can't make SO start at 9. :-) )
call user handler routine (still on stack chosen above)
when user routine returns, execute sigreturn() system call,
using the frame stored at setup time, possibly modified
by user routine
(At this point the process enters kernel mode, to execute sigreturn() system call)
system call: sigreturn(): set signal mask specified by sigreturn() argument
set other registers, including stack pointer(s) and
program counter, as specified by sigreturn() arguments
return to user code
(the program is now back in user mode, with registers set up to enter waitpid)
system call: waitpid()
At this point the process returns to the same state it had before it received the caught signal: waitpid puts it to sleep waiting for an event (step 2). Once awakened (step 3), either the event it was waiting for has occurred (e.g., the process being waitpid()-ed is done) and it can return normally, or another caught signal has occurred and it should repeat this sequence, or it is being killed and it should clean up, or whatever.
This sequence is why some system calls (such as some read()-like system calls) will "return early" if interrupted by a signal: they've done something irreversible between the "first" entry into the kernel and the time the signal handler is to be run. In this case, the signal frame pushed at step 6 must not have a program-counter value that causes the entire system call to restart. If it did, the irreversible work done before the process went to sleep would be lost. So, it is instead set up to return to the instruction that detects a successful system call, with the register values set up to return the short read() count, or whatever.
When system calls are set up not to restart (SA_RESTART is not set), the signal frame pushed in step 6 is also different. Instead of returning to the instruction that executes the system call, it returns to the instruction that detects a failed system call, with the register values set up to indicate an EINTR error.
(Often, but not always, these are the same instruction, e.g., a conditional branch to test for success/fail. In my original SPARC port, I made them different instructions in most cases. Since leaf routines return to %o6+8 with no register or stack manipulation, I just set a bit indicating that a successful return should return to the leaf routine's return address. So most system calls were just "put syscall number and ret-on-success flag into %g1, then trap to kernel, then jump-to-error-handling because the system call must have failed if we got here.")
1Versus queued signals.
Sometimes when I am debugging I get message like this.
Program received signal SIG44, Real-time event 44.
What does it means?
Thank you.
EDIT :
Platform is linux
A signal is a message sent by the kernel to a process in order to notify the process that event of some kind has occurred in the system.
Usual signals on linux are for example SIGINT (value 2, interrupt from keyboard) or SIGKILL ( value 9, kill a program).
Signals are received either when the kernel detects a system event (like division by zero is SIGFPE, value 8) or when a process invokes the kill() function to explicitly tell the kernel to send a signal to a process (or to the process itself that called the kill() ).
A signal can often be caught by the process in order to do something.
So to answer to your question, the code is most likely calling the kill() function and sending it a signal with value 44 when something happens. Since you are getting that message, it means that the process has received the signal and is going to exit or do what is written in the code in case that signal comes.
Unlike standard signals, real-time
signals have no predefined meanings:
the entire set of real-time signals
can be used for application-defined
purposes. (Note, however, that the
LinuxThreads implementation uses the
first three real-time signals.)
Source for the quote here
The GNU C++ library uses SIG44 to awaken sleeping threads when signalling condition variables.
I am invoking several processes in my main and I can get the pid of that processes. Now I want to wait until all this processes have been finished and then clear the shared memory block from my parent process. Also if any of the process not finished and segfaulted I want to kill that process. So how to check from the pid of processes in my parent process code that a process is finished without any error or it gave broke down becoz of runtime error or any other cause, so that I can kill that process.
Also what if I want to see the status of some other process which is not a child process but its pid is known.
Code is appreciated( I am not looking for script but code ).
Look into waitpid(2) with WNOHANG option. Check the "fate" of the process with macros in the manual page, especially WIFSIGNALED().
Also, segfaulted process is already dead (unless SIGSEGV is specifically handled by the process, which is usually not a good idea.)
From your updates, it looks like you also want to check on other processes, which are not children of your current process.
You can look at /proc/{pid}/status to get an overview of what a process is currently doing, its either going to be:
Running
Stopped
Sleeping
Disk (D) sleep (i/o bound, uninterruptable)
Zombie
However, once a process dies (fully, unless zombied) so does its entry in /proc. There's no way to tell if it exited successfully, segfaulted, caught a signal that could not be handled, or failed to handle a signal that could be handled. Not unless its parent logs that information somewhere.
It sounds like your writing a watchdog for other processes that you did not start, rather than keeping track of child processes.
If a program segfaults, you won't need to kill it. It's dead already.
Use the wait and waitpid calls to wait for children to finish and check the status for some idea of how they exiting. See here for details on how to use these functions. Note especially the WIFSIGNALED and WTERMSIG macros.
waitpid() from SIGCHLD handler to catch the moment when application terminates itself. Note that if you start multiple processes you have to loop on waitpid() with WNOHANG until it returns 0.
kill() with signal 0 to check whether the process is still running. IIRC zombies still qualify as processes thus you have to have proper SIGCHLD handler for that to work.