I created an application that receives commands from another process.
There the two exit commands.
exit: exits the main process (and his threads) and let the child processes finish their tasks.
exit now: exists the main process (and his threads) and sends a signal to exit the child processes to
The exit command is working fine but the exit now its not, I get a message saying "Exit (core dumped)" when I use it.
The exit command executes this function.
void processExit(){
/* some code to close opened files and to wait for threads to finish (pthread_join) */
exit(EXIT_SUCCESS);
}
The exit now command executes this function.
void processExitNow(){
signal(SIGQUIT, SIG_IGN);
kill(0, SIGQUIT);
processExit();
}
So I think the core dumped is caused by the kill function. But why does this happen? I can´t find the problem.
Thanks.
The purpose of SIGQUIT is to generate a core dump. Use a different signal. gnu.org/software/libc/manual/html_node/Termination-Signals.html
– Dark Falcon
Related
I am trying to catch the SIGTERM signal and print a message in the handler from a Linux daemon:
void SigStop_Handler(int sig)
{
D(printf("****************** HANDLED STOP SIGNAL ******************\n"));
printf("\n");
}
int main(int argc, char *argv[])
{
signal(SIGTERM, SigStop_Handler);
while(true)
{
//do something
}
return 0;
}
The program runs as a daemon, started from a command line:
systemctl start abc
The deameon will be stopped by:
systemctl stop abc
When the daemon is stopping, I expected that the message will be printed on the console. However the message is not printed and the command line doesn’t return to the command-promt. It does return after a while (timeout). The daemon will be stopped, but the message will not be printed.
What am I doing wrong?
Two items to consider: terminating the daemon when signal is received, and getting the message.
In the context of systemctl, you want your signal handler to exit the program. Otherwise,
it will just 'print' the message the messages, and resume processing. Try
void SigStop_Handler(int sig)
{
D(fprintf(stderr, "****************** HANDLED STOP SIGNAL ******************\n"));
printf("\n");
exit(sig+128) ;
}
Also, given that the process run as a daemon, stdout is not going to be connected to the terminal. Instead, it will get redirected into log file. Also, suggesting using stderr to send messages, instead of stdout (see code above). Also, look at StandardOutput and StandardErrro configuration entries for your service.
The delay that you currently observe occurs because 'systemctl' wait for few seconds after sending the TERM signal - giving the daemon change to terminate. If the daemon does not terminate voluntarily, a KILL signal will be sent, which will force the daemon to terminate, unconditionally, immediately.
abort() do collect the core dump, but I don't want the process to terminate. dump_core() collects the core dump, but in kernel space. Is there any function equivalent to dump_core() in user space?
A simple way to do it yourself is to fork the process (which creates a complete copy of the parent process) and call abort from the child process.
The child process will be aborted with a core-dump, while the parent process continues as if nothing happened.
Use gcore.
.
.
.
char command[ 1024 ];
sprintf( command, "gcore -o /core/file/name %d", getpid() );
system( command );
.
.
.
Error and bounds checking are omitted.
There is no such Linux C command. However, you may find some third party tools that can do this for you. For example, Google coredumper, which is also supposed to be able to capture all the threads. Another way would be to attach gdb to your running process, and issue the gcore command. This is essentially what the gcore command line utility does.
Kernel generates SIGSEGV signal to the process whenever coredumps, I think you should attach a handler to the SIGSEGV signal(Link) and call fork from that handler function.
I am working on an embedded linux with busybox. As part of my application I have a rc.init script E80-startmyprog. That script is calling my program prog.
trap "" HUP
startmyprog >${LOGFILE} 2>&1 </dev/null &
startmyprog() {
prog
}
In my program I can see that the signal handlers are set to ignore SIGHUP. I am checking that with
struct sigaction act;
sigaction(1, NULL, &act);
printf("action %p\n", act.sa_sigaction); // prints out 1 -> SIG_IGN
Now at some time in my program I need to start another process, give it some input and check if it printed "yes" on stdout. I am using system to do that.
const int ret = system("[ `echo input | second_process` == yes ]");
Normal behavior is that WIFEXITED(ret) is true and that WEXITSTATUS(ret) is 0 or 1.
But in some cases with unfortunate timing WIFSIGNALED(ret) is true and WTERMSIG(ret) is 1 (SIGHUP).
Debugging shows that if I execl("second_process", "second_process", (char*)NULL) the signal handler state in second_process is set correctly to SIGHUP=ignore. But if I use system, then second_process has SIGHUP=default.
My questions are:
What is going on there? Who is resetting the SIGHUP signal handler at startup? Is it the shell? Is there a way to prevent that? (In the sh man page I have not seen a command line option that looks so.)
I know I could do a workaround and setup a pipe, fork, exec second_process, write input to pipe, read output from pipe and parse output, but that is a lot of stuff compared to a system one liner and there is good chance that I will miss something and get it wrong.
I don't think that's exactly what's happening. When you type 'trap' into the shell, you're asking it list the actions it has established for that signal. When you invoke a subshell, you haven't given it any actions, so it won't show any (it doesn't know about what you gave to its parent) but that doesn't mean it has reset the SIGHUP state.
Try this small script that proves SIGHUP is still ignored even though "trap" shows nothing:
trap "" HUP
echo "TRAPs in parent"
trap
sh -c 'echo "TRAPs in child"; trap; sleep 5; echo "Still here. Traps: "; trap' &
child=$!
sleep 1
kill -HUP $child
echo 'Killed child'
Digging deeper into the sources of the busybox that is running on the Linux I found out that the shell in busybox is calling signal(SIGHUP, SIG_DFL); during init. This resets the sighup handler to default. So the shell itself and the program it runs (provided with -c ...) are running with default SIGHUP handler.
I see no code path that bypasses resetting the SIGHUP signal handler, so it seems I cannot achieve what I want with system().
I am new in C programming and I have been trying hard to customize an opensource tool written in C according to my organizational needs.
IDE: Eclipse,
Debugger: GDB,
OS: RHEL
The tool is multi-process in nature (main process executes first time and spawns several child processes using fork() ) and they share values in run time.
While debugging in Eclipse (using GDB), I find that the process being debugged is only running while other processes are in suspended mode. Thus, the only running process is not able to do its intended job because the other processes are suspended.
I saw somewhere that using MI command in GDB as "set non-stop on" could make other processes running. I used the same command in the gdbinit file shown below:
Note: I have overridden above .gdbinit file with an another gdbinit because the .gdbinit is not letting me to debug child processes as debugger terminates after the execution of main process.
But unfortunately debugger stops responding after using this command.
Please see below commands I am using in the gdbinit file:
Commenting non-stop enables Eclipse to continue usual debugging of the current process.
Adding: You can see in below image that only one process is running while others are suspended.
Can anyone please help me to configure GDB according to my requirement?
Thanks in advance.
OK #n.m.: Actually, You were right. I should have given more time to understand the flow of the code.
The tool creates 3 processes first and then the third process creates 5 threads and keeps on wait() for any child thread to terminate.
Top 5 threads (highlighted in blue) shown in the below image are threads and they are children of Process ID: 17991
The first two processes are intended to initiate basic functionality of the tool and hence they just wait to get exit(0). You can see below.
if (0 != (pid = zbx_fork()))
exit(0);
setsid();
signal(SIGHUP, SIG_IGN);
if (0 != (pid = zbx_fork()))
exit(0);
That was the reason I was not actually able to step in these 3 processes. Whenever, I tried to do so, the whole main process terminated immediately and consequently leaded to terminate all other processes.
So, I learned that I was supposed to "step-into" threads only. And yes, actually I can now debug :)
And this could be achieved because I had to remove the MI command "set follow-fork-mode child". So, I just used the default " .gdbinit" file with enabled "Automatically debug forked process".
Thanks everyone for your input. Stackoverflow is an awesome place to learn and share. :)
I have a program that requires it to pause and resume another program. To do this, I use the kill function, either from code with: -
kill(pid, SIGSTOP); // to pause
kill(pid, SIGCONT); // to resume
Or from the command line with the similar
kill -STOP <pid>
kill -CONT <pid>
I can trace what's going on with the threads using this code, taken from Mac OS X Internals.
If a program is paused and immediately resumed, the state of threads can show as UNINTERRUPTIBLE. Most of the time, they report as WAITING, which is not surprising and if a thread is doing work, it will show as RUNNING.
What I don't understand is when I pause a program and view the states of the threads, they still show as WAITING. I would have expected their state to be either STOPPED or HALTED
Can someone explain why they still show as WAITING and when would they be STOPPED or HALTED. In addition, is there another structure somewhere that shows the state of the program and its threads being halted in this way?
"Waiting" is shown in your case because you did not terminate the program rather paused it, where as Stopped or Halted state usually occurs when the program immediately stopped working due to some runtime error. As far as your second question is concerned, I do not think there is some other structure out there to show the state of the program. Cheers
After researching and experimenting with the available structures, I've discovered that it is possible to show the state of a program being halted by looking at the process suspend count. This is my solution: -
int ProcessIsSuspended(unsigned int pid)
{
kern_return_t kr;
mach_port_t task;
mach_port_t mytask;
mytask = mach_task_self();
kr = task_for_pid(mytask, pid, &task);
// handle error here...
char infoBuf[TASK_INFO_MAX];
struct task_basic_info_64 *tbi;
int infoSize = TASK_INFO_MAX;
kr = task_info(task, TASK_BASIC_INFO_64, (task_info_t)infoBuf, (mach_msg_type_number_t *)&infoSize);
// handle error here....
tbi = (struct task_basic_info_64 *) infoBuf;
if(tbi->suspend_count > 0) // process is suspended
return 1;
return 0;
}
If suspend_count is 0, the program is running, else it is in a paused state, waiting to be resumed.