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