Date: Thu, 2 Sep 1999 14:18:21 +0200 (MET DST) From: Ulrich Weigand <weigand@informatik.uni-erlangen.de> To: nox@jelal.kn-bremen.de, wine-devel@winehq.com, luoqi@watermarkgroup.com Cc: freebsd-emulation@FreeBSD.ORG Subject: Re: wine signal handlers lose %fs on FreeBSD Message-ID: <199909021218.OAA21251@faui11.informatik.uni-erlangen.de>
next in thread | raw e-mail | index | archive | help
Luoqi Chen <luoqi@watermarkgroup.com> wrote: > > Here's a strange one: Sometimes apparently wine's signal handlers receive > > %fs messed up (zeroed actually) and therefore crash/hang on FreeBSD > > (3.2-stable, wine current-cvs). Patch this and watch for > > `warn:seh:EXC_SaveContext teb=0xsomewhere teb_sel=something, fs=0, gs=foo' > > messages, teb_sel is what fs really should have been (and what is loaded > > back there after the message, so the program actually continues too.) Well, this problem would seem to be caused by Wine. The problem is that while any Wine signal handler is running, %fs needs to be loaded with the value %fs had in the code that was interrupted by the signal *if that code is 32-bit*. If *16-bit* code was interrupted, however, %fs needs to be loaded with the value had at the time the switch from 32-bit to 16-bit took place (this value was saved at the time) ... The reason for this is that Wine, like 32-bit Windows, uses the %fs register to identify the current thread. On 16-bit Windows, however, %fs has no special meaning and is freely used by apps ... To achieve this, Wine calls a macro HANDLER_INIT() at the start of every signal handler which is supposed to set %fs correctly. This is defined as follows: #ifdef FS_sig #include "syslevel.h" #define HANDLER_INIT() \ do { int fs = IS_SELECTOR_SYSTEM(CS_sig(HANDLER_CONTEXT)) ? \ FS_sig(HANDLER_CONTEXT) : SYSLEVEL_Win16CurrentTeb; \ if (!fs) fs = SYSLEVEL_EmergencyTeb; \ SET_FS(fs); } while (0) #else #define HANDLER_INIT() /* nothing */ #endif The problem is that the second case (which is active only if FS_sig is undefined, meaning that the sigcontext structure doesn't contain the %fs value, like on FreeBSD) is clearly wrong. Try changing this to #define HANDLER_INIT() \ do { int fs; GET_FS(fs); fs &= 0xffff; \ if (!IS_SELECTOR_SYSTEM(CS_sig(HANDLER_CONTEXT))) \ fs = SYSLEVEL_Win16CurrentTeb; \ if (!fs) fs = SYSLEVEL_EmergencyTeb; \ SET_FS(fs); } while (0) \ > The kernel sets %fs to 0 during a context switch if it triggers a fault > (protection fault or segment not present) and signals SIGBUS. Most likely > the EXC_segv in your previous email is this signal. Unfortunately there > is no easy way to know which %fs value is causing the fault (probably you > could add a kernel printf, in file sys/i386/i386/trap.c, search for > cpu_switch_load_fs). This is probably not a problem for Wine. If I understand it correctly, this should trigger only if a 16-bit app running under Wine loads %fs with a selector that becomes invalid while still loaded (and on next context switch to that thread, the fault happens). In this case the app is broken anyway and the only thing Wine will want to do in the handler is to run the built-in debugger; for this the EmergencyTeb is enough ... > I took a brief look at the exception code, it probably would not work > under 4.0-current because the kernel uses %fs and signal handlers are > called with a default %fs value (the same as the default %ds). You might > need to restore %fs from the value in sigcontext at beginning of your > signal handlers (yes, fs in sigcontext is set for 4.0-current. Regarding > this, we could change the kernel, both -current and -stable, so that fs/gs > are always saved in sigcontext when the signal is delivered, and restored > during the signal trampoline, hence a consistent interface to application > authors). Alternatively, we could change the kernel to call signal handlers > with the original fs. Well, Wine can work with both ways, as long as there is way to find out what method the OS uses! What should we use as a check? Bye, Ulrich To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-emulation" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199909021218.OAA21251>