don't panic if a program frees all its memory with sbrk().
if a program sbrk()'s to a non-page-boundary, don't free that page. corresponding usertests.
This commit is contained in:
parent
ca30cac702
commit
4de161f973
|
@ -232,9 +232,7 @@ growproc(int n)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else if(n < 0){
|
} else if(n < 0){
|
||||||
if((sz = uvmdealloc(p->pagetable, sz, sz + n)) == 0) {
|
sz = uvmdealloc(p->pagetable, sz, sz + n);
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
p->sz = sz;
|
p->sz = sz;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -268,7 +268,10 @@ uvmdealloc(pagetable_t pagetable, uint64 oldsz, uint64 newsz)
|
||||||
{
|
{
|
||||||
if(newsz >= oldsz)
|
if(newsz >= oldsz)
|
||||||
return oldsz;
|
return oldsz;
|
||||||
uvmunmap(pagetable, newsz, oldsz - newsz, 1);
|
|
||||||
|
uint64 newup = PGROUNDUP(newsz);
|
||||||
|
uvmunmap(pagetable, newup, oldsz - newup, 1);
|
||||||
|
|
||||||
return newsz;
|
return newsz;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1923,6 +1923,45 @@ pgbug(char *s)
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// does the kernel panic if a process sbrk()s its size to be less than
|
||||||
|
// a page, or zero?
|
||||||
|
void
|
||||||
|
zerosize(char *s)
|
||||||
|
{
|
||||||
|
int pid = fork();
|
||||||
|
if(pid < 0){
|
||||||
|
printf("fork failed\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if(pid == 0){
|
||||||
|
int sz = (uint64) sbrk(0);
|
||||||
|
// free all user memory; there used to be a bug that
|
||||||
|
// would not adjust p->sz correctly in this case,
|
||||||
|
// causing exit() to panic.
|
||||||
|
sbrk(-sz);
|
||||||
|
// user page fault here.
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
wait(0);
|
||||||
|
|
||||||
|
pid = fork();
|
||||||
|
if(pid < 0){
|
||||||
|
printf("fork failed\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if(pid == 0){
|
||||||
|
int sz = (uint64) sbrk(0);
|
||||||
|
// set the break to somewhere in the very first
|
||||||
|
// page; there used to be a bug that would incorrectly
|
||||||
|
// free the first page.
|
||||||
|
sbrk(-(sz - 3500));
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
wait(0);
|
||||||
|
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
// run each test in its own process. run returns 1 if child's exit()
|
// run each test in its own process. run returns 1 if child's exit()
|
||||||
// indicates success.
|
// indicates success.
|
||||||
int
|
int
|
||||||
|
@ -1961,6 +2000,7 @@ main(int argc, char *argv[])
|
||||||
char *s;
|
char *s;
|
||||||
} tests[] = {
|
} tests[] = {
|
||||||
{pgbug, "pgbug" },
|
{pgbug, "pgbug" },
|
||||||
|
{zerosize, "zerosize" },
|
||||||
{reparent, "reparent" },
|
{reparent, "reparent" },
|
||||||
{twochildren, "twochildren"},
|
{twochildren, "twochildren"},
|
||||||
{forkfork, "forkfork"},
|
{forkfork, "forkfork"},
|
||||||
|
|
Loading…
Reference in a new issue