From 0207e6b066192a25543ba83567311950b514344c Mon Sep 17 00:00:00 2001 From: Scott Haseley Date: Thu, 14 Apr 2016 17:47:54 -0400 Subject: [PATCH] More tests for ASST3.2 Added 2 new sbrktests, one to test a huge sbrk with only touch a few pages (shouldn't crash), and another to make sure pages are getting freed when the breakpoint moves down. Also, added a stacktest that checks that 4M stacks are supported and pages are allocated on-demand. --- test161/commands/vm.tc | 1 + test161/tests/vm/sbrktest.t | 6 +- test161/tests/vm/stacktest.t | 3 +- userland/testbin/sbrktest/sbrktest.c | 57 ++++++++++++++++ userland/testbin/stacktest/Makefile | 11 ++++ userland/testbin/stacktest/stacktest.c | 90 ++++++++++++++++++++++++++ 6 files changed, 165 insertions(+), 3 deletions(-) create mode 100644 userland/testbin/stacktest/Makefile create mode 100644 userland/testbin/stacktest/stacktest.c diff --git a/test161/commands/vm.tc b/test161/commands/vm.tc index 9cca46c..456764f 100644 --- a/test161/commands/vm.tc +++ b/test161/commands/vm.tc @@ -8,6 +8,7 @@ templates: - name: /testbin/parallelvm - name: /testbin/sbrktest - name: /testbin/sort + - name: /testbin/stacktest - name: /testbin/zero #Triples diff --git a/test161/tests/vm/sbrktest.t b/test161/tests/vm/sbrktest.t index 669397f..e39496d 100644 --- a/test161/tests/vm/sbrktest.t +++ b/test161/tests/vm/sbrktest.t @@ -6,7 +6,7 @@ description: > tags: [sbrk] depends: [not-dumbvm-vm, shell] sys161: - ram: 4M + ram: 2M --- khu $ /testbin/sbrktest 1 @@ -22,5 +22,7 @@ $ /testbin/sbrktest 12 $ /testbin/sbrktest 13 $ /testbin/sbrktest 14 $ /testbin/sbrktest 15 -$ /testbin/sbrktest 16 +$ /testbin/sbrktest 17 +$ /testbin/sbrktest 22 +$ /testbin/sbrktest 23 khu diff --git a/test161/tests/vm/stacktest.t b/test161/tests/vm/stacktest.t index 8cb8bae..55b2d58 100644 --- a/test161/tests/vm/stacktest.t +++ b/test161/tests/vm/stacktest.t @@ -5,6 +5,7 @@ description: > tags: [vm] depends: [not-dumbvm-vm, shell] sys161: - ram: 4M + ram: 2M --- $ /testbin/bigexec +$ /testbin/stacktest diff --git a/userland/testbin/sbrktest/sbrktest.c b/userland/testbin/sbrktest/sbrktest.c index 0327d56..da65a00 100644 --- a/userland/testbin/sbrktest/sbrktest.c +++ b/userland/testbin/sbrktest/sbrktest.c @@ -1125,6 +1125,61 @@ test21(void) stresstest(geti(), true); } +static +void +test22(void) +{ + int i; + void *p, *q; + int num = 10; + int num_pages = 5 * 1024; // 20MB + + p = dosbrk(num_pages * PAGE_SIZE); + q = dosbrk(0); + + if ((unsigned int)q - (unsigned int)p != (unsigned int)(num_pages*PAGE_SIZE)) { + errx(1, "Heap size not equal to expected size: p=0x%x q=0x%x", (unsigned int)p, (unsigned int)q); + } + + // Just touch the last 10 pages + for (i = 0; i < num; i++) { + markpage(p, num_pages-(i+1)); + } + + // Check the last 10 pages + for (i = 0; i < num; i++) { + if (checkpage(p, num_pages-(i+1), false)) { + errx(1, "FAILED: data corrupt"); + } + } + + success(TEST161_SUCCESS, SECRET, "/testbin/sbrktest"); +} + +static +void +test23(void) +{ + // Make sure sbrk is freeing memory. This allocates, in total, just over 4M + // of memory, but moves the heap breakpoint in such a way that only one page + // should ever be required. This test doesn't make much sense to run with + // more than 4M or with swap enabled. + void *start; + int num_pages = 1030; + int num; + + start = dosbrk(PAGE_SIZE); + + for (num = 1; num <= num_pages; num++) { + TEST161_LPROGRESS(num); + start = dosbrk(num*PAGE_SIZE); + markpagelight(start, num-1); + checkpagelight(start, num-1, true); + dosbrk(-(num*PAGE_SIZE)); + } + success(TEST161_SUCCESS, SECRET, "/testbin/sbrktest"); +} + //////////////////////////////////////////////////////////// // main @@ -1154,6 +1209,8 @@ static const struct { { 19, "Large stress test", test19 }, { 20, "Randomized large stress test", test20 }, { 21, "Large stress test with particular seed", test21 }, + { 22, "Large sbrk test", test22 }, + { 23, "Allocate 4MB in total, but free pages in between", test23 }, }; static const unsigned numtests = sizeof(tests) / sizeof(tests[0]); diff --git a/userland/testbin/stacktest/Makefile b/userland/testbin/stacktest/Makefile new file mode 100644 index 0000000..7a604dd --- /dev/null +++ b/userland/testbin/stacktest/Makefile @@ -0,0 +1,11 @@ +# Makefile for huge + +TOP=../../.. +.include "$(TOP)/mk/os161.config.mk" + +PROG=stacktest +SRCS=stacktest.c +BINDIR=/testbin + +.include "$(TOP)/mk/os161.prog.mk" + diff --git a/userland/testbin/stacktest/stacktest.c b/userland/testbin/stacktest/stacktest.c new file mode 100644 index 0000000..484ff0a --- /dev/null +++ b/userland/testbin/stacktest/stacktest.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009 + * The President and Fellows of Harvard College. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * stacktest.c + * + * Tests the VM system's stack by allocating a large array on the stack and + * accessing it in a sparse manner. In total, we allocate 4*200*4096 = 3.125M + * on the stack. However, we only touch 1/4 of it, meaning this test should + * run when with <=2M of memory if stack pages are allocated on demand. + * + * When the VM system assignment is done, your system should be able + * to run this successfully. + */ + +#include +#include +#include +#include +#include + +#define PageSize 4096 +#define NumPages 200 +#define Answer 4900 + +static int +stacktest1() +{ + int sparse[NumPages][PageSize]; + int i, j; + + for (i = 0; i < NumPages; i+=4) { + // This is a fresh stack frame, so it better be zeroed. Otherwise, + // the kernel is leaking information between processes. + for (j = 0; j < PageSize/4; j++) { + if (sparse[i][j] != 0) { + errx(1, "Your stack pages are leaking data!"); + } + } + sparse[i][0] = i; + } + + // We need to do something with the values so the compiler doesn't + // optimize this array away. + int total = 0; + for (i = 0; i < NumPages; i+=4) { + total += sparse[i][0]; + } + + return total; +} + +int +main(void) +{ + int total = stacktest1(); + if (total != Answer) { + errx(1, "Expected %d got %d\n", Answer, total); + } + + // Success is not crashing + success(TEST161_SUCCESS, SECRET, "/testbin/stacktest"); + return 0; +}