diff options
| author | Robert Morris <rtm@csail.mit.edu> | 2020-08-19 12:35:14 -0400 | 
|---|---|---|
| committer | Robert Morris <rtm@csail.mit.edu> | 2020-08-19 12:35:14 -0400 | 
| commit | aefa2697d705e316aa5255004e4b6a129e9afe2a (patch) | |
| tree | 6e6581500c59d692267bdc1980dcd21f123ee6fb | |
| parent | b33574df38f358ba2173caa92e8287b5b0cb9cff (diff) | |
| download | xv6-labs-aefa2697d705e316aa5255004e4b6a129e9afe2a.tar.gz xv6-labs-aefa2697d705e316aa5255004e4b6a129e9afe2a.tar.bz2 xv6-labs-aefa2697d705e316aa5255004e4b6a129e9afe2a.zip | |
usertest for exec() out of memory recovery
and fix a few exec() bugs
| -rw-r--r-- | kernel/exec.c | 4 | ||||
| -rw-r--r-- | kernel/sysfile.c | 5 | ||||
| -rw-r--r-- | 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"}, | 
