From aefa2697d705e316aa5255004e4b6a129e9afe2a Mon Sep 17 00:00:00 2001 From: Robert Morris Date: Wed, 19 Aug 2020 12:35:14 -0400 Subject: [PATCH] usertest for exec() out of memory recovery and fix a few exec() bugs --- kernel/exec.c | 4 +++- kernel/sysfile.c | 5 ++--- user/usertests.c | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/kernel/exec.c b/kernel/exec.c index 8a2d1dc..0e8762f 100644 --- a/kernel/exec.c +++ b/kernel/exec.c @@ -67,8 +67,10 @@ exec(char *path, char **argv) // Allocate two pages at the next page boundary. // Use the second as the user stack. 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; + sz = sz1; uvmclear(pagetable, sz-2*PGSIZE); sp = sz; stackbase = sp - PGSIZE; diff --git a/kernel/sysfile.c b/kernel/sysfile.c index 015c942..5dc453b 100644 --- a/kernel/sysfile.c +++ b/kernel/sysfile.c @@ -436,10 +436,9 @@ sys_exec(void) } argv[i] = kalloc(); if(argv[i] == 0) - panic("sys_exec kalloc"); - if(fetchstr(uarg, argv[i], PGSIZE) < 0){ goto bad; - } + if(fetchstr(uarg, argv[i], PGSIZE) < 0) + goto bad; } int ret = exec(path, argv); diff --git a/user/usertests.c b/user/usertests.c index cc88555..acdba0f 100644 --- a/user/usertests.c +++ b/user/usertests.c @@ -2452,6 +2452,42 @@ badarg(char *s) 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. // @@ -2520,6 +2556,7 @@ main(int argc, char *argv[]) void (*f)(char *); char *s; } tests[] = { + {execout, "execout"}, {copyin, "copyin"}, {copyout, "copyout"}, {copyinstr1, "copyinstr1"},