https://bugs.winehq.org/show_bug.cgi?id=48898
Bug ID: 48898 Summary: OpenGL demo fails due to ordinal mismatch Product: Wine Version: unspecified Hardware: x86 OS: Linux Status: UNCONFIRMED Severity: normal Priority: P2 Component: opengl Assignee: wine-bugs@winehq.org Reporter: chris@kode54.net Distribution: ---
End of Time, by Alcatraz and Altair, a <5KB demo .exe for Windows, crashes shortly after startup in Wine, because it is importing opengl32.dll symbols by ordinal instead of by name.
http://www.pouet.net/prod.php?which=77102
A similar bug affected APITrace, now fixed:
https://github.com/apitrace/apitrace/issues/652#issuecomment-610443894
It doesn't need to implement all functions, just the same set it currently does, but they also need the correct ordinals to match Windows.
https://bugs.winehq.org/show_bug.cgi?id=48898
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- Summary|OpenGL demo fails due to |4k demoscene OpenGL demo |ordinal mismatch |'End of time' by Alcatraz | |and Altair crashes on | |startup due to opengl32.dll | |imports ordinal mismatch URL| |http://www.pouet.net/prod.p | |hp?which=77102 Version|unspecified |5.5 CC| |focht@gmx.net Ever confirmed|0 |1 Keywords| |download Status|UNCONFIRMED |NEW
--- Comment #1 from Anastasius Focht focht@gmx.net --- Hello folks,
refining/filling some fields and confirming on behalf of Chris.
I've created a snapshot via Internet Archive in case the original download/mirrors disappear one day.
https://web.archive.org/web/20200408083804/http://xtr1m.com/downloads/atz-en...
$ sha1sum atz-end_of_time.zip 3a4ce3fd92e2fdd1a4533ee67d4809d3f2184f6b atz-end_of_time.zip
$ du -sh atz-end_of_time.zip 3.3M atz-end_of_time.zip
$ wine --version wine-5.5-373-g38e95ed222
Regards
https://bugs.winehq.org/show_bug.cgi?id=48898
Vijay Kamuju infyquest@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |infyquest@gmail.com
--- Comment #2 from Vijay Kamuju infyquest@gmail.com --- I am unable to test with wine 5.6, it throws module failed to load error
https://bugs.winehq.org/show_bug.cgi?id=48898
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- Depends on| |42125
--- Comment #3 from Anastasius Focht focht@gmx.net --- Hello Vijay,
that's because the app runs into bug 42125 ("4k/8k demos often fail with 'Bad EXE Format' due to Crinkler executable file compressor's "optimized" usage of PE header fields (loader compatibility)").
OP used Wine-Staging for testing but didn't bother to mention this important detail. When I refined the ticket fields I didn't check myself otherwise I would have mentioned it.
--- snip --- $ WINEDEBUG=+seh,+relay,+server,+module,+imports,+ntdll wine ./End\ of\ time\ 720p.exe >>log.txt 2>&1 ... 0009:trace:ntdll:FILE_CreateFile handle=0xff982a30 access=80100000 name=L"\??\Z:\home\focht\Downloads\End of time 720p.exe" objattr=00000040 root=(nil) sec=(nil) io=0xff982a40 alloc_size=(nil) attr=00000000 sharing=00000005 disp=1 options=00000060 ea=(nil).0x00000000 0009: create_file( access=80100000, sharing=00000005, create=1, options=00000060, attrs=00000000, objattr={rootdir=0000,attributes=00000040,sd={},name=L""}, filename="/home/focht/.wine/dosdevices/z:/home/focht/Downloads/End of time 720p.exe" ) 0009: create_file() = 0 { handle=0014 } 0009: get_handle_fd( handle=0014 ) 0009: *fd* 0014 -> 24 0009: get_handle_fd() = 0 { type=1, cacheable=1, access=00120089, options=00000060 } 0009: create_mapping( access=000f000d, flags=01000000, file_access=00000001, size=00000000, file_handle=0014, objattr={} ) 0009: create_mapping() = INVALID_FILE_FOR_SECTION { handle=0000 } 0009: close_handle( handle=0014 ) 0009: close_handle() = 0 0009:warn:module:load_dll Failed to load module L"Z:\home\focht\Downloads\End of time 720p.exe"; status=c0000020 0009:err:module:__wine_process_init failed to load L"Z:\home\focht\Downloads\End of time 720p.exe", error c0000020 0009: terminate_process( handle=ffffffff, exit_code=-1073741792 ) 0009: terminate_process() = 0 { self=1 } 0009: *killed* exit_code=-1073741792 0008: *process killed* --- snip ---
Adding dependency to bug 42125
Regards
https://bugs.winehq.org/show_bug.cgi?id=48898
--- Comment #4 from Vijay Kamuju infyquest@gmail.com --- Hello Anastasius,
With the relay log and the patch from #42125 can we find the ordinals the demo uses?
https://bugs.winehq.org/show_bug.cgi?id=48898
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- Summary|4k demoscene OpenGL demo |4k demoscene OpenGL demo |'End of time' by Alcatraz |'End of time' by Alcatraz |and Altair crashes on |and Altair crashes on |startup due to opengl32.dll |startup due to missing |imports ordinal mismatch |opengl32.dll | |'wglGetDefaultProcAddress' | |stub
--- Comment #5 from Anastasius Focht focht@gmx.net --- Hello Vijay,
--- quote --- With the relay log and the patch from #42125 can we find the ordinals the demo uses? --- quote ---
well, no. It's actually more complicated. The Crinkler executable file compressor implements a custom loader/imports resolver which doesn't use any win32 API calls for resolving. Since everything needs to be kept small, it uses a pretty clever approach, consuming only a minimum amount of information/data storage.
--- snip --- $ WINEDEBUG=+seh,+relay,+imports,+module,+opengl,+wgl wine ./End\ of\ time\ 720p.exe >>log.txt 2>&1 ... 0009:Call KERNEL32.LoadLibraryA(004208eb "opengl32") ret=004200a4 ... 0009:Ret KERNEL32.LoadLibraryA() retval=7a840000 ret=004200a4 ... 0009:Call opengl32.wglMakeCurrent(00421314,00008b30) ret=00420814 0009:Ret opengl32.wglMakeCurrent() retval=00000000 ret=00420814 0009:trace:seh:raise_exception code=c0000005 flags=0 addr=(nil) ip=00000000 tid=0009 0009:trace:seh:raise_exception info[0]=00000000 0009:trace:seh:raise_exception info[1]=00000000 0009:trace:seh:raise_exception eax=00000000 ebx=00400148 ecx=00421250 edx=00000000 esi=7a8477cc edi=00030039 0009:trace:seh:raise_exception ebp=1518ff00 esp=1518fee4 cs=0023 ds=002b es=002b fs=0063 gs=006b flags=00010202 0009:trace:seh:call_stack_handlers calling handler at 0x7b469400 code=c0000005 flags=0 --- snip ---
As already said, relay trace yields no useful information. One has to debug it.
The easiest way to debug Crinkler executables is to set a hardware breakpoint on execution at the decompression area for code. It's usually located at fixed 0x420000 address range for 32-bit.
After hitting the breakpoint you will come across the following code. I've annotated the relevant disassembly snippet but will also describe it in a summary after the snippet in case assembly it not your cup of tea ;-)
--- snip --- ; uncompressed entry 00420000 POP EDI 00420001 MOV ECX,1D 00420006 MOV AL,0E8 ... 00420018 MOV EBX,OFFSET 00400108 ; hash names start 0042001D MOV ESI,OFFSET 004208CE ; hash imports ranges 00420022 MOV EDI,OFFSET 00430000 ; area for custom IAT 00420027 POP EAX ; PEB 00420028 MOV EAX,DWORD PTR DS:[EAX+0C] ; PEB_LDR_DATA 0042002B MOV EAX,DWORD PTR DS:[EAX+0C] 0042002E MOV EAX,DWORD PTR DS:[EAX] 00420030 MOV EAX,DWORD PTR DS:[EAX] ; Flink ; _LDR_DATA_TABLE_ENTRY.DllBase (kernel32) 00420032 MOV EBP,DWORD PTR DS:[EAX+18] 00420035 TEST EBP,EBP ; module load address != 0? 00420037 JNE SHORT 00420047 00420039 PUSH 0 0042003B PUSH 0 0042003D PUSH EDX 0042003E PUSH 0 00420040 CALL DWORD PTR DS:[43001C] ; user32.MessageBoxA 00420046 RETN 00420047 XOR EAX,EAX 00420049 LODS BYTE PTR DS:[ESI] ; symbol (imports) range counter 0042004A XCHG EAX,ECX 0042004B PUSHAD 0042004C MOV EAX,DWORD PTR SS:[EBP+3C] ; EBP = module address, DOS->e_lfanew 0042004F ADD EAX,EBP ; VA PE header 00420051 MOV EDX,DWORD PTR DS:[EAX+78] ; RVA export directory 00420054 ADD EDX,EBP ; 00420056 MOV ECX,DWORD PTR DS:[EDX+18] ; Exports: NumberOfNames 00420059 MOV EAX,DWORD PTR DS:[EDX+20] ; Exports: AddressOfNames 0042005C ADD EAX,EBP ; 0042005E MOV ESI,DWORD PTR DS:[ECX*4+EAX-4] ; RVA sym_name[entry] 00420062 ADD ESI,EBP ; VA sym_name[entry] 00420064 XOR EDI,EDI 00420066 ROL EDI,6 ; sym_hash # 00420069 XOR EAX,EAX 0042006B LODS BYTE PTR DS:[ESI] ; sym_name[entry][char] 0042006C XOR EDI,EAX ; sym_hash # 0042006E DEC EAX 0042006F JGE SHORT 00420066 ; reached null terminator? 00420071 CMP EDI,DWORD PTR DS:[EBX] ; hashed function name match? 00420073 LOOPNZ SHORT 00420059 ; entry-- ; next (top-down) entry 00420075 MOV EAX,DWORD PTR DS:[EDX+24] ; Exports: AddressOfNameOrdinals 00420078 ADD EAX,EBP 0042007A MOV CX,WORD PTR DS:[ECX*2+EAX]; ECX = number of function 0042007E MOV EAX,DWORD PTR DS:[EDX+1C] ; Exports: AddressOfFunctions 00420081 ADD EAX,EBP 00420083 LEA EAX,[ECX*4+EAX] ; RVA API entry 00420086 MOV DWORD PTR SS:[ESP+14],EAX 0042008A POPAD 0042008B MOV EAX,DWORD PTR DS:[EDX] 0042008D ADD EAX,EBP ; VA API entry 0042008F ADD EDX,4 ; entry++ 00420092 STOS DWORD PTR ES:[EDI] ; store entry in custom IAT 00420093 DEC BYTE PTR DS:[ESI] ; range_entry counter-- 00420095 JNE SHORT 0042008B 00420097 INC ESI ; next range index 00420098 ADD EBX,4 ; next hash 0042009B LOOP SHORT 0042004B ; range counter--, next iteration 0042009D PUSH ESI 0042009E CALL DWORD PTR DS:[430008] ; kernel32.LoadLibraryA 004200A4 XCHG EAX,EBP ; EBP = module load address 004200A5 MOV EDX,ESI 004200A7 LODS BYTE PTR DS:[ESI] 004200A8 DEC AL 004200AA JNS SHORT 004200A7 004200AC INC AL 004200AE JE SHORT 00420035 --- snip ---
First, let me recap the export directory for you since the relation of the arrays/tables are important here. It points to 3 arrays/tables, containing RVAs:
* AddressOfFunctions * AddressOfNames * AddressOfNameOrdinals
Some general properties of these arrays:
* 'Names' and 'NameOrdinals' arrays = same length = NumberOfNames
* 'Names' and 'NameOrdinals' arrays can be shorter than 'Functions' array if functions are exported purely by ordinal. In extreme case they can be even empty (all exports ordinals only)
* The Ordinal of each exported function is the index in 'Functions' array. Important: starting from 1 (!)
* The relation between name and function address is done via 'NameOrdinals' array. Each entry in 'NameOrdinals' is an index into 'Functions' array. Important: starting from 0 (!)
---
As indicated in the preamble, the imports resolver uses a clever way to minimize the amount of information needed to resolve/lookup function addresses.
After loading each dll, it traverses the export directory 'AddressOfNames' array from top-down (last entry is processed first) and hashes each API function name. The hash algorithm from the disassembly can be written in C code like this:
--- snip --- int result = 0x0;
while (*str) { result = _rotl(result, 6); result ^= *str++; } --- snip ---
Every bit of the input has to affect the result (character set of the string). Basically the current result is rotated by a number of bits and then the current result is XORed with the current string byte. Repeat until the end of the string.
The compressor has two internal tables for each dll:
* pre-computed 32-bit hashes for API function names * number of consecutive functions to import (range)
It compares the hashed value of the API function name to a pre-computed 32-bit hash from above table. When it finds a match, it uses the 'NameOrdinals' array for further lookup. The association of name and function address is done in 'NameOrdinals' array. Each entry in 'NameOrdinals' is an index into 'Functions' array (starting from 0). The position of the entry in 'NameOrdinals' denotes the position of name in 'Names' array with the name of the function.
In the case of 'opengl32.dll' only two ranges are used.
range #1: glBindTexture + 241 (0xf1) consecutive functions range #2: glTexParameteri + 46 (0x2e) consecutive functions
To illustrate further, a dump of the resolver's custom IAT after processing:
--- snip --- Address Value Comments 00430000 7B42F93C ; kernel32.CreateThread 00430004 7B45010C ; kernel32.ExitProcess 00430008 7B430DF0 ; kernel32.LoadLibraryA 0043000C 7E8910A0 ; user32.ChangeDisplaySettingsA 00430010 7E89A250 ; user32.CreateWindowExA 00430014 7E84FE90 ; user32.GetAsyncKeyState 00430018 7E87B320 ; user32.GetDC 0043001C 7E875C60 ; user32.MessageBoxA 00430020 7E8717E0 ; user32.PeekMessageA 00430024 7E82A7E0 ; user32.ShowCursor 00430028 7E597AA0 ; gdi32.ChoosePixelFormat 0043002C 7E597C40 ; gdi32.SetPixelFormat 00430030 7E597CD0 ; gdi32.SwapBuffers
; opengl32 imports range #1 00430034 7A8AD8D0 ; opengl32.glBindTexture 00430038 7A8AD940 ; opengl32.glBitmap ... 004303C4 7A8B48F0 ; opengl32.glRasterPos4i 004303C8 7A8B4970 ; opengl32.glRasterPos4iv 004303CC 7A8B49E0 ; opengl32.glRasterPos4s 004303D0 7A8B4A70 ; opengl32.glRasterPos4sv 004303D4 7A8B4AE0 ; opengl32.glReadBuffer 004303D8 7A8B4B50 ; opengl32.glReadPixels 004303DC 7A8B4C00 ; opengl32.glRectd 004303E0 7A8B4CB0 ; opengl32.glRectdv 004303E4 7A8B4D20 ; opengl32.glRectf 004303E8 7A8B4DE0 ; opengl32.glRectfv 004303EC 7A8B4E50 ; opengl32.glRecti 004303F0 7A8B4ED0 ; opengl32.glRectiv 004303F4 7A8B4F40 ; opengl32.glRects
; opengl32 imports range #2 004303F8 7A8B6DB0 ; opengl32.glTexParameteri 004303FC 7A8B6E30 ; opengl32.glTexParameteriv 00430400 7A8B6EB0 ; opengl32.glTexSubImage1D 00430404 7A8B6F60 ; opengl32.glTexSubImage2D 00430408 7A8B7020 ; opengl32.glTranslated 0043040C 7A8B70C0 ; opengl32.glTranslatef 00430410 7A8B7160 ; opengl32.glVertex2d ... 004304A4 7A8BB980 ; opengl32.wglGetProcAddress 004304A8 7A8B98A0 ; opengl32.wglMakeCurrent 004304AC 7A8BB2A0 ; opengl32.wglRealizeLayerPalette 004304B0 00000000 004304B4 00000000 --- snip ---
Since import-by-ordinal mechanics are not used for resolving as explained above, misordered or even missing functions are a problem. The custom imports resolver relies on the fact that all needed API functions appear in a specific order in these ranges.
To investigate the discrepancy you basically use Wine's 'winedump' tool to dump exports from Wine builtin and native opengl32. Grep out each range, by using the start function name (see range #1 and range #2) and the count (-A argument in grep) to generate a range "diff".
aaaaand the offender is: 'wglGetDefaultProcAddress'
It seems AJ's commit https://source.winehq.org/git/wine.git/commitdiff/17dffaac7d5a8fc595775d456b... ("opengl32: Get WGL function definitions from the XML files.") in October 2017 removed it.
--- snip --- -@ stub wglGetDefaultProcAddress --- snip ---
BTW. the demo still crashes if you re-add the stub again. That's bug 43638 ("Yermom demoscene demo crashes on start up") for you ;-)
Regards
https://bugs.winehq.org/show_bug.cgi?id=48898
--- Comment #6 from Vijay Kamuju infyquest@gmail.com --- Does my patch https://source.winehq.org/patches/data/183299 fix this?
https://bugs.winehq.org/show_bug.cgi?id=48898
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- Keywords| |obfuscation Summary|4k demoscene OpenGL demo |4k demoscene OpenGL demos |'End of time' by Alcatraz |crash on startup due to |and Altair crashes on |missing opengl32.dll |startup due to missing |'wglGetDefaultProcAddress' |opengl32.dll |stub (Crinkler's imports |'wglGetDefaultProcAddress' |resolver requires named API |stub |exports matching native | |opengl32)
--- Comment #7 from Anastasius Focht focht@gmx.net --- Hello Vijay,
sure. Your patch adds the needed 'wglGetDefaultProcAddress' export back in correct place, directly after 'wglGetCurrentDC'.
--- snip --- +@ stub GlmfBeginGlsBlock +@ stub GlmfCloseMetaFile +@ stub GlmfEndGlsBlock +@ stub GlmfEndPlayback +@ stub GlmfInitPlayback +@ stub GlmfPlayGlsRecord @ stdcall glAccum(long float) @ stdcall glAlphaFunc(long float) @ stdcall glAreTexturesResident(long ptr ptr) @@ -344,6 +350,7 @@ @ stdcall wglDescribePixelFormat(long long long ptr) @ stdcall wglGetCurrentContext() @ stdcall wglGetCurrentDC() +@ stub wglGetDefaultProcAddress @ stdcall wglGetLayerPaletteEntries(long long long long ptr) @ stdcall wglGetPixelFormat(long) @ stdcall wglGetProcAddress(str) @@ -354,6 +361,7 @@ @ stdcall wglShareLists(long long) @ stdcall wglSwapBuffers(long) @ stdcall wglSwapLayerBuffers(long long) +@ stub wglSwapMultipleBuffers @ stdcall wglUseFontBitmapsA(long long long long) @ stdcall wglUseFontBitmapsW(long long long long) @ stdcall wglUseFontOutlinesA(long long long long float float long ptr) --- snip ---
The other changes, that is adding new GlmfXXX exports to the beginning and 'wglSwapMultipleBuffers' export near the end wouldn't affect Crinkler's imports resolver for this demo.
As explained in my comment #5, only the named API function order within the import chunks matters. The second range ends at 'wglSetLayerPaletteEntries' (including it), hence adding 'wglSwapMultipleBuffers' later is fine as well.
I'm refining the summary a bit, as more 4K demos are likely affected by it and to avoid dupes. Also adding my favourite keyword - 'obfuscation' ;-)
Regards
https://bugs.winehq.org/show_bug.cgi?id=48898
--- Comment #8 from Vijay Kamuju infyquest@gmail.com --- We need to hack make_opengl to add entries for: wglGetDefaultProcAddress wglSwapMultipleBuffers
https://bugs.winehq.org/show_bug.cgi?id=48898
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- Fixed by SHA1| |c169bfb42829e4cc5d76be62a6e | |b407fdc2d003d Status|NEW |RESOLVED Resolution|--- |FIXED
--- Comment #9 from Anastasius Focht focht@gmx.net --- Hello folks,
this is fixed by commit https://source.winehq.org/git/wine.git/commitdiff/c169bfb42829e4cc5d76be62a6... ("opengl32: Add stub for wglGetDefaultProcAddress()."
Thanks Alexandre
Regards
https://bugs.winehq.org/show_bug.cgi?id=48898
Alexandre Julliard julliard@winehq.org changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |CLOSED
--- Comment #10 from Alexandre Julliard julliard@winehq.org --- Closing bugs fixed in 5.7.
https://bugs.winehq.org/show_bug.cgi?id=48898
--- Comment #11 from Chris Moeller chris@kode54.net --- I cannot verify this is fixed with my distribution's build of 5.7, or with my own build of 5.7. Would this require completely obliterating my prefixes to verify?
https://bugs.winehq.org/show_bug.cgi?id=48898
--- Comment #12 from Anastasius Focht focht@gmx.net --- Hello Chris,
--- quote --- I cannot verify this is fixed with my distribution's build of 5.7, or with my own build of 5.7. Would this require completely obliterating my prefixes to verify? --- quote ---
well, it seems the demos suffer from more issues then ;-)
--- snip --- $ WINEDEBUG=+seh,+relay,+wgl,+opengl,+win,+msg,+winmm wine ./End\ of\ time\ 720p.exe >>log.txt 2>&1 ... 002c:Call winex11.drv.CreateDesktopWindow(00010020) ret=7e84b47d 002c:Ret winex11.drv.CreateDesktopWindow() retval=00000001 ret=7e84b47d ... 002c:Call winex11.drv.GetDC(00030039,00010020,00010020,1518fdd0,1518fde0,00000013) ret=7e88682e 002c:Ret winex11.drv.GetDC() retval=00000001 ret=7e88682e 002c:trace:win:GetDCEx (0x10020,(nil),0x13): returning 0x30039 (updated) 002c:Ret user32.GetDC() retval=00030039 ret=004200fb ... 002c:trace:wgl:glxdrv_wglDescribePixelFormat (0x30039,72,40,0x1518fe18) 002c:trace:wgl:get_pixel_format Returning fmt_id=0x11a for iPixelFormat=72 002c:trace:wgl:dump_PIXELFORMATDESCRIPTOR size 40 version 1 flags 37 type 0 color 32 8,8,8,8 accum 0 depth 24 stencil 8 aux 0 PFD_DOUBLEBUFFER PFD_DRAW_TO_WINDOW PFD_SUPPORT_OPENGL 002c:trace:wgl:wglChoosePixelFormat returning 4 002c:Ret opengl32.wglChoosePixelFormat() retval=00000004 ret=7e5a3e18 002c:Ret gdi32.ChoosePixelFormat() retval=00000004 ret=00420111 002c:Call gdi32.SetPixelFormat(00030039,00000004,00000000) ret=00420119 002c:Call opengl32.wglSetPixelFormat(00030039,00000004,00000000) ret=7e5a3fbd 002c:Call gdi32.__wine_get_wgl_driver(00030039,00000015) ret=7a8bb654 002c:Call ntdll.RtlRunOnceExecuteOnce(7e4f4a64,7e4929c0,00000000,00000000) ret=7b043505 002c:Ret ntdll.RtlRunOnceExecuteOnce() retval=00000000 ret=7b043505 002c:Ret gdi32.__wine_get_wgl_driver() retval=7e4f1040 ret=7a8bb654 002c:trace:wgl:set_pixel_format (0x30039,4) 002c:warn:wgl:set_pixel_format not a valid window DC 0x30039/0x10020 002c:Ret opengl32.wglSetPixelFormat() retval=00000000 ret=7e5a3fbd 002c:Ret gdi32.SetPixelFormat() retval=00000000 ret=00420119 002c:Call opengl32.wglCreateContext(00030039) ret=0042011f 002c:Call gdi32.__wine_get_wgl_driver(00030039,00000015) ret=7a8ba743 ... 002c:Ret gdi32.__wine_get_wgl_driver() retval=7e4f1040 ret=7a8ba743 002c:Ret opengl32.wglCreateContext() retval=00000000 ret=0042011f 002c:Call opengl32.wglMakeCurrent(00030039,00000000) ret=00420127 002c:Ret opengl32.wglMakeCurrent() retval=00000001 ret=00420127 002c:Call user32.ShowCursor(00000000) ret=0042012d 002c:Call winex11.drv.SetCursor(00000000) ret=7e835d31 002c:Ret winex11.drv.SetCursor() retval=00000000 ret=7e835d31 002c:Ret user32.ShowCursor() retval=ffffffff ret=0042012d 002c:Call opengl32.glGenTextures(00000001,00422410) ret=004202d9 002c:trace:opengl:glGenTextures (1, 0x422410) 002c:Ret opengl32.glGenTextures() retval=0000002e ret=004202d9 002c:Call winmm.waveOutOpen(03ab08e8,ffffffff,00421330,00000000,00000000,00000000) ret=00420155 002c:trace:winmm:waveOutOpen (03AB08E8, 4294967295, 00421330, 0, 0, 00000000) 002c:trace:winmm:WINMM_StartDevicesThread Starting up devices thread ... 002c:Ret winmm.waveOutOpen() retval=00000000 ret=00420155 002c:Call winmm.waveOutPrepareHeader(0000ff00,00421230,00000020) ret=00420161 ... 002c:Ret winmm.waveOutPrepareHeader() retval=00000000 ret=00420161 ... 002c:Call winmm.waveOutWrite(0000ff00,00421230,00000020) ret=0042016d ... 002c:Ret winmm.waveOutWrite() retval=00000000 ret=0042016d 002c:Call winmm.waveOutGetPosition(0000ff00,00421200,0000000c) ret=00420186 002c:trace:winmm:waveOutGetPosition (0000FF00, 00421200, 12) ... 002c:Ret winmm.waveOutGetPosition() retval=00000000 ret=00420186 002c:Call opengl32.wglGetProcAddress(00421314 "glCreateShaderProgramv") ret=00420814 002c:warn:wgl:wglGetProcAddress No active WGL context found 002c:Ret opengl32.wglGetProcAddress() retval=00000000 ret=00420814 ... 002c:trace:seh:raise_exception code=c0000005 flags=0 addr=(nil) ip=00000000 tid=002c 002c:trace:seh:raise_exception info[0]=00000000 002c:trace:seh:raise_exception info[1]=00000000 002c:trace:seh:raise_exception eax=00000000 ebx=00400148 ecx=00421250 edx=00000000 esi=7a847bbc edi=00030039 002c:trace:seh:raise_exception ebp=1518fefc esp=1518fedc cs=0023 ds=002b es=002b fs=0063 gs=006b flags=00010206 002c:trace:seh:call_stack_handlers calling handler at 0x7b46adb0 code=c0000005 flags=0 ... wine: Unhandled page fault on read access to 00000000 at address 00000000 (thread 002c), starting debugger... --- snip ---
The crash is not related to opengl32 exports/ordering this bug is about.
To me it looks like bug 18490 ("Multiple games fail to set pixel format on D3D device context created on desktop window (Empire: Total War, Napoleon: Total War, Utopia City)") but for GL device context on the desktop window.
According to online information it's not allowed to do any rendering using this context but enough to call functions like glGetString() etc.
Maybe some of the Wine graphics folks could weigh in with an opinion if this limitation is already known / tracked in a bug?
Regards
https://bugs.winehq.org/show_bug.cgi?id=48898 Bug 48898 depends on bug 42125, which changed state.
Bug 42125 Summary: 4k/8k demos often fail with 'Bad EXE Format' or 'error c0000020' due to Crinkler executable file compressor's "optimized" usage of PE header fields (loader compatibility) https://bugs.winehq.org/show_bug.cgi?id=42125
What |Removed |Added ---------------------------------------------------------------------------- Status|STAGED |RESOLVED Resolution|--- |FIXED
https://bugs.winehq.org/show_bug.cgi?id=48898
--- Comment #13 from Henri Verbeet hverbeet@gmail.com --- (In reply to Anastasius Focht from comment #12)
The crash is not related to opengl32 exports/ordering this bug is about.
To me it looks like bug 18490 ("Multiple games fail to set pixel format on D3D device context created on desktop window (Empire: Total War, Napoleon: Total War, Utopia City)") but for GL device context on the desktop window.
According to online information it's not allowed to do any rendering using this context but enough to call functions like glGetString() etc.
Maybe some of the Wine graphics folks could weigh in with an opinion if this limitation is already known / tracked in a bug?
I'm not aware of an existing bug report for this issue, no. It does strike me as similar to bug 36506 though, and it would not particularly surprise me if wglGetProcAddress() is supposed to return results consistent with GL_EXTENSIONS/GL_VERSION here, even without a current GL context.
I seem to recall having established in the context of bug 18490 that creating a GL context (or more specifically, setting a pixel format) on the desktop window is indeed supposed to fail. In any case, this seems like of of those bugs that would benefit from tests to establish what's supposed to happen.
https://bugs.winehq.org/show_bug.cgi?id=48898
--- Comment #14 from Anastasius Focht focht@gmx.net --- Hello folks,
it turned out the 4k demoscene demos suffer from a different problem and the OpenGL calls with no active WGL context (desktop window) was a side effect.
I've created bug 49195 ("Multiple 4k demoscene OpenGL demos crash on startup (failure to lookup atom 0xC019 'static' from global atom tables)") to track it.
Regards
https://bugs.winehq.org/show_bug.cgi?id=48898
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- URL|http://www.pouet.net/prod.p |https://web.archive.org/web |hp?which=77102 |/20200408083804/http://xtr1 | |m.com/downloads/atz-end_of_ | |time.zip