Re: forking heap question



Havoc Pennington wrote:
> 
> Edscott Wilson García <edscott imp mx> writes:
> >
> >   I was getting random "io X error" after forking and the child was
> > not using any GTK, nor was it using exit() in stead of _exit(). I
> > finally tracked down the problem to the child using malloc() and
> > free(), and overwriting the GTK widget information in the parent
> > process. By using stack memory the problem is gone. Is this
> > possible? Should the use of heap memory be avoided at all costs when
> > using gtk with fork()?
> 
> I don't think it's possible. There should be no relation between
> parent and child address spaces.
> 
> Havoc

Neither do I think it's possible. Yet, it is so. Maybe a failed malloc()
or free() makes the child access a gtk widget it's not supposed to, via
some globally defined variable. This is the offending code executed by
the child (the complete file is xtree_cpy.c from program xftree of the
xfce desktop environment with CVS at sourceforge.net):

The recursive call makes the parent fail quickly. The non recursive call
also makes it
fail, as long as the child executes it the subroutined enough number of
times. 


static gboolean SubChildTransfer(char *target,char *source){
        struct stat s_stat,t_stat;
        int i,rc;
        if (stat(target,&t_stat)<0){  /* follow link stat() */
                char *route,*end;
                route=(char *)malloc(strlen(target+1));
                if (route) {
                  strcpy(route,target);
                  end=strrchr(route,'/');
                  if (end==route) end[1]=0; /* root directory */
                  else end[0]=0;
                  stat(route,&t_stat);
                  free(route);
                }
        }
        lstat(source,&s_stat); /* stat() the link itself */
        
        /* recursivity, if src is directory:
         * 1- mkdir tgt/src
         * 2- glob src
         * 3 foreach glob in globlist recall function.
         * */

        if (S_ISDIR(s_stat.st_mode)) { /* directories fall in here,
going
recursive */
                glob_t dirlist;
                char *globstring,*newtarget,*src;
                
                
                globstring = (char *)malloc(strlen(source)+3);
                if (!globstring) return FALSE;
                sprintf(globstring,"%s/*",source);
                /* create target dir */
                if (mkdir(target,(s_stat.st_mode|0700))<0){
                        fprintf(stdout,"child:%s
%s\n",strerror(errno),target);
                        return FALSE;
                }
                /*fprintf(stderr,"dbg:dir created: %s\n",target);*/
                /* glob source dir */
                if (glob (globstring, GLOB_ERR | GLOB_TILDE, NULL,
&dirlist)
!= 0) {
                  /*fprintf (stderr, "dbg:%s: no match\n",
globstring);*/
                        return TRUE;
                }
                else for (i = 0; i < dirlist.gl_pathc; i++) {
                  if (strstr(dirlist.gl_pathv[i],"/"))
src=strrchr(dirlist.gl_pathv[i],'/')+1;
                  else src = dirlist.gl_pathv[i];
                  newtarget=(char
*)malloc(strlen(target)+strlen(src)+3);
                  if (!newtarget) {
                          free(globstring);
                          return FALSE;
                  }
                  sprintf(newtarget,"%s/%s",target,src);
                  /*fprintf(stderr,"dbg:dirlist:
%s\n",dirlist.gl_pathv[i]);*/
                  if (!SubChildTransfer(newtarget,dirlist.gl_pathv[i])){
                        /*fprintf(stderr,"dbg:dirlisterror:
%s\n",dirlist.gl_pathv[i]);*/
                        free(globstring);
                        free(newtarget);
                        return FALSE;
                  }
                  free(newtarget);
                }
                free(globstring);
                
                /* remove old directory */
                if ((child_mode & TR_MOVE) && (rmdir(source)<0)){
                        process_error(RW_ERROR_WRITING_TGT);
                        return FALSE;
                }
                return TRUE;            
        }
... more code here that doesn't affect the appearance of the bug ...
        return TRUE;

}


-- 

saludos,

Edscott



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]