usertest for exec() out of memory recovery

and fix a few exec() bugs
This commit is contained in:
Robert Morris 2020-08-19 12:35:14 -04:00 committed by Frans Kaashoek
parent d4d487731a
commit 5860dcd07d
3 changed files with 42 additions and 4 deletions

View file

@ -67,8 +67,10 @@ exec(char *path, char **argv)
// Allocate two pages at the next page boundary. // Allocate two pages at the next page boundary.
// Use the second as the user stack. // Use the second as the user stack.
sz = PGROUNDUP(sz); sz = PGROUNDUP(sz);
if((sz = uvmalloc(pagetable, sz, sz + 2*PGSIZE)) == 0) uint64 sz1;
if((sz1 = uvmalloc(pagetable, sz, sz + 2*PGSIZE)) == 0)
goto bad; goto bad;
sz = sz1;
uvmclear(pagetable, sz-2*PGSIZE); uvmclear(pagetable, sz-2*PGSIZE);
sp = sz; sp = sz;
stackbase = sp - PGSIZE; stackbase = sp - PGSIZE;

View file

@ -436,10 +436,9 @@ sys_exec(void)
} }
argv[i] = kalloc(); argv[i] = kalloc();
if(argv[i] == 0) if(argv[i] == 0)
panic("sys_exec kalloc");
if(fetchstr(uarg, argv[i], PGSIZE) < 0){
goto bad; goto bad;
} if(fetchstr(uarg, argv[i], PGSIZE) < 0)
goto bad;
} }
int ret = exec(path, argv); int ret = exec(path, argv);

View file

@ -2452,6 +2452,42 @@ badarg(char *s)
exit(0); exit(0);
} }
// test the exec() code that cleans up if it runs out
// of memory. it's really a test that such a condition
// doesn't cause a panic.
void
execout(char *s)
{
for(int avail = 0; avail < 15; avail++){
int pid = fork();
if(pid < 0){
printf("fork failed\n");
exit(1);
} else if(pid == 0){
// allocate all of memory.
while(1){
uint64 a = (uint64) sbrk(4096);
if(a == 0xffffffffffffffffLL)
break;
}
// free a few pages, in order to let exec() make some
// progress.
for(int i = 0; i < avail; i++)
sbrk(-4096);
close(1);
char *args[] = { "echo", "x", 0 };
exec("echo", args);
exit(0);
} else {
wait((int*)0);
}
}
exit(0);
}
// //
// use sbrk() to count how many free physical memory pages there are. // use sbrk() to count how many free physical memory pages there are.
// //
@ -2520,6 +2556,7 @@ main(int argc, char *argv[])
void (*f)(char *); void (*f)(char *);
char *s; char *s;
} tests[] = { } tests[] = {
{execout, "execout"},
{copyin, "copyin"}, {copyin, "copyin"},
{copyout, "copyout"}, {copyout, "copyout"},
{copyinstr1, "copyinstr1"}, {copyinstr1, "copyinstr1"},