/*
 * Allocate, then fork, then free the allocated page in the child.
 */
static
void
test14(void)
{
	pid_t pid;
	void *p;

	tprintf("Allocating a page...\n");
	p = dosbrk(PAGE_SIZE);
	markpage(p, 0);
	if (checkpage(p, 0, false)) {
		errx(1, "FAILED: data corrupt before forking");
	}

	tprintf("Forking...\n");
	pid = dofork();
	if (pid == 0) {
		/* child */
		if (checkpage(p, 0, false)) {
			errx(1, "FAILED: data corrupt in child");
		}
		tprintf("Child freeing a page...\n");
		dosbrk(-PAGE_SIZE);
		exit(0);
	}
	dowait(pid);
	if (checkpage(p, 0, false)) {
		errx(1, "FAILED: data corrupt in parent after child ran");
	}
	tprintf("Passed sbrk test 14.\n");
	success(TEST161_SUCCESS, SECRET, "/testbin/sbrktest");
}
Exemple #2
0
/*
 * Allocate and then fork, in case fork doesn't preserve the heap.
 */
static
void
test13(void)
{
	pid_t pid;
	void *p;

	printf("Allocating a page...\n");
	p = dosbrk(PAGE_SIZE);
	markpage(p, 0);
	if (checkpage(p, 0, false)) {
		errx(1, "FAILED: data corrupt before forking");
	}

	printf("Forking...\n");
	pid = dofork();
	if (pid == 0) {
		/* child */
		if (checkpage(p, 0, false)) {
			errx(1, "FAILED: data corrupt in child");
		}
		exit(0);
	}
	if (checkpage(p, 0, false)) {
		errx(1, "FAILED: data corrupt in parent");
	}
	dowait(pid);
	printf("Passed sbrk test 13.\n");
}
/*
 * Fork and then allocate in both the parent and the child, in case
 * fork messes up the heap. Note: this is not intended to test the
 * parent and child running concurrently -- that should probably be
 * its own test program.
 */
static
void
test12(void)
{
	pid_t pid;
	void *p;

	tprintf("Forking...\n");
	pid = dofork();
	if (pid == 0) {
		/* child */
		say("Child allocating a page...\n");
		p = dosbrk(PAGE_SIZE);
		markpage(p, 0);
		if (checkpage(p, 0, false)) {
			errx(1, "FAILED: data corrupt in child");
		}
		say("Child done.\n");
		exit(0);
	}
	/* parent */
	say("Parent allocating a page...\n");
	p = dosbrk(PAGE_SIZE);
	markpage(p, 0);
	if (checkpage(p, 0, false)) {
		errx(1, "FAILED: data corrupt in parent");
	}
	say("Parent done.\n");
	dowait(pid);
	tprintf("Passed sbrk test 12.\n");
	success(TEST161_SUCCESS, SECRET, "/testbin/sbrktest");
}
Exemple #4
0
main()
{
   checkpage(0,0x404);
   checkpage(10,0x405);
   ozputs(0,20,"Fill?");
   if(ozgetch()!='y') return;
   fillpage(0x404);
   fillpage(0x405);
   return;
}
Exemple #5
0
/*
 * Allocate six pages, check that they hold data and that the pages
 * don't get mixed up, and free them one at a time, repeating the
 * check after each free.
 */
static
void
test4(void)
{
	const unsigned num = 6;

	void *op, *p, *q;
	unsigned i, j;
	bool bad;

	op = dosbrk(0);

	printf("Allocating %u pages...\n", num);
	p = dosbrk(PAGE_SIZE * num);
	if (p != op) {
		errx(1, "FAILED: sbrk grow didn't return the old break "
		     "(got %p, expected %p", p, op);
	}

	bad = false;
	for (i=0; i<num; i++) {
		markpage(p, i);
		if (checkpage(p, i, false)) {
			warnx("FAILED: data corrupt on page %u", i);
			bad = true;
		}
	}
	if (bad) {
		exit(1);
	}

	printf("Freeing the pages one at a time...\n");
	for (i=num; i-- > 0; ) {
		(void)dosbrk(-PAGE_SIZE);
		for (j=0; j<i; j++) {
			if (checkpage(p, j, false)) {
				warnx("FAILED: data corrupt on page %u "
				      "after freeing %u pages", j, i);
				bad = true;
			}
		}
	}
	if (bad) {
		exit(1);
	}

	q = dosbrk(0);
	if (q != op) {
		errx(1, "FAILED: sbrk shrink didn't restore the heap "
		     "(got %p, expected %p", q, op);
	}

	printf("Passed sbrk test 4.\n");
}
/*
 * Allocate one page, check that it holds data, and free it.
 */
