mcm@rti.UUCP (Mike Mitchell) (11/16/89)
I have run into a problem with Mach 2.5. It is a problem that been in BSD 4.X until BSD 4.3-Tahoe. The fix is well understood for BSD type systems, but I'm not sure how it fits into the Mach kernel. The problem is that memory pages are not returned properly when using the 'brk()' library routine to free them. More specifically, the PTE entries are not invalidated properly when shrinking a region. I can supply some diffs to fix the problem for BSD systems, but I've never seen Mach source. Anyway, try running the enclosed program. Please tell me if it works on your machine, and if so, what version of Mach and the type of CPU. ------------------------------------------------------------------------- /* * This program shows off a problem with the kernel's "expand()" routine. */ #include <signal.h> main() { char *old_break, *cp; int i; extern char *sbrk(), *brk(); void segv(); signal(SIGSEGV, segv); i = getpagesize(); old_break = sbrk(0); /* get the current "break" */ (void) brk(old_break + 2*i); /* bump it up 2 pages */ cp = old_break + i + 256; *cp = 1; /* write into a new page */ (void) brk(old_break); /* release the memory */ *cp = 2; /* write into the page again. This */ /* time, you should get a sigsegv */ printf("Your brk routine is broken!\n"); exit(1); } void segv() { printf("Your brk routine works correctly.\n"); exit(0); } -------------------------------------------------------------------- -- Mike Mitchell {decvax,seismo,ihnp4,philabs}!mcnc!rti!mcm mcm@rti.rti.org "If you hear me talking on the wind, You've got to understand, We must remain perfect strangers" (919) 541-6098
Rick.Rashid@CS.CMU.EDU (11/16/89)
The bug you describe has always been in Mach kernels and certainly is in our current versions. We have tried as much as possible to imitate the behaviour of 4.3bsd and the code for brk() was written explicitly to do so. I didn't work on that particular routine myself, but in similar situations in other parts of the bsd compatibility code we have similarly opted to preserve the actual workings of 4.3bsd rather than make up a new definition of behaviour that might be more logical. In cases where we have occasionally tried to modify the actions of bsd functions to better approximate the man page definitions, we have often discovered that user or vendor programs depend on the "incorrect" bsd implementation. This is the reason for our caution in making "corrections". In any case, the impact of this particular bug is only to prevent the actual release of the memory, not the semantics of brk() as defined in the man pages. In Mach terms, brk() does a vm_allocate if it expands the memory but does not do a corresponding vm_deallocate if it contracts. Programs will still work as advertised unless the brk() was actually needed to free up backing store. If you want to do that and you don't want to add the vm_deallocate to your kernel sources, you should simply call vm_deallocate explicitly after your call to brk. -Rick
Rick.Rashid@CS.CMU.EDU (11/16/89)
I should also comment (since someone else certainly will) that the brk() call has been labeled as "defunct" in bsd kernels for some time. CMU's standard C libraries don't even allow it (although the trap remains for compatibility). -Rick