Core is getting generated when the alarm goes off - c

I'm trying to call the func1 for 3 times using SIGALRM but there is crash happen and core is getting generated intermittently.
This is the sample func:
int func_incr++;
volatile sig_atomic_t valData=0;
void alarm_hdlr(int signum);
{
func_incr++;
valData = 1;
}
void func1()
{
signal(SIGALRM, alarm_hdlr);
alarm(300);
while(func_incr !=3)
{
if(valData) // while debugging using gdb, in this line SIGABRT signal is received (Thread 1 "func1" SIGABRT signal received)
{
valData=0;
func1();
}
}
}
int func1()
{
func2();
}
Can someone help me?
Thanks

Since you are using gdb, and you are also getting abrt signal, you should be able to see the backtrace to see what is reason for sigabrt.

Related

C - Higher Order Function

Signal takes a callback function as one of its arguments. To have variable behaviour I want to create a function within a function. This is my attempt so far:
typedef void (*sighandler_t)(int);
sighandler_t f(int pid) {
void sigintHandler(int sig) {
printf("Process %d", pid);
}
return sigintHandler
}
int main(void) {
...
if (signal(SIGTSTP, *f(1)) == SIG_ERR) {
...
}
...
}
But, every time I send a SIGTSTP (Ctrl-z), I get a seg fault.
As a sidenote: any tips on how to debug seg faults in general would be really appreciated!
Your code compiles because it's syntactically correct and you're using compiler extensions; however, there are some fundamental issues with your code that might be leading to your segfault.
First, your signal handler code:
typedef void (*sighandler_t)(int);
sighandler_t f(int pid) {
void sigintHandler(int sig) {
printf("Process %d", pid);
}
return sigintHandler;
}
This is not standard C and even requires the -ftrampolines flag be specified on some versions of gcc to actually compile.
Your signal handler function itself has a few issues that need to be resolved:
sigintHandler is a nested function, thus when your signal handler function f returns by return sigintHandler;, you're returning a function pointer.
In your code, this compiles correctly because you have typedef void (*sighandler_t)(int);, which defines a function pointer type that can point to functions that have a void return type and take an int as a parameter, which your sigintHandler is defined as.
Instead, your signal handler function could be written simply as:
void sigintHandler(int sig) {
printf("Signal %d\n", sig);
}
In your main function, you have the following:
if (signal(SIGTSTP, *f(1)) == SIG_ERR) {
// ....
}
Here it should be noted this as well has some issues. First, the signal function takes as its first parameter the signal number (usually a macro defined in the signal.h header) and as it's second argument a pointer to a function defined as void func_name(int sig).
To this, you are calling the function instead of passing it as a pointer.
*f(1) actually makes a call to f passing 1 as its parameter; instead, you would change it to the following:
if (signal(SIGTSTP, f) == SIG_ERR) {
// ....
}
But this should emit a warning/error since f is defined as returning a function pointer instead of void.
So to change the code to be compliant, you could just do the following:
#include <stdio.h>
#include <signal.h>
void sigintHandler(int sig) {
printf("Signal %d", sig);
}
int main(void) {
// ...
if (signal(SIGTSTP, sigintHandler) == SIG_ERR) {
// ...
}
// ...
return 0;
}
You stated however:
To have variable behaviour ...
This depends on what kind of variable nature you're intending, but if it's variable functions based on the signal, you can do something like the following:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
void sig_stop(int sig) {
printf("Process %d stop\n", getpid());
}
void sig_int(int sig) {
printf("Process %d interrupt\n", getpid());
}
int main(void) {
// ...
if (signal(SIGTSTP, sig_stop) == SIG_ERR) {
// ...
}
if (signal(SIGINT, sig_int) == SIG_ERR) {
// ...
}
// ...
return 0;
}
Or you could use a switch statement:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
void sigHandler(int sig) {
printf("Process %d received %d\n", getpid(), sig);
switch (sig) {
case SIGTSTP:
// do stop code
break;
case SIGINT:
// do interupt code
break;
}
}
int main(void) {
// ...
if (signal(SIGTSTP, sigHandler) == SIG_ERR) {
// ...
}
if (signal(SIGINT, sigHandler) == SIG_ERR) {
// ...
}
// ...
return 0;
}
any tips on how to debug seg faults in general would be really appreciated!
First, understand what a segmentation fault is; then you can use a debugger like gdb to step through your code or inspect crash dumps to see where specifically the segfault is happening.
Hope that can help.
aint sure about what you are asking, but i can help you understand your segmentation fault.
when you call a function there are several things that are done.
push function arguments to stack
push return address to stack
jump to function address
function body
pop return address from stack
pop function arguments from stack.
when 1,2, 6 are done by the Calling scope.
As you know, signal is a void arguments hence the call (1) would push 0 arguments to the stack.
while the return (6) would pop your "unexistant" int from the stack and corrupt it.
somewhat solution
you can't have signal function with parameters,
what you can is:
you can read your global variables within the signal function. and therefore read the current state of the program.
you can sys_call to get your process_id, thread_id.
i wouldn't recommend but you can read your stack further to the previous scope and get it's local variables. With BIG Note that it won't be the function you set the signal at... but the function that was running at the moment of the signal.

how to block same signal while processing a signal?

I programmed a daemon which usually pauses and do something after getting a signal (I use SIGHUP for waking up it to another process).
Here is my code.
...
static volatile sig_atomic_t saw_hup = 0;
static void sighup_handler(int s)
{
saw_hup = 1;
}
int main(void)
{
struct sigaction act_new;
...
sigemptyset(&act_new.sa_mask);
act_new.sa_handler = sighup_handler;
sigaction(SIGHUP, &act_new, NULL);
while(1) {
saw_hup = 0;
pause();
if(saw_hup) {
do_section_A();
}
}
}
As far as I've tested it, it seems that there is some stack for signal, so the signal, which occurs in executing section A, makes the daemon waken up from pause() execute section A again right after finishing section A by previous one.
But, I want the next SIGHUP signal to be blocked and not to execute section A again by it. What I want is to execute section A whenever SIGHUP occurs except for in the middle of section A executed by previous SIGHUP signal. How do I do that?
I think i the problem that section A is executed again right after section A execution by SIGHUP occurred in the middle of section A execution.
Here is my modified code
...
static volatile sig_atomic_t saw_hup = 0;
static void sighup_handler(int s)
{
saw_hup = 1;
}
int main(void)
{
struct sigaction act_new;
...
sigemptyset(&act_new.sa_mask);
act_new.sa_handler = sighup_handler;
sigaction(SIGHUP, &act_new, NULL);
while(1) {
saw_hup = 0;
pause();
if(saw_hup) {
do_section_A();
}
}
}
It seems to work as i wanted. does anybody think there is any problem to this code?
pthread_sigmask() can be used to mask signal in thread. sigprocmask() can be used to mask signal in single thread application.

Find signal handler function using GDB?

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) ()

handler for SIGALRM does not work

I'm on an Assignment.
The Assignment is making virtual Real Time Operating System on Linux System(on Ubuntu).
My problem is SIGALRM and it's handler for Scheduler.
void scheduler(int signo) {
/*variables */
printf("Scheduler awake!!\n");
/* Do
Schedule */
}
int RunScheduler(void) {
signal(SIGALRM, scheduler);
alarm(1);
while(1)
pause();
return 0;
}
int main() {
RunScheduler();
}
The function scheduler(handler) does not work. alarm(1) works, but just paused after alarm(1).
Is there any reason signal handler does not work??
The very same code works correctly on my machine.
I have used the gcc compiler that comes bundled with Ubuntu. Are you using the same compiler?

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.

Resources