Find signal handler function using GDB? - c

I am working on a C project that has bunch of files. Now I want to find the signal handler functions, but no success while surfing the project tree.
The first way I think about approaching this problem is running the binary with GDB.
Is there a way I can ask GDB to break as soon as a signal (e.g. Ctrl-C) is received?

Here is some reference:
http://nirbhay.in/2012/09/debug-signal-handlers-using-gdb/
Let's do some experiment with this program:
/*
#file : sig.c
*/
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
void signalhandler(int signum) {
printf("\n SIGINT caught : %d", signum);
}
int main() {
signal(SIGINT, signalhandler);
while (1) {
printf("\n looping : inside main()");
sleep(1);
}
}
in this case you can do this way:
(gdb) handle SIGINT stop pass
after that, you step forward to get the signal handler function. Here I got:
$ gdb ./a
...
(gdb) handle SIGINT stop pass
SIGINT is used by the debugger.
Are you sure you want to change it? (y or n) y
Signal Stop Print Pass to program Description
SIGINT Yes Yes Yes Interrupt
(gdb) r
Starting program: /home/arc/a
looping : inside main()
looping : inside main()
^C
Program received signal SIGINT, Interrupt.
0x00007ffff7aef900 in __nanosleep_nocancel () from /usr/lib/libc.so.6
(gdb) s
Single stepping until exit from function __nanosleep_nocancel,
which has no line number information.
0x0000000000400596 in signalhandler(int) ()

Related

Block SIGINT from terminating program

