Mail Archives: djgpp/1997/12/08/21:25:57
Ok, after being pointed out that my code doesn't lock the touched code and
variables, here is a completely bulletproof program (as far as I can
tell) that crashes under Win95 DPMI. It may take a while, but it does
crash. I've had it crash anywhere from 1 minute to 15 minutes after
starting it.
I would post a symified traceback, except it doesn't get there. Windows
intercepts the crash with the "This program has violated...." message and
gives a pointer to 0028:c0002840, which is inside the VMM function
Build_Int_Stack_Frame.
This is a very scary bug. If it does turn out to be a bug in Win95 DPMI,
it's really going to hurt DJGPP, since the ___djgpp_hw_exception trick is
the basis of signals under DJGPP.
Josh Turpen
44699 AT ef DOT gc DOT maricopa DOT edu
compiled with: gcc -o test1.exe test1.c test1asm.S
------------------Begin Test1.c-----------------------
#include <stdio.h>
#include <dpmi.h>
#include <signal.h>
#include <sys/segments.h>
extern void int_handler(void);
extern void end_int_handler(void);
void sig_handler(int signum);
static void bottom_of_functions(void);
static int _lwp_lock_data( void *lockaddr, unsigned long locksize );
static int _lwp_lock_code( void *lockaddr, unsigned long locksize );
static void top_of_vars() {};
int tick;
int old_sel, old_off;
static void bottom_of_vars() {};
static void top_of_functions() {};
void main()
{
__dpmi_paddr old, new;
void (*old_handler)(int);
if(_lwp_lock_code(top_of_functions, (long) bottom_of_functions -
(long) top_of_functions) == -1)
{
printf("Unable to lock code\n");
exit(-1);
}
if(_lwp_lock_code(int_handler, (long) end_int_handler - (long)
int_handler) == -1)
{
printf("Unable to lock int_handler\n");
exit(-1);
}
if(_lwp_lock_data(top_of_vars, (long) bottom_of_vars - (long)
top_of_vars) == -1)
{
printf("Unable to lock variables\n");
exit(-1);
}
old_handler = signal(SIGILL, sig_handler);
__dpmi_get_protected_mode_interrupt_vector(0x8, &old);
old_sel = old.selector;
old_off = old.offset32;
new.offset32 = (long) int_handler;
new.selector = _my_cs();
__dpmi_set_protected_mode_interrupt_vector(0x8, &new);
while(!kbhit())
{
printf("Tick %d\n", tick);
}
__dpmi_set_protected_mode_interrupt_vector(0x8, &old);
signal(SIGILL, old_handler);
}
void sig_handler(signum)
{
tick++;
}
static void bottom_of_functions() {};
static int _lwp_lock_data( void *lockaddr, unsigned long locksize )
{
unsigned long baseaddr;
__dpmi_meminfo memregion;
if( __dpmi_get_segment_base_address( _my_ds(), &baseaddr) == -1 )
{
return( -1 );
}
memset( &memregion, 0, sizeof(memregion) );
memregion.address = baseaddr + (unsigned long) lockaddr;
memregion.size = locksize;
if( __dpmi_lock_linear_region( &memregion ) == -1 )
{
return( -1 );
}
return( 0 );
}
static int _lwp_lock_code( void *lockaddr, unsigned long locksize )
{
unsigned long baseaddr;
__dpmi_meminfo memregion;
if( __dpmi_get_segment_base_address( _my_cs(), &baseaddr) == -1 )
{
return( -1 );
}
memset( &memregion, 0, sizeof(memregion) );
memregion.address = baseaddr + (unsigned long) lockaddr;
memregion.size = locksize;
if( __dpmi_lock_linear_region( &memregion ) == -1 )
{
return( -1 );
}
return( 0 );
}
--------------------------end Test1.c---------------------------
-------------------------Begin Test1asm.S----------------------
.globl _int_handler
.globl _end_int_handler
.align 4
_int_handler:
pushl $0
pushl $0
pushl %eax
pushl %ds
.byte 0x2e
movw ___djgpp_ds_alias, %ds
movl $0x99, %eax
call ___djgpp_hw_exception
movl _old_sel, %eax
movl %eax, 12(%esp)
movl _old_off, %eax
movl %eax, 8(%esp)
popl %ds
popl %eax
lret
_end_int_handler:
------------------------end test1asm.S-----------------------
- Raw text -