http://bugs.winehq.org/show_bug.cgi?id=13599 Anastasius Focht <focht(a)gmx.net> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |focht(a)gmx.net --- Comment #56 from Anastasius Focht <focht(a)gmx.net> 2008-06-29 09:04:30 --- Hello, ideally it should work without gl context (returning NULL) - though the call is questionable because it makes no sense at all. That custom action is either a leftover or the developer didn't understand at all what he wrote. On the wine/linux side it's most likely a misconception in nvidia's opengl driver which leads to the crash. The custom action runs in a secondary msi thread (by design) and that's why the bug is uncovered that late. The following sample code illustrates the problem, calling gl without context from primary and secondary thread: --- snip sample --- /* winegcc -o gltest gltest.c -lopengl32 */ #include <windows.h> #include <stdio.h> #include <GL/gl.h> void print_info() { printf("(%x, %p)\n", GetCurrentThreadId(), glGetString(GL_VERSION)); } static DWORD WINAPI thread_proc( PVOID arg) { print_info(); return 0; } int main() { print_info(); WaitForSingleObject( CreateThread( NULL,0, thread_proc, NULL, 0, NULL), INFINITE); return 0; } --- snip sample --- Ideally it shouldn't crash, printing out two times "(<tid>, (nil))". --- snip winedbg session --- winedbg gltest.exe.so WineDbg starting on pid 001e 0x7b87de58 DbgBreakPoint+0x4 in kernel32: popl %ebp Wine-dbg>b wine_glGetString Breakpoint 1 at 0x7d1eeaad wine_glGetString in opengl32 Wine-dbg>c Stopped on breakpoint 1 at 0x7d1eeaad wine_glGetString in opengl32 .. 0x7d1eead3 wine_glGetString+0x26 in opengl32: call 0x7d1ecd74 enter_gl in opengl32 Wine-dbg> 0x7d1eead8 wine_glGetString+0x2b in opengl32: movl 0x8(%ebp),%eax Wine-dbg> 0x7d1eeadb wine_glGetString+0x2e in opengl32: movl %eax,0x0(%esp) Wine-dbg> 0x7d1eeade wine_glGetString+0x31 in opengl32: call 0x7d1a7d1c Wine-dbg>si 0x7d1a7d1c: jmp *0x4ec(%ebx) .. Wine-dbg>x/10x $ebx 0x7d20701c _GLOBAL_OFFSET_TABLE_: 0007fee8 00000000 00000000 60505ed0 0x7d20702c _GLOBAL_OFFSET_TABLE_+0x10: 60505510 60506010 605042d0 60504e10 0x7d20703c _GLOBAL_OFFSET_TABLE_+0x20: 604ffb10 60505670 .. Wine-dbg>x/x _GLOBAL_OFFSET_TABLE_ Many symbols with name '_GLOBAL_OFFSET_TABLE_', choose the one you want (<cr> to abort): [1]: 0x616cedd0 _GLOBAL_OFFSET_TABLE_ in winex11 [2]: 0x616f6130 _GLOBAL_OFFSET_TABLE_ in imm32 [3]: 0x7d20701c _GLOBAL_OFFSET_TABLE_ in opengl32 .. 0x7d2074fc _GLOBAL_OFFSET_TABLE_+0x4e0: 60505210 605027f0 605053f0 605052f0 .. Wine-dbg>disas 0x605052f0 0x605052f0: movl %gs:0xffffffb0,%eax 0x605052f6: jmp *0x390(%eax) 0x605052fc: int $3 .. Wine-dbg>si 0x605052f0: movl %gs:0xffffffb0,%eax Wine-dbg> 0x605052f6: jmp *0x390(%eax) Wine-dbg> 0x60a1c9c0: xorl %eax,%eax Wine-dbg> 0x60a1c9c2: ret .. --- snip winedbg session --- The GOT entry for glGetString is at _GLOBAL_OFFSET_TABLE_+0x4ec (opengl32.dll.so, section .GOT) The target address contains a R_386_TLS_LE (reloc) type instruction which resolves jump destination for the thunk. Let's see where this target address belongs to ... --- snip --- cat /proc/17753/maps .. 6045e000-604f2000 r-xp 00000000 fd:00 19081266 /usr/lib/nvidia/libGL.so.173.14.09 604f2000-6050d000 rwxp 00094000 fd:00 19081266 /usr/lib/nvidia/libGL.so.173.14.09 .. 6052f000-611d4000 r-xp 00000000 fd:00 19081262 /usr/lib/nvidia/libGLcore.so.173.14.09 611d4000-61361000 rwxp 00ca4000 fd:00 19081262 /usr/lib/nvidia/libGLcore.so.173.14.09 .. --- snip --- Now lets verify it's really the correct destination: --- snip --- objdump -T /usr/lib/nvidia/libGL.so.173.14.09 | grep glGetString 002ad2f0 g DF .writetext 00000000 Base glGetString --- snip --- Seems so. The thunks will be written at runtime (hence the ".writetext" section name). --- snip --- readelf -x .writetext /usr/lib/nvidia/libGL.so.173.14.09 | grep 002ad2f0 0x002ad2f0 00000000 00000000 00000000 00000000 ................ --- snip --- As already indicated by instruction type, all API entries are *TLS* aware. No gl context: If called from main thread, the resulting TLS value points to a small stub in libGLcore.so. If called from a different thread context, the resulting TLS value is zero, pointing to nirvana, resulting in crash. This seems to be a misconception in nvidia's opengl driver, not properly handling context-less calls from different threads. With valid gl context: The resulting thunk address will point to real implementation. It's probably a very rare case that an application calls gl API without context so I suggest to fix only wine_glGetString() for now, returning NULL for empty context and not calling drivers glGetString (making a big NOTE in source code, referring to nvidia brain damage). The fix with SEH guard would only hide other bugs. Regards -- Configure bugmail: http://bugs.winehq.org/userprefs.cgi?tab=email Do not reply to this email, post in Bugzilla using the above URL to reply. ------- You are receiving this mail because: ------- You are watching all bug changes.