Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 2 Sep 1999 21:09:26 +0200
From:      Juergen Lock <nox@jelal.kn-bremen.de>
To:        Ulrich Weigand <weigand@informatik.uni-erlangen.de>
Cc:        nox@jelal.kn-bremen.de, wine-devel@winehq.com, luoqi@watermarkgroup.com, freebsd-emulation@FreeBSD.ORG
Subject:   Re: wine signal handlers lose %fs on FreeBSD
Message-ID:  <19990902210926.B5073@saturn.kn-bremen.de>
In-Reply-To: <199909021218.OAA21251@faui11.informatik.uni-erlangen.de>
References:  <199909021218.OAA21251@faui11.informatik.uni-erlangen.de>

next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, Sep 02, 1999 at 02:18:21PM +0200, Ulrich Weigand wrote:
> 
> Luoqi Chen <luoqi@watermarkgroup.com> wrote:
> 
(That was me actually:)

> > > 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.

 *DOH!*

>  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)       \
> 

 Heh.  I did search the wine sources for SET_FS but seems i forgot its
includes!  Yes, looks like this is the real fix (after removing the last \)
Thank you for restoring my confidence in FreeBSD's kernel... :)

> > 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?

 True, there needs to be some way to find out whether the fs/gs in the
sigcontext struct are for real or not...

 Regards,
-- 
Juergen Lock <nox.foo@jelal.kn-bremen.de>
(remove dot foo from address to reply)


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?19990902210926.B5073>