Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 9 Dec 2003 23:05:27 -0600
From:      Craig Boston <craig@xfoil.gank.org>
To:        current@freebsd.org
Subject:   nss and pthreads and wine, oh my!
Message-ID:  <200312092305.27056.craig@xfoil.gank.org>

next in thread | raw e-mail | index | archive | help
I've come across a problem that I believe had been plaguing me on -CURRENT for 
a while but I just now was able to track down a possible cause.  The symptoms 
are that wine is unable to run any Win32 program that uses gethostbyname or 
getaddrinfo.  I'm seeing this on a recent 5.2-BETA and also an older 
5.1-RELEASE, so I can rule out the statfs ABI changes.  Wine is built from 
source on both and without CPUTYPE on the 5.2-BETA machine.

After building wine (and libc) with debug symbols, I can reproduce the 
following backtrace of where the crash occurs:

#0  0x5ce20000 in ?? ()
#1  0x5c0f3c98 in _nsdispatch (retval=0x5c71f054, disp_tab=0x5c131400,
    database=0x5c12c920 "hosts", method_name=0x5c12c912 "gethostbyname",
    defaults=0x5c1313d0) at /usr/src/lib/libc/net/nsdispatch.c:574
#2  0x5c0f3004 in gethostbyname2 (name=0x5d031c40 "test",
    type=2) at /usr/src/lib/libc/net/gethostnamadr.c:88
#3  0x5c0f2f9e in gethostbyname (name=0x5d031c40 "test")
    at /usr/src/lib/libc/net/gethostnamadr.c:72

line 574 of nsdispatch.c looks like this:

574             result = _pthread_rwlock_rdlock(&nss_lock);

Now, I've never really delved into libc before, so everything from this point 
is pure guesswork.  However, it strikes me as odd that nsdispatch() is 
calling pthread locking primitives in the non-reentrant C library (wine is 
linked against libc.so.5).

A quick grep of the source code shows that the only other thing similar in 
libc is in the RPC code, but in that case it uses a macro that checks 
__isthreaded before calling the pthread function.  According to the comments, 
__isthreaded is only set if a process has more than 1 thread.  So, I tried 
wrapping all of the pthreads stuff in nsdispatch.c with if(__isthreaded) 
blocks and presto, wine is working again.

I have no idea why wine seems to be the only program that behaves this way...  
At this point I'm not sure if it's a bug in libc or a bug in wine.  Has 
anybody else seen similar behavior out of wine or anything else?

Are there any threads gurus out there who know what the 'right thing' for 
nsdispatch to do is?

Thanks!
Craig



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200312092305.27056.craig>