finding out where the text/bss sits

Tony Luck aegl at unisoft.UUCP
Tue Jan 15 04:24:28 AEST 1991


If you don't have "/proc", then this little program will tell you where
things are attached in your address space (its up to you to guess which
things are text, data, bss, stack etc. ... but you get some clues ... like
whether the area is read-only or read-write).

Usage is "checkaddr [ start [ end [ pagesize ] ] ] ... it defaults to
a start address of 0x0, an end address of 4 Gbyte, and a pagesize of 4 Kbyte.
With these parameters it will take a *LONG* time to run as it is a little
program ... so most of the 4Gbyte address space is empty, so it will take,
and catch and longjmp out of about a million bus errors. Some systems may
try to grow the stack to "fix" a bus error that is below the stack but
within the maximum process size limits ... on these systems this program
may take an exceptionally long time ... and a great deal of swapping/paging
may happen.

CAUTION! This program does nothing that's wrong, but bugs in some operating
systems have resulted in unwanted effects (machines have panic'ed or hung).
If you choose to run this, then you are on your own ... don't blame me if
bad things happen. Further disclaimer ... UniSoft Corp. doesn't even know
that I'm posting this ... so don't try to blame them either.


/*
 * Copyright (c) 1991 Tony Luck.
 * Do what you like with this ... except sell it ... and don't blame me
 * for anything that happens.
 *
 * Check accessibility of all pages in address space.
 *
 * Usage: checkaddr [ start [ end [ pagesize ] ] ]
 */
#include <stdio.h>
#include <signal.h>
#include <setjmp.h>

#define	INVALID		0
#define	READONLY	1
#define	READWRITE	2

static char	*name[] = {
	"invalid", "readonly", "read/write"
};

static jmp_buf	buf;

/*ARGSUSED*/
static void
trap(signum)
	int	signum;
{
	signal(SIGSEGV, trap);
	longjmp(buf, 1);
}

int
main(argc, argv)
	int	argc;
	char	**argv;
{
	unsigned long	start, addr, oldaddr, limit, pagesize;
	char	tmp;
	int	access_type, lastaccess = -1;

	signal(SIGSEGV, trap);
	if (argc > 1)
		sscanf(argv[1], "%x", &start);
	else
		start = 0;
	if (argc > 2)
		sscanf(argv[2], "%x", &limit);
	else
		limit = 0xffffffff;
	if (argc > 3)
		sscanf(argv[3], "%x", &pagesize);
	else
		pagesize = 0x1000;


	addr = start;
	while (addr < limit) {
		if (setjmp(buf) == 0) {
			tmp = *(char *)addr;
			if (setjmp(buf) == 0) {
				tmp = *(char *)addr;
				*(char *)addr = tmp;
				access_type = READWRITE;
			}
			else {
				access_type = READONLY;
			}
		}
		else {
			access_type = INVALID;
		}
		if (access_type != lastaccess) {
			if (addr > start)
				printf("[0x%.8x -> 0x%.8x]: %s\n", start,
					addr-1, name[lastaccess]);
			start = addr;
			lastaccess = access_type;
		}
		oldaddr = addr;
		addr += pagesize;
		if (addr < oldaddr)
			break; /* address wraparound */
	}
	printf("[0x%.8x -> 0x%.8x]: %s\n", start, addr-1, name[lastaccess]);

	return 0;
}



More information about the Comp.unix.internals mailing list