[comp.sys.sun] Dynamic unexec continued:

viktor@melon.princeton.edu (02/17/90)

The code below excersizes unexec in combination with malloc, All works
well except that malloc is unable to free data allocated in the previous
life.  This is quite natural.   Granted -Bstatic on the same code allows
such free() calls,  but I do not think that this is a very serious
limitation,  malloc seems to detect that the pointer is too "small" to
have been allocated by it,  and simply returns 0,  one just ends up using
more memory than in the static case.

/*
 *  unexec(...) deleted
 * I cannot yet send out the unexec() routine itself,  but I hope
 * I will be able to do so soon.
 */

main(argc,argv)
	char **argv;
{
  static char *a, *b;
  char *malloc() ;
  char buf[20] ;

  if (!initialized) {
    /* allocate, print B, init&print *b, free(b) */
    b=malloc(50);sprintf(buf,"%-8X\n",b);write(1,buf,9);strcpy(b,"Hello B\n");
    write(1,b,8);sprintf(buf,"%-8X\n",free(b));write(1,buf,9) ;

    /*  Alloc a, print a,*a,free(a)  should be old b,*b,1 */
    a=malloc(50);sprintf(buf,"%-8X\n",a);write(1,buf,9);write(1,a,8);
    /* init&print *a unexec() */
    strcpy(a,"Hello A\n");write(1,a,8);unexec("bar","foo",0,0,0) ;
  } else {
    /* fix Break, print *a, free(a) */
    brk(Brk);write(1,a,8);sprintf(buf,"%-8X\n",free(a));write(1,buf,9) ;

    /* Alloc b, hope for old a ... */
    b=malloc(50);sprintf(buf,"%-8X\n",b);write(1,buf,9);write(1,b,strlen(b)) ;
    sprintf(buf,"%-8X\n",strlen(b));write(1,buf,9);

    /* init&print, free b */
    strcpy(b,"Hello B\n");write(1,b,strlen(b));sprintf(buf,"%-8X\n",free(b)) ;
    write(1,buf,9) ;

    /*  Alloc a, print a,*a,free(a)  should be old b,*b,1 */
    a = malloc(50);sprintf(buf,"%-8X\n",a);write(1,buf,9);write(1,a,8) ;
    /* init& print *a */
    strcpy(a,"Hello A\n");write(1,a,8) ;
  }    
}

script started...
melon(21) cc -o foo foo.c
melon(22) ./foo
20524   
Hello B
1       
20524   
Hello B
Hello A
melon(23) ./bar
Hello A
0       
24528   
1       
Hello B
1       
24528   
Hello B
Hello A
melon(24) cc -Bstatic -o foo foo.c
melon(25) ./foo
2149C   
Hello B
1       
2149C   
Hello B
Hello A
melon(26) ./bar
Hello A
1       
2149C   
Hello A
8       
Hello B
1       
2149C   
Hello B
Hello A
melon(27) exit
melon(28) 
script done on Fri Feb 16 15:35:39 1990

The only difference between the static and dynamic runs was that freeing
the pre-unexec allocated pointer failed,  and malloc did not reallocate
the same data,  it did however continue to work.  I could write code to
check point malloc also,  but this  will need to rely too much on the
details of the internal implementation, since shared libraries come and
go,  and the whole point is to divorce programs from C-library internals,
this would be a bad idea.  In summary,  if you only grow memory,  or
ignore return values from free(),  unexec is easy,  an undump can be built
trivially from the code in my unexec.  If you really rely on freeing
pointers after checkpointing,  write your own malloc (get GNU malloc!) and
link it statically.

	Viktor Dukhovni <viktor@math.princeton.edu>	: ARPA
		<...!uunet!princeton!math!viktor>	: UUCP
	Fine Hall, Washington Rd., Princeton, NJ 08544  : US-Post
		+1-(609)-258-5792		 	: VOICE