static
void
test2(void)
{
	void *op, *p, *q;

	op = dosbrk(0);

	tprintf("Allocating a page...\n");
	p = dosbrk(PAGE_SIZE);
	if (p != op) {
		errx(1, "FAILED: sbrk grow didn't return the old break "
		    "(got %p, expected %p", p, op);
	}
	markpage(p, 0);
	if (checkpage(p, 0, false)) {
		errx(1, "FAILED: data corrupt");
	}

	p = dosbrk(0);

	tprintf("Freeing the page...\n");
	q = dosbrk(-PAGE_SIZE);
	if (q != p) {
		errx(1, "FAILED: sbrk shrink didn't return the old break "
		     "(got %p, expected %p", q, p);
	}
	q = dosbrk(0);
	if (q != op) {
		errx(1, "FAILED: sbrk shrink didn't restore the heap "
		     "(got %p, expected %p", q, op);
	}
	success(TEST161_SUCCESS, SECRET, "/testbin/sbrktest");
}
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");
}
/*
 * Allocate one page, check that it holds data, and leak it.
 */
static
void
test1(void)
{
	void *p;

	tprintf("Allocating a page...\n");
	p = dosbrk(PAGE_SIZE);
	markpage(p, 0);
	if (checkpage(p, 0, false)) {
		errx(1, "FAILED: data corrupt");
	}
	success(TEST161_SUCCESS, SECRET, "/testbin/sbrktest");
}
Exemple #9
0
/*
 * Allocate one page, check that it holds data, and leak it.
 */
static
void
test1(void)
{
	void *p;

	printf("Allocating a page...\n");
	p = dosbrk(PAGE_SIZE);
	markpage(p, 0);
	if (checkpage(p, 0, false)) {
		errx(1, "FAILED: data corrupt");
	}

	printf("Passed sbrk test 1.\n");
}
/*
 * Allocate all of memory one page at a time. The same restrictions
 * and considerations apply as above.
 */
static
void
test10(void)
{
	void *p, *op;
	unsigned i, n;
	bool bad;

	tprintf("Allocating all of memory one page at a time:\n");
	op = dosbrk(0);
	n = 0;
	while ((p = sbrk(PAGE_SIZE)) != (void *)-1) {
		markpagelight(op, n);
		n++;
	}
	tprintf("Got %u pages (%zu bytes).\n", n, (size_t)PAGE_SIZE * n);

	tprintf("Now freeing them.\n");
	bad = false;
	for (i=0; i<n; i++) {
		if (checkpagelight(op, n - i - 1, false)) {
			warnx("FAILED: data corrupt on page %u", i);
			bad = true;
		}
		(void)dosbrk(-PAGE_SIZE);
	}
	if (bad) {
		exit(1);
	}
	tprintf("Freed %u pages.\n", n);

	p = dosbrk(0);
	if (p != op) {
		errx(1, "FAILURE: break did not return to original value");
	}

	tprintf("Now let's see if I can allocate another page.\n");
	p = dosbrk(PAGE_SIZE);
	markpage(p, 0);
	if (checkpage(p, 0, false)) {
		errx(1, "FAILED: data corrupt");
	}
	(void)dosbrk(-PAGE_SIZE);

	tprintf("Passed sbrk test 10.\n");
	success(TEST161_SUCCESS, SECRET, "/testbin/sbrktest");
}
/*
 * Allocate six pages, check that they hold data and that the
 * pages don't get mixed up, and free them.
 */
static
void
test3(void)
{
	const unsigned num = 6;

	void *op, *p, *q;
	unsigned i;
	bool bad;

	op = dosbrk(0);

	tprintf("Allocating %u pages...\n", num);
	p = dosbrk(PAGE_SIZE * num);
	if (p != op) {
		errx(1, "FAILED: sbrk grow didn't return the old break "
		     "(got %p, expected %p", p, op);
	}

	bad = false;
	for (i=0; i<num; i++) {
		markpage(p, i);
		if (checkpage(p, i, false)) {
			warnx("FAILED: data corrupt on page %u", i);
			bad = true;
		}
	}
	if (bad) {
		exit(1);
	}

	p = dosbrk(0);

	tprintf("Freeing the pages...\n");
	q = dosbrk(-PAGE_SIZE * num);
	if (q != p) {
		errx(1, "FAILED: sbrk shrink didn't return the old break "
		     "(got %p, expected %p", q, p);
	}
	q = dosbrk(0);
	if (q != op) {
		errx(1, "FAILED: sbrk shrink didn't restore the heap "
		     "(got %p, expected %p", q, op);
	}
	success(TEST161_SUCCESS, SECRET, "/testbin/sbrktest");
}
/*
 * Allocate and free in both the parent and the child, and do more
 * than one page.
 */
