Wed Mar 13 19:46:50 1996 Alexandre Julliard <julliard@lrc.epfl.ch> * [controls/edit.c] Removed calls to memmove (not portable). * [debugger/dbg.y] [debugger/debug.l] Prefixed all token with 't' to avoid conflicts with type definitions. Added 'walk queue', 'walk class' and 'info class' commands. * [debugger/info.c] Moved queue and window information functions to windows/queue.c and windows/win.c respectively. * [loader/signal.c] Added SIGHUP handling to force entry into built-in debugger. Cleaned up a bit. * [misc/spy.c] General cleanup and performance improvements. * [windows/class.c] Added CLASS_DumpClass() and CLASS_WalkClasses() functions for debugger. * [windows/event.c] Pressing Ctrl-Alt-Return forces an entry into the debugger. Not sure if this key combination is a good choice... * [windows/message.c] [windows/queue.c] (New file) Moved message queue handling functions to windows/queue.c. Tue Mar 12 14:55:16 1996 Onno Hovers <onno@stack.urc.tue.nl> * [if1632/except.S] [include/except.h] [win32/except.c] (New files) Implemented Win32 exception functions: RaiseException(), RtlUnwind(), SetUnhandledExceptionFilter() and UnhandledExceptionFilter(). Mon Mar 11 19:23:29 1996 Albrecht Kleine <kleine@ak.sax.de> * [controls/listbox.c] [include/listbox.h] Special handling for COMBOLBOX styles introduced via extension of HEADLIST structure: lphl->dwStyle. Mon Mar 11 13:31:06 1996 Greg Kreider <kreider@natlab.research.philips.com> * [controls/combo.c] Any mouse movement within a small distance (defined by CBLMM_EDGE) of the top or bottom edge causes the window to scroll. Also moved some assignments so the routine works correctly. * [controls/listbox.c] Changing selection in ListBoxSetCurSel now updates PrevFocused. Added to LBSetFont and CreateListBoxStruct a fake hdc that tests and sets the standard text height. Sun Mar 10 08:39:23 1996 Alex Korobka <alex@phm30.pharm.sunysb.edu> * [windows/dce.c] Fixed memory leak in DCE_ClipWindows().
191 lines
4.9 KiB
C
191 lines
4.9 KiB
C
#ifndef WINELIB
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <signal.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <time.h>
|
|
#include <setjmp.h>
|
|
|
|
#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__svr4__)
|
|
#include <sys/syscall.h>
|
|
#include <sys/param.h>
|
|
#else
|
|
#include <syscall.h>
|
|
#endif
|
|
|
|
#include "debugger.h"
|
|
#include "miscemu.h"
|
|
#include "registers.h"
|
|
#include "win.h"
|
|
|
|
#if !defined(BSD4_4) || defined(linux) || defined(__FreeBSD__)
|
|
char * cstack[4096];
|
|
#endif
|
|
|
|
#ifdef linux
|
|
extern void ___sig_restore();
|
|
extern void ___masksig_restore();
|
|
|
|
/* Similar to the sigaction function in libc, except it leaves alone the
|
|
restorer field */
|
|
|
|
static int
|
|
wine_sigaction(int sig,struct sigaction * new, struct sigaction * old)
|
|
{
|
|
__asm__("int $0x80":"=a" (sig)
|
|
:"0" (SYS_sigaction),"b" (sig),"c" (new),"d" (old));
|
|
if (sig>=0)
|
|
return 0;
|
|
errno = -sig;
|
|
return -1;
|
|
}
|
|
#endif
|
|
|
|
|
|
#if defined(linux)
|
|
static void win_fault(int signal, struct sigcontext_struct context_struct)
|
|
{
|
|
struct sigcontext_struct *context = &context_struct;
|
|
#elif defined(__svr4__)
|
|
static void win_fault(int signal, void *siginfo, ucontext_t *context)
|
|
{
|
|
#else
|
|
static void win_fault(int signal, int code, struct sigcontext *context)
|
|
{
|
|
#endif
|
|
if (signal == SIGTRAP)
|
|
{
|
|
/* If SIGTRAP not caused by breakpoint or single step
|
|
don't jump into the debugger */
|
|
if (!(EFL_reg(context) & STEP_FLAG))
|
|
{
|
|
DBG_ADDR addr;
|
|
addr.seg = CS_reg(context);
|
|
addr.off = EIP_reg(context) - 1;
|
|
if (DEBUG_FindBreakpoint(&addr) == -1) return;
|
|
}
|
|
}
|
|
else if (signal != SIGHUP)
|
|
{
|
|
if (CS_reg(context) == WINE_CODE_SELECTOR)
|
|
{
|
|
fprintf(stderr, "Segmentation fault in Wine program (%x:%lx)."
|
|
" Please debug.\n",
|
|
CS_reg(context), EIP_reg(context) );
|
|
}
|
|
else
|
|
{
|
|
if (INSTR_EmulateInstruction( context )) return;
|
|
fprintf( stderr, "Segmentation fault in Windows program %x:%lx.\n",
|
|
CS_reg(context), EIP_reg(context) );
|
|
}
|
|
}
|
|
|
|
XUngrabPointer(display, CurrentTime);
|
|
XUngrabServer(display);
|
|
XFlush(display);
|
|
wine_debug( signal, context ); /* Enter our debugger */
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* SIGNAL_SetHandler
|
|
*/
|
|
static void SIGNAL_SetHandler( int sig, void (*func)() )
|
|
{
|
|
int ret;
|
|
struct sigaction sig_act;
|
|
|
|
#ifdef linux
|
|
sig_act.sa_handler = func;
|
|
/* Point to the top of the stack, minus 4 just in case, and make
|
|
it aligned */
|
|
sig_act.sa_restorer =
|
|
(void (*)()) (((unsigned int)(cstack) + sizeof(cstack) - 4) & ~3);
|
|
ret = wine_sigaction( sig, &sig_act, NULL );
|
|
#endif /* linux */
|
|
|
|
#if defined(__NetBSD__) || defined(__FreeBSD__)
|
|
sig_act.sa_handler = func;
|
|
sig_act.sa_flags = SA_ONSTACK;
|
|
sig_act.sa_mask = sig_mask;
|
|
ret = sigaction( sig, &sig_act, NULL );
|
|
#endif /* __FreeBSD__ || __NetBSD__ */
|
|
|
|
#if defined (__svr4__)
|
|
sig_act.sa_handler = func;
|
|
sig_act.sa_flags = SA_ONSTACK | SA_SIGINFO;
|
|
sig_act.sa_mask = sig_mask;
|
|
ret = sigaction( sig, &sig_act, NULL );
|
|
#endif /* __svr4__ */
|
|
|
|
if (ret < 0)
|
|
{
|
|
perror( "sigaction" );
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* init_wine_signals
|
|
*/
|
|
void init_wine_signals(void)
|
|
{
|
|
extern void stop_wait(int a);
|
|
|
|
#if defined(__NetBSD__) || defined(__FreeBSD__)
|
|
sigset_t sig_mask;
|
|
struct sigaltstack ss;
|
|
|
|
#if !defined (__FreeBSD__)
|
|
if ((ss.ss_base = malloc(MINSIGSTKSZ)) == NULL) {
|
|
#else
|
|
if ((ss.ss_sp = malloc(MINSIGSTKSZ)) == NULL) {
|
|
#endif
|
|
fprintf(stderr, "Unable to allocate signal stack (%d bytes)\n",
|
|
MINSIGSTKSZ);
|
|
exit(1);
|
|
}
|
|
ss.ss_size = MINSIGSTKSZ;
|
|
ss.ss_flags = 0;
|
|
if (sigaltstack(&ss, NULL) < 0) {
|
|
perror("sigstack");
|
|
exit(1);
|
|
}
|
|
sigemptyset(&sig_mask);
|
|
#endif /* __FreeBSD__ || __NetBSD__ */
|
|
|
|
#if defined (__svr4__)
|
|
sigset_t sig_mask;
|
|
struct sigaltstack ss;
|
|
|
|
if ((ss.ss_sp = malloc(SIGSTKSZ) ) == NULL) {
|
|
fprintf(stderr, "Unable to allocate signal stack (%d bytes)\n",
|
|
SIGSTKSZ);
|
|
exit(1);
|
|
}
|
|
ss.ss_size = SIGSTKSZ;
|
|
ss.ss_flags = 0;
|
|
if (sigaltstack(&ss, NULL) < 0) {
|
|
perror("sigstack");
|
|
exit(1);
|
|
}
|
|
sigemptyset(&sig_mask);
|
|
#endif /* __svr4__ */
|
|
|
|
SIGNAL_SetHandler( SIGSEGV, (void (*)())win_fault );
|
|
SIGNAL_SetHandler( SIGILL, (void (*)())win_fault );
|
|
SIGNAL_SetHandler( SIGFPE, (void (*)())win_fault );
|
|
SIGNAL_SetHandler( SIGTRAP, (void (*)())win_fault ); /* For debugger */
|
|
SIGNAL_SetHandler( SIGHUP, (void (*)())win_fault ); /* For forced break */
|
|
#ifdef SIGBUS
|
|
SIGNAL_SetHandler( SIGBUS, (void (*)())win_fault );
|
|
#endif
|
|
#ifdef CONFIG_IPC
|
|
SIGNAL_SetHandler( SIGUSR2, (void (*)())stop_wait ); /* For IPC */
|
|
#endif
|
|
}
|
|
|
|
#endif /* ifndef WINELIB */
|