[Bug 13599] Can't install Autocad 2005

wine-bugs at winehq.org wine-bugs at winehq.org
Sun Jun 29 09:04:31 CDT 2008


http://bugs.winehq.org/show_bug.cgi?id=13599


Anastasius Focht <focht at gmx.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |focht at gmx.net




--- Comment #56 from Anastasius Focht <focht at 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.



More information about the wine-bugs mailing list