From d175beadf5f009d0fb8881e32c913b1bc175c9f6 Mon Sep 17 00:00:00 2001 From: Robert Morris Date: Mon, 23 Sep 2019 06:50:25 -0400 Subject: bug fix: reparent() sometimes deadlocked bug fix: exit() sometimes released a different parent lock than it acquired usertests --- user/usertests.c | 55 +++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 16 deletions(-) (limited to 'user') diff --git a/user/usertests.c b/user/usertests.c index fe3ae49..db9f680 100644 --- a/user/usertests.c +++ b/user/usertests.c @@ -598,6 +598,31 @@ forkforkfork(char *s) sleep(10); // one second } +// regression test. does reparent() violate the parent-then-child +// locking order when giving away a child to init, so that exit() +// deadlocks against init's wait()? also used to trigger a "panic: +// release" due to exit() releasing a different p->parent->lock than +// it acquired. +void +reparent2(char *s) +{ + for(int i = 0; i < 800; i++){ + int pid1 = fork(); + if(pid1 < 0){ + printf("fork failed\n"); + exit(1); + } + if(pid1 == 0){ + fork(); + fork(); + exit(0); + } + wait(0); + } + + exit(0); +} + // allocate all mem, free it, and allocate again void mem(char *s) @@ -1937,9 +1962,9 @@ stacktest(char *s) exit(xstatus); } -// copyin(), copyout(), and copyinstr() used to cast the virtual page -// address to uint, which (with certain wild system call arguments) -// resulted in a kernel page faults. +// regression test. copyin(), copyout(), and copyinstr() used to cast +// the virtual page address to uint, which (with certain wild system +// call arguments) resulted in a kernel page faults. void pgbug(char *s) { @@ -1952,9 +1977,9 @@ pgbug(char *s) exit(0); } -// does the kernel panic if a process sbrk()s its size to be less than -// a page, or zero, or reduces the break by an amount too small to -// cause a page to be freed? +// regression test. does the kernel panic if a process sbrk()s its +// size to be less than a page, or zero, or reduces the break by an +// amount too small to cause a page to be freed? void sbrkbugs(char *s) { @@ -2010,13 +2035,11 @@ sbrkbugs(char *s) exit(0); } -// does write() with an invalid buffer pointer cause -// a block to be allocated for a file that is then -// not freed when the file is deleted? if the kernel -// has this bug, it will panic: balloc: out of blocks. -// assumed_free may need to be raised to be -// more than the number of free blocks. -// this test takes a long time. +// regression test. does write() with an invalid buffer pointer cause +// a block to be allocated for a file that is then not freed when the +// file is deleted? if the kernel has this bug, it will panic: balloc: +// out of blocks. assumed_free may need to be raised to be more than +// the number of free blocks. this test takes a long time. void badwrite(char *s) { @@ -2049,9 +2072,8 @@ badwrite(char *s) exit(0); } -// test whether exec() leaks memory if one of the -// arguments is invalid. the test passes if -// the kernel doesn't panic. +// regression test. test whether exec() leaks memory if one of the +// arguments is invalid. the test passes if the kernel doesn't panic. void badarg(char *s) { @@ -2102,6 +2124,7 @@ main(int argc, char *argv[]) void (*f)(char *); char *s; } tests[] = { + {reparent2, "reparent2"}, {pgbug, "pgbug" }, {sbrkbugs, "sbrkbugs" }, // {badwrite, "badwrite" }, -- cgit v1.2.3