I need some help on C program - it is a reverse shell (https://github.com/arturgontijo/remoteShell/blob/master/reverseShell.c) I made few changes, like put that all in a loop and some sleep pattern + put some argument to pass directly IP and PORT now that thing works very good it's stable (problem that cannot autocomplete stuff with TAB I don't really care) BUT what I really care is that this thing will break if on target machine I press CTRL+C the program just exits itself. Now I used this example to block CTRL+C calls:
/* Signal Handler for SIGINT */
void sigintHandler(int sig_num)
{
/* Reset handler to catch SIGINT next time.
Refer http://en.cppreference.com/w/c/program/signal */
signal(SIGINT, sigintHandler);
printf("\n Cannot be terminated using Ctrl+C \n");
fflush(stdout);
}
signal(SIGINT, sigintHandler);
I got this example online and put it on my loop as well, but still from client pressing ctrl+C breaks program. I wonder dup2() is responsible for that or something because on simple C program this actually worked fine.
You can use the sigetops family of functions to manipulate the signals sent into your application.
So for your example you could use:
#include <signal.h>
#include <unistd.h>
int main(int argc, char **argv)
{
sigset_t block_set;
sigemptyset(&block_set);
sigaddset(&block_set, SIGINT);
sigprocmask(SIG_BLOCK, &block_set, NULL);
while(1) {
sleep(1);
}
}
Running Example: https://repl.it/repls/RelevantImaginarySearchservice
You can unblock the signal at a later time by calling
sigprocmask(SIG_UNBLOCK, &block_set, NULL);

Interrupted system call in C

I want to make my program sleep upto 10 seconds even the signal is occured. So, I tried the following program.
Program:
#include<stdio.h>
#include<signal.h>
#include<errno.h>
int main()
{
printf("PID: %d\n",getpid());
int unslept=10;
while(unslept>0){
unslept=sleep(unslept);
if(errno==EINTR)
continue;
}
return 0;
}
Output:
$ ./a.out
PID: 18935
User defined signal 1
$
I expect the above program will execute 10 seconds even the signal is interrupted. I exeperiment it like, in one terminal I
executed this program. And using another terminal using kill command I sent the SIGUSR1 signal to this process. But, the same problem
occurs. Once the signal is passed, the program terminates. So, is there any way to execute my program upto 10 seconds without affecting
any signal.
You can ignore the signal. See the below example, in that example, if the SIGUSR1 signal is interrupted, it just ignore the signal using the SIG_IGN.
#include<stdio.h>
#include<signal.h>
int main(void)
{
if (signal(SIGUSR1, SIG_IGN) == SIG_ERR)
perror("SIGUSR1");
sleep(30);
}
You can use signal handling mechanism. Register your method that will handle interrupt signals and just ignore it that in your function.
// signal handler
void my_function(int sig){
//do nothing
}
// register signal
signal(SIGNAL_ID, my_function);

How to detect program termination in C/Linux?

How can an application find out that it just started terminating ? Can I use signal handler for that ?
Enable atexit(). It will call a function when program terminated normally.
Sample code:
#include <stdio.h>
#include <stdlib.h>
void funcall(void);
void fnExit1 (void)
{
printf ("Exit function \n");
}
int main ()
{
atexit (fnExit1);
printf ("Main function start\n");
funcall();
printf ("Main function end\n");
return 0;
}
void funcall(void)
{
sleep(2);
exit(0);
}
Output:
Main function start
Exit function
You Could try ---> int raise (int sig)
And handle when SIGTERM or SIGKILL is raised!!
You can also register a function to be called upon exit of a process. See man atexit
You can install a signal handler for SIGINT ,SIGKILL and SIGSEGV. In the signal handler you can take a stack dump so you can debug your application later.In the signal handler set the disposition of SIGINT ,SIGKILL and SIGSEGV back to default.

Handling multiple signals

I have a question about handling a signal.
Assume that if we recieve SIGINT signal, we should print "Recieved Signal". If within ten seconds the handler recieves another signal, it should print "Shutting Down" then exit with status 1.
I made my code like this:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
void handler(int);
void secondhandler(int);
void alrmhandler(int);
void alrmhandler (int alrmsig)
{
alarm(0);
}
void secondhandler(int sig)
{
/* after recieving second signal prints shutting down and exit */
printf("Shutting Down\n");
exit(1);
}
void handler ( int sig )
{
/* recieve first SIGINT signal */
printf ("Recieved Signal\n");
/* handle for the alarm function */
signal(SIGALRM, alrmhandler);
/* start 10s alarm */
alarm(10);
/* catch second SIGINT signal within 10s*/
signal(SIGINT, secondhandler);
}
int main( void )
{
signal(SIGINT, handler);
printf( "Hello World!\n" );
for ( ;; )
{
/* infinite loop */
}
return 0;
}
I tried to compile it with dev c++, but it failed. Because SIGALRM undeclared(first use in this function).
Anyway, what I want to know is if this code is right. I actually kinda not sure with the alrmhandler(). should I ignore the SIGALRM?
If you are on a Windows platform, the only signals you will be able to send are : SIGABRT, SIGFPE, SIGILL, SIGINT, SIGSEGV, or SIGTERM.
You write:
what I want to know is if this code is right.
Not entirely. printf() is not async-signal-safe, and so should not be called from within a signal handler unless you are very sure it is safe to do so. It is not safe to do so within the code you provide.
The alarm() technique is, generally, race-prone. Your ten second alarm might expire in the middle of your secondhandler() function. To guard against this, you might mask out signals to compensate with a more sophisticated signal manipulation function.
There are more elegant/flexible ways of implementing the timeout you desire, but that's perhaps a question better suited for codereview.stackexchange.com.

What is the difference between normal function call and signal() system call?

While learning signal() system call, I supposed to come across the following code,
#include <stdio.h>
#include <signal.h>
void sigproc(int);
void quitproc(int);
int main(int argc,char **argv)
{
signal(SIGINT, sigproc); //Is it like a normal Call to signal()?
signal(SIGQUIT, quitproc);// This too?
printf("ctrl- c disabled use ctrl\ to quit \n");
while(1);
return 0;
}
void sigproc(int signo)
{
printf("you have pressed ctrl - c \n");
}
void quitproc(int signo)
{
printf("U cant quit\n");
// exit(0);
}
I am calling the function signal() twice in main(). But its executed only when I'm pressing Ctrl-C and Ctrl-\ keys. I thought its also like normal function call. What is actually happening in the signal handler functions?
The signal function establishes a signal handler. What it means: "When my process receives this signal, run this function instead of doing whatever the default was".
So, in your example the calls to signal don't call the function. To actually see the signals in action, do this:
Start your process in one terminal
From another terminal:
kill -INT `pidof proc`
As a side note, printf and friends aren't async-signal-safe. It might come as a shocker, but it's unsafe to use them in signal handlers.
As a side side note, even if you tagged your question Unix it's important to know that signals (and the signal function) are standard, integral parts of C. Signal handling and the signal function are described in C99 in ยง7.14.1.

Resources