Subject: Why SIGBUS vs. SIGSEGV?
To: None <current-users@NetBSD.ORG>
From: Mike Long <mike.long@analog.com>
List: current-users
Date: 10/07/1996 21:49:00
I'd like to know why this bit of code raises SIGBUS under NetSD/i386
1.2, instead of the expected SIGSEGV. It's originally from Berkeley
SPICE 3F4, file src/lib/fte/resource.c.
------------------------------------------------------------------------
#include <sys/types.h>
#include <signal.h>
#include <setjmp.h>
/*
* baseaddr( ) returns the base address of the data segment on most Unix
* systems. It's an ugly hack for info that should be provided by the OS.
*/
/* Does anyone use a pagesize < 256 bytes?? I'll bet not;
* too small doesn't hurt
*/
#define LOG2_PAGESIZE 8
static jmp_buf env;
static void
fault( )
{
signal(SIGSEGV, (void (*)()) fault); /* SysV style */
longjmp(env, 1);
}
static void *
baseaddr( )
{
char *low, *high, *at;
char *sbrk( );
long x;
void (*orig_signal)( );
low = 0;
high = (char *) ((unsigned long) sbrk(0) & ~((1 << LOG2_PAGESIZE) - 1));
orig_signal = signal(SIGSEGV, (void (*)()) fault);
do {
at = (char *) ((((long)low >> LOG2_PAGESIZE)
+ ((long)high >> LOG2_PAGESIZE))
<< (LOG2_PAGESIZE - 1));
if (at == low || at == high) {
break;
}
if (setjmp(env)) {
low = at;
continue;
} else
x = *at;
if (setjmp(env)) {
low = at;
continue;
} else
*at = x;
high = at;
} while (1);
(void) signal(SIGSEGV, (void (*)()) orig_signal);
return (void *) high;
}
main( )
{
printf("testing\n");
printf("baseaddr: %#8x topaddr: %#8x\n", baseaddr( ), sbrk(0));
}
------------------------------------------------------------------------
--
Mike Long <mike.long@analog.com> <URL:http://www.shore.net/~mikel>
VLSI Design Engineer finger mikel@shore.net for PGP public key
Analog Devices, CPD Division CCBF225E7D3F7ECB2C8F7ABB15D9BE7B
Norwood, MA 02062 USA (eq (opinion 'ADI) (opinion 'mike)) -> nil