1

I am writing a Linux daemon to execute my code. My code makes a call to a third party library. If I execute my code from the parent then everything runs fine, but if I execute my code directly from a child the call to the third party library never returns. And if I create a second executable that executes my code and I have the daemon run the executable then everything runs fine.

Why can't I call my code from the child process?

int main(void)
{
    // Our process ID and Session ID
    pid_t pid, sid;

    fflush(stdout);

    // Fork off the parent process
    pid = fork();
    if (pid < 0)
        exit(EXIT_FAILURE);

    // If we got a good PID, then we can exit the parent process.
    if (pid > 0)
        exit(EXIT_SUCCESS);

    // Change the file mode mask
    umask(0);

    // Open any logs here
    close(STDIN_FILENO);
    close(STDOUT_FILENO);
    close(STDERR_FILENO);
    if (open("/dev/null",O_RDONLY) == -1)
        exit(EXIT_FAILURE);
    if (open("/dev/null",O_WRONLY) == -1)
        exit(EXIT_FAILURE);
    if (open("/dev/null",O_WRONLY) == -1)
        exit(EXIT_FAILURE);

    // Create a new SID for the child process
    sid = setsid();
    if (sid < 0)
        exit(EXIT_FAILURE);

    // Change the current working directory
    if ((chdir("/")) < 0)
        exit(EXIT_FAILURE);

    // doesn't work
    MyObject ob;
    ob.start();

    // works
    //execlp("/home/root/NextGenAutoGuidance", "NextGenAutoGuidance", (char*)NULL);


    while(1)
    {
        sleep(60);
    }

    exit(EXIT_SUCCESS);
}

I have tried putting the object declaration of my object as a global and static global, I have also tried doing a new/delete of my object.

The only way the call to the third party library will return is if my object is started from the parent process.

How can I create the daemon so that I don't have to call an external binary to run correctly?

Edit

I need to add that I have also tried to not kill the parent and I have the same problem.

Fred
  • 1,054
  • 1
  • 12
  • 32

1 Answers1

1

After many hours of digging I found the cause and solution of my problem.

Cause:

I had a private global static class object in the MyObject class that started a thread that called the third party library.

Because the class object was global it was created before the fork, even though I declared MyObject after the fork. As soon as the static class object was created it started a thread that called the third party library and in the library function it hit a mutex. When you fork threads are not copied, so after the fork the parent process was killed and the child process created a new static class object which started a new thread which called the library function and came to the same mutex. Because the mutex wasn't released by the parent because it was killed before leaving the library function, the child process was stuck waiting for the mutex to be released.

Solution:

Don't create threads on object creation and wait for child to create threads until after the fork.

Fred
  • 1,054
  • 1
  • 12
  • 32