static
void
test15(void)
{
	unsigned num = 12;

	pid_t pid;
	unsigned i;
	void *p;

	tprintf("Allocating %u pages...\n", num);
	p = dosbrk(PAGE_SIZE * num);
	for (i=0; i<num; i++) {
		markpage(p, i);
	}
	for (i=0; i<num; i++) {
		if (checkpage(p, i, false)) {
			errx(1, "FAILED: data corrupt before forking");
		}
	}

	tprintf("Freeing one page...\n");
	(void)dosbrk(-PAGE_SIZE);
	num--;
	for (i=0; i<num; i++) {
		if (checkpage(p, i, false)) {
			errx(1, "FAILED: data corrupt before forking (2)");
		}
	}

	tprintf("Allocating two pages...\n");
	(void)dosbrk(PAGE_SIZE * 2);
	markpage(p, num++);
	markpage(p, num++);
	for (i=0; i<num; i++) {
		if (checkpage(p, i, false)) {
			errx(1, "FAILED: data corrupt before forking (3)");
		}
	}

	tprintf("Forking...\n");
	pid = dofork();
	if (pid == 0) {
		/* child */
		for (i=0; i<num; i++) {
			if (checkpage(p, i, false)) {
				errx(1, "FAILED: data corrupt in child");
			}
		}

		say("Child: freeing three pages\n");
		dosbrk(-PAGE_SIZE * 3);
		num -= 3;
		for (i=0; i<num; i++) {
			if (checkpage(p, i, false)) {
				errx(1, "FAILED: data corrupt in child (2)");
			}
		}

		say("Child: allocating two pages\n");
		dosbrk(PAGE_SIZE * 2);
		markpage(p, num++);
		markpage(p, num++);
		for (i=0; i<num; i++) {
			if (checkpage(p, i, false)) {
				errx(1, "FAILED: data corrupt in child (3)");
			}
		}

		say("Child: freeing all\n");
		dosbrk(-PAGE_SIZE * num);
		exit(0);
	}
	say("Parent: allocating four pages\n");
	dosbrk(PAGE_SIZE * 4);
	for (i=0; i<4; i++) {
		markpage(p, num++);
	}
	for (i=0; i<num; i++) {
		if (checkpage(p, i, false)) {
			errx(1, "FAILED: data corrupt in parent");
		}
	}

	say("Parent: waiting\n");
	dowait(pid);

	for (i=0; i<num; i++) {
		if (checkpage(p, i, false)) {
			errx(1, "FAILED: data corrupt after waiting");
		}
	}

	(void)dosbrk(-PAGE_SIZE * num);
	tprintf("Passed sbrk test 15.\n");
	success(TEST161_SUCCESS, SECRET, "/testbin/sbrktest");

}
Exemple #13
0
int
main(int ac, char **av)
{
    const char *corefile = NULL;
    const char *sysfile = NULL;
    vm_page_t mptr;
    struct vm_page m;
    struct vm_object obj;
    kvm_t *kd;
    int ch;
    int hv;
    int i;
    const char *qstr;
    const char *ostr;

    while ((ch = getopt(ac, av, "M:N:dv")) != -1) {
	switch(ch) {
	case 'd':
	    ++debugopt;
	    break;
	case 'v':
	    ++verboseopt;
	    break;
	case 'M':
	    corefile = optarg;
	    break;
	case 'N':
	    sysfile = optarg;
	    break;
	default:
	    fprintf(stderr, "%s [-M core] [-N system]\n", av[0]);
	    exit(1);
	}
    }
    ac -= optind;
    av += optind;

    if ((kd = kvm_open(sysfile, corefile, NULL, O_RDONLY, "kvm:")) == NULL) {
	perror("kvm_open");
	exit(1);
    }
    if (kvm_nlist(kd, Nl) != 0) {
	perror("kvm_nlist");
	exit(1);
    }

#if 0
    kkread(kd, Nl[0].n_value, &vm_page_buckets, sizeof(vm_page_buckets));
    kkread(kd, Nl[1].n_value, &vm_page_hash_mask, sizeof(vm_page_hash_mask));
#endif
    kkread(kd, Nl[0].n_value, &vm_page_array, sizeof(vm_page_array));
    kkread(kd, Nl[1].n_value, &vm_page_array_size, sizeof(vm_page_array_size));

    /*
     * Scan the vm_page_array validating all pages with associated objects
     */
    for (i = 0; i < vm_page_array_size; ++i) {
	if (debugopt) {
	    printf("page %d\r", i);
	    fflush(stdout);
	}
	kkread(kd, (u_long)&vm_page_array[i], &m, sizeof(m));
	if (m.object) {
	    kkread(kd, (u_long)m.object, &obj, sizeof(obj));
	    checkpage(kd, &vm_page_array[i], &m, &obj);
	}
	if (verboseopt) {
	    if (m.queue >= PQ_HOLD) {
		qstr = "HOLD";
	    } else if (m.queue >= PQ_CACHE) {
		qstr = "CACHE";
	    } else if (m.queue >= PQ_ACTIVE) {
		qstr = "ACTIVE";
	    } else if (m.queue >= PQ_INACTIVE) {
		qstr = "INACTIVE";
	    } else if (m.queue >= PQ_FREE) {
		qstr = "FREE";
	    } else {
		qstr = "NONE";
	    } 
	    printf("page %p obj %p/%-8jd val=%02x dty=%02x hold=%d "
		   "wire=%-2d act=%-3d busy=%d %8s",
		&vm_page_array[i],
		m.object,
		(intmax_t)m.pindex,
		m.valid,
		m.dirty,
		m.hold_count,
		m.wire_count,
		m.act_count,
		m.busy,
		qstr
	    );
	    switch(obj.type) {
	    case OBJT_DEFAULT:
		ostr = "default";
		break;
	    case OBJT_SWAP:
		ostr = "swap";
		break;
	    case OBJT_VNODE:
		ostr = "vnode";
		break;
	    case OBJT_DEVICE:
		ostr = "device";
		break;
	    case OBJT_PHYS:
		ostr = "phys";
		break;
	    case OBJT_DEAD:
		ostr = "dead";
		break;
	    default:
		ostr = "unknown";
		break;
	    }
	    printf(" %-7s", ostr);
	    if (m.flags & PG_BUSY)
		printf(" BUSY");
	    if (m.flags & PG_WANTED)
		printf(" WANTED");
	    if (m.flags & PG_WINATCFLS)
		printf(" WINATCFLS");
	    if (m.flags & PG_FICTITIOUS)
		printf(" FICTITIOUS");
	    if (m.flags & PG_WRITEABLE)
		printf(" WRITEABLE");
	    if (m.flags & PG_MAPPED)
		printf(" MAPPED");
	    if (m.flags & PG_ZERO)
		printf(" ZERO");
	    if (m.flags & PG_REFERENCED)
		printf(" REFERENCED");
	    if (m.flags & PG_CLEANCHK)
		printf(" CLEANCHK");
	    if (m.flags & PG_SWAPINPROG)
		printf(" SWAPINPROG");
	    if (m.flags & PG_NOSYNC)
		printf(" NOSYNC");
	    if (m.flags & PG_UNMANAGED)
		printf(" UNMANAGED");
	    if (m.flags & PG_MARKER)
		printf(" MARKER");
	    if (m.flags & PG_RAM)
		printf(" RAM");
	    if (m.flags & PG_SWAPPED)
		printf(" SWAPPED");
	    printf("\n");
	}
    }
    if (debugopt || verboseopt)
	printf("\n");

#if 0
    /*
     * Scan the vm_page_buckets array validating all pages found
     */
    for (i = 0; i <= vm_page_hash_mask; ++i) {
	if (debugopt) {
	    printf("index %d\r", i);
	    fflush(stdout);
	}
	kkread(kd, (u_long)&vm_page_buckets[i], &mptr, sizeof(mptr));
	while (mptr) {
	    kkread(kd, (u_long)mptr, &m, sizeof(m));
	    if (m.object) {
		kkread(kd, (u_long)m.object, &obj, sizeof(obj));
		hv = ((uintptr_t)m.object + m.pindex) ^ obj.hash_rand;
		hv &= vm_page_hash_mask;
		if (i != hv)
		    printf("vm_page_buckets[%d] ((struct vm_page *)%p)"
			" should be in bucket %d\n", i, mptr, hv);
		checkpage(kd, mptr, &m, &obj);
	    } else {
		printf("vm_page_buckets[%d] ((struct vm_page *)%p)"
			" has no object\n", i, mptr);
	    }
	    mptr = m.hnext;
	}
    }
#endif
    if (debugopt)
	printf("\n");
    return(0);
}