Hi guys,
For some reason my application is doing a seg fault when I tell the parent to wait for the child to be done with the process.
Here is the output:
andorian 73% pr5 -a 3 -s 10 -c 1
child_alarm_time = 3
child_processes = 1
child_sleep_time = 10
Installed SIGALRM, SIGINIT,SIGCHLD signals
18740: Tue Oct 14 02:57:45 2008 alarm signal received
18740: Tue Oct 14 02:57:48 2008 alarm signal received
18740: Tue Oct 14 02:57:51 2008 alarm signal received
18740: Tue Oct 14 02:57:52 2008 here is child 0
18740: Tue Oct 14 02:57:52 2008 Killing this child process. 0
18739: Tue Oct 14 02:57:52 2008 child signal received - ignored
Segmentation fault
I also get the seg fault if I do the following:
pr5 -c 1
pr5 -c 2
Here is my code
Code:static void Sleep(int alarm_time_interval, int total_sleep_time) { int remaining_sleep_time = total_sleep_time; while (remaining_sleep_time > 0) { if (alarm_time_interval > 0) { alarm(alarm_time_interval); } remaining_sleep_time = sleep(remaining_sleep_time); } } /*----------------------------------------------------------------------------*/ /* The functions in this section are intended to demonstrate various usages and * properties of signals and signal handlers. They should be removed or modified * in the final version of the program. */ static void generic_signal_handler(int sig) { print_message_1("generic_signal_handler, signal", sig); } static void SIGALRM_handler(int sig) { if (sig == SIGALRM) { print_message("alarm signal received"); } else { print_message_1("serious error: SIGALRM_handler, received signal", sig); } } static void SIGINT_handler(int sig) { if (sig == SIGINT) { print_message("interrupt signal received - ignored"); } else { print_message_1("serious error: SIGINT_handler, received signal", sig); } } static void SIGCHLD_hanlder(int sig) { if(sig == SIGCHLD) { print_message("child signal received - ignored"); } else { print_message_1("serious error: SIGCHLD_handler, received signal", sig); } } #ifndef NSIG #define NSIG 64 #endif static int generic_signal_handler_installed[NSIG]; /* signal 0 is reserved * the default handlers for SIGKILL and SIGSTOP cannot be replaced */ /* try to replace every default signal handler */ static void signal_setup(void) { /* int i, ret; for (i = 0; i < NSIG; i++) { ret = install_signal_handler(i, generic_signal_handler); generic_signal_handler_installed[i] = (ret == 0); }*/ printf("Installed SIGALRM, SIGINIT,SIGCHLD signals\n"); //just set up these 3 signal handlers install_signal_handler(SIGALRM, SIGALRM_handler); install_signal_handler(SIGINT, SIGINT_handler); install_signal_handler(SIGCHLD,SIGCHLD_hanlder); } /*----------------------------------------------------------------------------*/ int main(int argc, char *argv[]) { //set up the signal handlers signal_setup(); //check to see if no arguments were passed, if there weren't then don't //create any children //fork children based on what is passed through the command line pid_t child_pid; //holds an array of the child processes so the parent can wait for them. pid_t child_array[MAX_CHILDREN]; int CHILD_STAT; //print_process_table("Table before forking."); //creating processes for(int i =0; i < child_processes; i++) { child_pid = fork(); child_array[i] = child_pid; if(child_pid == (pid_t)(-1)) { //this is the parent process. The fork failed, and there is no child print_message_error("fork()", strerror(errno)); exit(EXIT_FAILURE); } else if(child_pid == 0) { //this is a child process. The fork worked //checking to see if alarm/sleep flags were set if(a_flag || s_flag) { Sleep(child_alarm_time,child_sleep_time); } print_message_1("here is child ",i); print_message_1("Killing this child process.",i); exit(child_exit_status); } else { //print_message("here is the parent, all children created."); //if this flag is set, then set the parent alarm/sleep if(b_flag || t_flag) { //set alarm //printf("set the alarm: %d set sleep: %d for the process: %d\n",parent_alarm_time,parent_sleep_time,getpid()); Sleep(parent_alarm_time,parent_sleep_time); } //this is a parent process. The fork worked //add more code but do not exit yet //Wait for the child process to be done wait_child(child_pid,CHILD_STAT); //update the process table //printf("added child process %d\n", child_pid); insert_process_table(child_pid); //print_process_table("Table after inserting the process in parent."); //print_process_table("Parent calling this again"); } } //tried this didn't work /*for(int i = 0; i < child_processes; i++) { wait_child(child_array[i],CHILD_STAT); }*/ print_message("here is the parent, all children created"); if(b_flag || t_flag) { //set alarm //printf("set the alarm: %d set sleep: %d for the process: %d",parent_alarm_time,parent_sleep_time,getpid()); Sleep(parent_alarm_time,parent_sleep_time); } return EXIT_SUCCESS;
So basically I'm getting this when I try to create a 1 or more child processes and I tell the parent to wait for the child to be done, so the wait_child is where the error has to be at and I"m not sure why.
My guess is that I'm killing the process and then asking it to wait for a dead process?
Here is what the child_wait process looks like:
Code:#include <errno.h> /* for waitpid(2) and wait(2) */ #include <sys/types.h> #include <sys/wait.h> #include "pr5_wait.h" /*----------------------------------------------------------------------------*/ /* wait for a child process whose pid you know * * return 1 if a child was found * *child_status has been updated, and the child has terminated * * return 0 if no child was found * *child_status has not been updated */ int wait_child(pid_t wait_pid, int *child_status) { int s; /* loop because waitpid() can be interrupted by a signal and return early */ while (waitpid(wait_pid, &s, 0) == (pid_t)(-1)) { if (errno == ECHILD) /* no more children */ { return 0; } } *child_status = s; return 1; } /*----------------------------------------------------------------------------*/ /* wait for a child process whose pid you do not know * if more than one child has terminated, report only one * * return 1 if a child was found * *wait_pid and *child_status have been updated, and the child has terminated * * return 0 if no child was found * *wait_pid and *child_status have not been updated */ int wait_any_child(pid_t *wait_pid, int *child_status) { pid_t w; int s; /* loop because wait() can be interrupted by a signal and return early */ while ((w = wait(&s)) == (pid_t)(-1)) { if (errno == ECHILD) /* no more children */ { return 0; } } *wait_pid = w; *child_status = s; return 1; } /*----------------------------------------------------------------------------*/
That code is correct, I"m just using it wrong I think.
Any help would be great.



LinkBack URL
About LinkBacks


