Click here to Skip to main content
15,897,187 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi,

Few month ago I had an interview and they asked me the following question:

"Find and fix the bug in `test.c', briefly explain how you found it and what the problem is. Describe the output you expect and the actual output. You'll need a POSIX system to be able to compile and run this code (on Windows, fork() behaves differently). If you don't have access to a POSIX system, just describe the expected output of the program."

I built and ran the program, but I could not find any problem on it. They were not satisfied with my answer. This question is bugging me for a while, since I still think the program is working properly

Here is the code

C++
/** @file test.c
 *
 * A small example of daemon code.  It forks off
 * a child process, while the parent exits immediately.
 *
 * @todo Close file descriptors in the child.
 */

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>


/** Parameters to be passed to the daemon. */
struct params {
   pid_t pid;
   unsigned sleeptime;
};

/** Functionality of the child process.
 *
 * This is the main function of the daemon.  Fill in the
 * daemon functionality in this function.
 *
 * Any parameters that have to be passed to the daemon
 * are collected in the params struct.
 */
void childfunc (struct params *params)
{
    sleep(params->sleeptime);
    printf("Child has stopped.\n");
}

int main (int argc, char* argv[])
{
    struct params params;

    printf("Parent started: ");
    params.sleeptime = 3;
    if ( (params.pid = fork()) < 0) {
        printf("fork failed: %m!\n");
        return 1;
    } else if (params.pid > 0) {
        printf("child forked with PID %d and will sleep for %u seconds.\n", params.pid, params.sleeptime);
    } else {
        childfunc(¶ms);
    }

    return 0;
}


Any help in advance will be very much appriciated

Thanks
Posted

I did not compile and run the program but I think the problem is indicated by the output. What is the output? From the code ist should be:
Parent started: child forked...
Parent started: Child has stopped.

The 'Parent started' indication of the second line is wrong. This is printed by the child. To fix this, remove the first printf() and prepend the started string to the fork messages. Optionally add a printf("Child has the started") before calling childfunc().
 
Share this answer
 
Comments
GiZmoDragonBack 21-Jul-13 2:57am    
This is clear one aspect of the problems that has this small example.
I'm regularly programming posix/linux systems but I'm definitely not a guru. Still I have a few tips regarding this interview question. The program itself doesn't have any serious bugs that would cause a crash or the end of the world, it has only one aesthetic and maybe one technical problem if we are talking about a daemon. I haven't compiled and tested your program but what I wouldn't expect a forked daemon process to print on the console the "Child has stopped." message. A daemon process never logs to the console and more importantly it should be completely detached from every terminals in your system.
The esthetic problem: When you start the program the parent process probably prints it stuff ("Parent started: hild forked with PID.....") to the console and then exists immediately. Since our shell program in the console waits for the parent process that terminates immediately the control returns to the console and the prompt is being printed to the screen by your shell like "duckfoot:/home/duckfoot$"). Since the child/"daemon" process hasn't yet stopped and hasn't been detached from the console and it has file descriptors (stdin/out/err) open to the console it prints its stuff to the console in parallel with other programs (your shell, or maybe another console program you start while the child is waiting for the 3 seconds to pass). A daemon process should never log to any console, it should log/print to something else (like /dev/null, a socket, a syslog server, a logfile, ...) and it should be detached from the console completely. What I know about daemon initialization and console detach is the following: You have to fork twice. You fork once to create your first child process. The child process should close all file handles especially those that are opened to the console/terminal (I have seen code that closes all handles from zero to getdtablesize()) and it should call setsid(). After this the child process forks to create the daemon process and then it terminates. The daemon process is correctly detached from the console and it doesn't have any inherited handles that reference any terminals. The first child process did it job so it can exit. In the original (first and parent) process you are waiting for the first child to prevent it from becoming a zombie. In the daemon process you can start by initializing/opening your own stdin(0), stdout(1) and stderr(2) handles for your stdio calls for example by pointing to /dev/null or to a file or socket or whatever.
 
Share this answer
 
v2
Comments
GiZmoDragonBack 21-Jul-13 2:49am    
After reading some information regarding zombie process, I thought that the problem might be related to that. However, I ran the program and there is no zombie process created.
The only stuff that I noticed is that the parent process does not verify which is the output of the child process. Maybe that the error that they were expecting to identify.
pasztorpisti 21-Jul-13 3:08am    
Your program can't create zombies as the parent process terminates immediately. Only a living process is able to create zombies by creating child processes without waiting for them with waitpid(). If the parent terminates then its children become orphaned and init becomes their parent. I think the problem was staying attached to the console and logging to it from the daemon process.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month


CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900