Search code examples
c++linuxcrashforkkill

C++ kill() crashes linux to login screen


i am having problems with a project of mine, i am creating child processes with fork and then terminating them with kill(pid,SIGINT) and then restarting them after the second time interrupting the process linux will crash to the login screen. so it is also possible that gnome or my windowmanager is actually the thing that is crashing i dont know how to fix this. here is the code that results in a crash

#include <iostream>
#include <signal.h>
#include <thread>

const int CHILDREN = 3;
bool is_active;

using namespace std;

void signalHandler(int signum)
{
    cout << "Interrupt signal (" << signum << ") received.\n";

    // cleanup and close up stuff here
    // terminate program

    is_active = false;
}

pid_t fork_process(int process_nr)
{
    pid_t c_pid;
    c_pid = fork();
    if (c_pid == -1)
    {
        perror("failure to fork new process");
        return -1;
    }
    else if (c_pid == 0)
    { // child process
        signal(SIGINT, signalHandler);
        is_active = true;
        while (is_active)
        {
        }
        cout << "child " << process_nr << " EXIT" << endl;
        return -1;
    }
    return c_pid;
}

pid_t restart_process(int process_nr, pid_t pid)
{
    cout << "restart process " << process_nr << endl;
    pid_t new_c_pid;
    kill(pid, SIGINT);//THIS IS WHERE THE CRASH HAPPENS

    sleep(3);

    new_c_pid = fork_process(process_nr);
    return new_c_pid;
}

int main(int argc, char const *argv[])
{
    int ret;
    pid_t c_pid[CHILDREN];

    for (int i = 0; i < CHILDREN; i++)
    {
        ret = fork_process(i);
        if (ret == -1)
            return 0;
        c_pid[i] = ret;
        cout << "parent created child " << i << " with c_pid " << c_pid[i] << endl;
    }

    int to_restart = 1;

    this_thread::sleep_for(chrono::seconds(16));

    // restart the selected process
    c_pid[to_restart] = restart_process(to_restart, c_pid[to_restart]);

    this_thread::sleep_for(chrono::seconds(16));

    // restart the selected process
    c_pid[to_restart] = restart_process(to_restart, c_pid[to_restart]);//THIS IS WHERE THE CRASH HAPPENS

    this_thread::sleep_for(chrono::seconds(16));
    return 0;
}

with the Makefile

CC = g++
CFLAGS = -Wall -g

output: main.o
    $(CC) $(CFLAGS) -o output main.o
main.o: main.cpp
    $(CC) $(CFLAGS) -c  main.cpp
clean:
    rm *.o output

thanks for the help.

restarting once works fine so i dont know how calling it twice would create the crash i have run it with gdb and have marked where the crash happens. however it will not happen immediately but after 5 second after executing the kill() function


Solution

  • When you restart_process, you are not checking the result value for -1. So, when the forked child returns, it continues like it were on the main process, except that the next time it kills the presumed child, it calls kill(-1, ...) which kills everything you have permission to kill.

    Something like that, anyway.