Hello,
I've updated today from wine and got into troubles after installing it - got Segmentation fault. I dig in it and figured the problem is my environment variable WINEDLLPATH which was set to "." (current directory). The back trace of stack during the crash was similar to this (just the frames 5,6,7,8 were repeating many times - until stack overflow):
#0 __pthread_rwlock_unlock (rwlock=0x4032b600) at ../../scheduler/pthread.c:669 #1 0x40220ea7 in gettext () from /lib/i686/libc.so.6 #2 0x40220885 in dcgettext () from /lib/i686/libc.so.6 #3 0x4021f667 in __assert_fail () from /lib/i686/libc.so.6 #4 0x400903d7 in __pthread_rwlock_unlock (rwlock=0x4032b600) at ../../scheduler/pthread.c:671 #5 0x40220ea7 in gettext () from /lib/i686/libc.so.6 #6 0x40220885 in dcgettext () from /lib/i686/libc.so.6 #7 0x4021f667 in __assert_fail () from /lib/i686/libc.so.6 #8 0x400903d7 in __pthread_rwlock_unlock (rwlock=0x4032b600) at ../../scheduler/pthread.c:671 #9 0x40220ea7 in gettext () from /lib/i686/libc.so.6 #10 0x40220885 in dcgettext () from /lib/i686/libc.so.6 #11 0x40278059 in strerror_r () from /lib/i686/libc.so.6 #12 0x40277ea5 in strerror () from /lib/i686/libc.so.6 #13 0x4035513a in dlerror () from /lib/libdl.so.2 #14 0x400f7c00 in wine_dlopen (filename=0x3c001862 "./ntdll.dll.so", flag=0x2, error=0xbffff244 "", errorsize=0x400) at loader.c:452 #15 0x400f745b in dlopen_dll (name=0x400f80cb "ntdll.dll", error=0xbffff244 "", errorsize=0x400, test_only=0x0, exists=0xbffff21c) at loader.c:151 #16 0x400f7b48 in wine_init (argc=0x1, argv=0xbffff694, error=0xbffff244 "", error_size=0x400) at loader.c:424 #17 0x3c000550 in main (argc=0x1, argv=0xbffff694) at main.c:33 #18 0x402137f7 in __libc_start_main () from /lib/i686/libc.so.6
So, I guess wine pthread functions table should be initialized before any (system) library get's chance to throw error, otherwise we have SIGSEGV.
I've fixed the error on my side with WINEDLLPATH="/usr/local/lib/wine:.". Anyways I think it's a workaround not a solution... Since I don't know much about initialization, I would leave the real fix for someone more skillful.
Best Regards, Juraj
Le mar 09/09/2003 à 12:34, Juraj Hercek a écrit :
I've fixed the error on my side with WINEDLLPATH="/usr/local/lib/wine:.". Anyways I think it's a workaround not a solution... Since I don't know much about initialization, I would leave the real fix for someone more skillful.
It seems like if WINEDLLPATH is set, Wine dlls are only searched for in it and nowhere else. I'll verify if that's the case or not, but that's my gut feeling for now. Is it the behaviour we want?
Dimi, it seems it's the same issue we had with the winewrap generated scripts (WINEDLLPATH was ".:").
Vincent
Le mer 10/09/2003 à 11:13, Vincent Béron a écrit :
Le mar 09/09/2003 à 12:34, Juraj Hercek a écrit :
I've fixed the error on my side with WINEDLLPATH="/usr/local/lib/wine:.". Anyways I think it's a workaround not a solution... Since I don't know much about initialization, I would leave the real fix for someone more skillful.
It seems like if WINEDLLPATH is set, Wine dlls are only searched for in it and nowhere else. I'll verify if that's the case or not, but that's my gut feeling for now. Is it the behaviour we want?
Further investigation reveals that the problem lies in kernel32.dll.so not being loaded yet when ntdll.dll.so fails to be found in dll_paths[i].
pthread_init (from kernel32.dll.so) must be called to initialize the various pthread functions used by Wine.
Would it be acceptable to swap the following 2 lines in wine_init (sorry about the wrapping): if (!(ntdll = dlopen_dll( "ntdll.dll", error, error_size, 0, &file_exists ))) return; if (!dlopen_dll( "kernel32.dll", error, error_size, 0, &file_exists )) return;
so kernel32.dll is opened before ntdll.dll, or is there a dependency from kernel32.dll to ntdll.dll?
Or is it possible to move the pthread_init function elsewhere, to someplace called before ntdll.dll is loaded?
Vincent
Vincent Béron wrote:
Le mer 10/09/2003 à 11:13, Vincent Béron a écrit :
Le mar 09/09/2003 à 12:34, Juraj Hercek a écrit :
I've fixed the error on my side with WINEDLLPATH="/usr/local/lib/wine:.". Anyways I think it's a workaround not a solution... Since I don't know much about initialization, I would leave the real fix for someone more skillful.
It seems like if WINEDLLPATH is set, Wine dlls are only searched for in it and nowhere else. I'll verify if that's the case or not, but that's my gut feeling for now. Is it the behaviour we want?
Further investigation reveals that the problem lies in kernel32.dll.so not being loaded yet when ntdll.dll.so fails to be found in dll_paths[i].
That's exactly the problem I'm having with compiling Wine without optimizations. the wine binary tries to link with ntdll. ntdll needs "InterlockedCompareExchange" from kernel32. In my case, this translates to a compilation error, which I have not managed to eliminate.
Ok, the tie breaker is in. On Windows 2000, ntdll.dll is not depnding on ANYTHING else. On the other hand, kernel32.dll does depend on ntdll.dll. This means that we have a circular dependancy in Wine that is not there in Windows 2000.
Would it be acceptable to swap the following 2 lines in wine_init (sorry about the wrapping): if (!(ntdll = dlopen_dll( "ntdll.dll", error, error_size, 0, &file_exists ))) return; if (!dlopen_dll( "kernel32.dll", error, error_size, 0, &file_exists )) return;
I think it would be wrong. Kernel32 obviously does depend on ntdll. It would probably be better to figure out why ntdll depends on kernel32 (we know that - InterlockedCompareExchange), and remove that.
so kernel32.dll is opened before ntdll.dll, or is there a dependency from kernel32.dll to ntdll.dll?
Unfortunetly, there is in Wine too.
Or is it possible to move the pthread_init function elsewhere, to someplace called before ntdll.dll is loaded?
Do "ldd miscemu/wine" for an answer - ntdll is loaded by the Linux linker, even if dlopen was not called at all. It's an interesting question why we need the dlopen, then.
Vincent
Shachar
Le mer 10/09/2003 à 11:51, Shachar Shemesh a écrit :
That's exactly the problem I'm having with compiling Wine without optimizations. the wine binary tries to link with ntdll. ntdll needs "InterlockedCompareExchange" from kernel32. In my case, this translates to a compilation error, which I have not managed to eliminate.
I'm leaning towards the inline InterlockedCompareExchange from winbase.h, as if I rebuild ntdll with -O1 miscemu/wine is built correctly (ie ntdll doesn't have any undefined references). It's from win32/device.c and win32/except.c which call InterlockedCompareExchangePointer(), which itself calls InterlockedCompareExchange() from winbase.h.
"extern inline InterlockedCompareExchange() {return bar();}" seems a bit odd for a function definition. What the purpose of having both extern and inline?
The whole point might be moot regarding linking, as ntdll is not required for miscemu/wine (see below).
Ok, the tie breaker is in. On Windows 2000, ntdll.dll is not depnding on ANYTHING else. On the other hand, kernel32.dll does depend on ntdll.dll. This means that we have a circular dependancy in Wine that is not there in Windows 2000.
Would it be acceptable to swap the following 2 lines in wine_init (sorry about the wrapping): if (!(ntdll = dlopen_dll( "ntdll.dll", error, error_size, 0, &file_exists ))) return; if (!dlopen_dll( "kernel32.dll", error, error_size, 0, &file_exists )) return;
I think it would be wrong. Kernel32 obviously does depend on ntdll. It would probably be better to figure out why ntdll depends on kernel32 (we know that - InterlockedCompareExchange), and remove that.
See above. BTW, ldd ntdll.dll.so doesn't show kernel32.
so kernel32.dll is opened before ntdll.dll, or is there a dependency from kernel32.dll to ntdll.dll?
Unfortunetly, there is in Wine too.
Yes, ntdll is the first thing to be loaded.
Or is it possible to move the pthread_init function elsewhere, to someplace called before ntdll.dll is loaded?
Do "ldd miscemu/wine" for an answer - ntdll is loaded by the Linux linker, even if dlopen was not called at all. It's an interesting question why we need the dlopen, then.
Hmmm... I guess the -lntdll.dll on the linking line of miscemu/wine is the cause :) I've been able to link it while removing that part, so I'm not sure if that part is still useful.
Vincent
Vincent Béron wrote:
Le mer 10/09/2003 à 11:51, Shachar Shemesh a écrit :
That's exactly the problem I'm having with compiling Wine without optimizations. the wine binary tries to link with ntdll. ntdll needs "InterlockedCompareExchange" from kernel32. In my case, this translates to a compilation error, which I have not managed to eliminate.
I'm leaning towards the inline InterlockedCompareExchange from winbase.h, as if I rebuild ntdll with -O1 miscemu/wine is built correctly (ie ntdll doesn't have any undefined references). It's from win32/device.c and win32/except.c which call InterlockedCompareExchangePointer(), which itself calls InterlockedCompareExchange() from winbase.h.
"extern inline InterlockedCompareExchange() {return bar();}" seems a bit odd for a function definition. What the purpose of having both extern and inline?
Probably should be "static inline". That's the way you usually do it inside headers.
I was under the impression that InterlockedCompareExchange rightfully belonged in kernel32 (that's where nm said it was defined, after all). That's why I thought this was a circular dependancy.
Ahh, I now see why I thought so. It is also defined in dlls/kernel/sync.c as a regular function. MSDN says this:
*Client: *Included in Windows XP, Windows 2000 Professional, Windows NT Workstation 4.0, Windows Me, and Windows 98. *Server: *Included in Windows Server 2003, Windows 2000 Server, and Windows NT Server 4.0. *Header: *Declared in Winbase.h; include Windows.h. *Library: *Use Kernel32.lib.
I think it's probably a bad idea to use this function (actually, InterlockedCompareExchangePointer) from ntdll at all. This is a circular dependancy, even if we manage to get away with it using optimizer tricks.
The whole point might be moot regarding linking, as ntdll is not required for miscemu/wine (see below).
Ok, the tie breaker is in. On Windows 2000, ntdll.dll is not depnding on ANYTHING else. On the other hand, kernel32.dll does depend on ntdll.dll. This means that we have a circular dependancy in Wine that is not there in Windows 2000.
Would it be acceptable to swap the following 2 lines in wine_init (sorry about the wrapping): if (!(ntdll = dlopen_dll( "ntdll.dll", error, error_size, 0, &file_exists ))) return; if (!dlopen_dll( "kernel32.dll", error, error_size, 0, &file_exists )) return;
I think it would be wrong. Kernel32 obviously does depend on ntdll. It would probably be better to figure out why ntdll depends on kernel32 (we know that - InterlockedCompareExchange), and remove that.
See above. BTW, ldd ntdll.dll.so doesn't show kernel32.
You did the wrong test the question is not whether ntdll.dll depends on kernel32 (if you compile without optimizations, it has an undefined symbol, but nm is the tool to show you that, not ldd). The question was whether wine depended on ntdll. sun@sun:~/sources/wine/wine$ ldd miscemu/wine libntdll.dll.so => /home/sun/sources/wine/wine/dlls/libntdll.dll.so (0x40015000) libwine.so.1 => not found libwine_unicode.so.1 => not found libc.so.6 => /lib/libc.so.6 (0x40101000) libwine.so.1 => not found libwine_unicode.so.1 => not found libm.so.6 => /lib/libm.so.6 (0x40226000) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
Do "ldd miscemu/wine" for an answer - ntdll is loaded by the Linux linker, even if dlopen was not called at all. It's an interesting question why we need the dlopen, then.
Hmmm... I guess the -lntdll.dll on the linking line of miscemu/wine is the cause :) I've been able to link it while removing that part, so I'm not sure if that part is still useful.
Vincent
While I think the the "-lntdll" is a strange kludge in miscemu/wine makefile, and therefor should go if it's indeed not necessary, I don't think it is correct to load kernel32 before ntdll. The DLLs obviously depend one on the other in the opposite order (or, more precisely, should).
Shachar
Le mer 10/09/2003 à 14:14, Shachar Shemesh a écrit :
Vincent Béron wrote:
Le mer 10/09/2003 à 11:51, Shachar Shemesh a écrit :
That's exactly the problem I'm having with compiling Wine without optimizations. the wine binary tries to link with ntdll. ntdll needs "InterlockedCompareExchange" from kernel32. In my case, this translates to a compilation error, which I have not managed to eliminate.
I'm leaning towards the inline InterlockedCompareExchange from winbase.h, as if I rebuild ntdll with -O1 miscemu/wine is built correctly (ie ntdll doesn't have any undefined references). It's from win32/device.c and win32/except.c which call InterlockedCompareExchangePointer(), which itself calls InterlockedCompareExchange() from winbase.h.
"extern inline InterlockedCompareExchange() {return bar();}" seems a bit odd for a function definition. What the purpose of having both extern and inline?
Probably should be "static inline". That's the way you usually do it inside headers.
That's how InterlockedCompareExchangePointer() is defined. I'll try that.
Result: fails, because it's only a replacement implementation (hence the extern). Actually, only defining InterlockedCompareExchange as static inline works, but it becomes highly tricky, since there's a slew of other functions still defined as extern inline in the same chunk of winbase.h.
I was under the impression that InterlockedCompareExchange rightfully belonged in kernel32 (that's where nm said it was defined, after all). That's why I thought this was a circular dependancy.
Ahh, I now see why I thought so. It is also defined in dlls/kernel/sync.c as a regular function. MSDN says this:
*Client: *Included in Windows XP, Windows 2000 Professional, Windows NT Workstation 4.0, Windows Me, and Windows 98. *Server: *Included in Windows Server 2003, Windows 2000 Server, and Windows NT Server 4.0. *Header: *Declared in Winbase.h; include Windows.h. *Library: *Use Kernel32.lib.
I think it's probably a bad idea to use this function (actually, InterlockedCompareExchangePointer) from ntdll at all. This is a circular dependancy, even if we manage to get away with it using optimizer tricks.
Dll separation issue then.
While I think the the "-lntdll" is a strange kludge in miscemu/wine makefile, and therefor should go if it's indeed not necessary, I don't think it is correct to load kernel32 before ntdll. The DLLs obviously depend one on the other in the opposite order (or, more precisely, should).
Actually, wine doesn't run even if it links if I remove -lntdll. So it must stay as a dependency of wine.
Vincent