http://bugs.winehq.org/show_bug.cgi?id=10062
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- Keywords| |obfuscation Status|NEW |RESOLVED CC| |focht@gmx.net Component|kernel32 |-unknown Hardware|Other |x86 Resolution|--- |WONTFIX Summary|Segmentation Fault with |Bellybutton Groove demo |Bellybutton Groove demo |runs out of stack space | |(broken by design)
--- Comment #16 from Anastasius Focht focht@gmx.net --- Hello folks,
confirming, actually a WONTFIX.
Some "genius" tried to be clever and reserved a stupid amount of stack space on the main thread stack (hard coded).
The guy most likely calculated the typical thread stack usage by Windows API and subtracted that from default 1MB limit.
--- snip --- 004010E0 55 PUSH EBP 004010E1 8BEC MOV EBP,ESP 004010E3 6A FF PUSH -1 004010E5 68 0AEF4000 PUSH dotdot_T.0040EF0A ; install SE handler 004010EA 64:A1 00000000 MOV EAX,DWORD PTR FS:[0] 004010F0 50 PUSH EAX 004010F1 64:8925 00000000 MOV DWORD PTR FS:[0],ESP 004010F8 51 PUSH ECX 004010F9 B8 FC370F00 MOV EAX,0F37FC ; alloc stack (~974KB) 004010FE E8 CD650000 CALL dotdot_T.004076D0 00401103 53 PUSH EBX 00401104 56 PUSH ESI 00401105 57 PUSH EDI 00401106 C745 FC 00000000 MOV DWORD PTR SS:[EBP-4],0 0040110D 8965 F0 MOV DWORD PTR SS:[EBP-10],ESP 00401110 E8 FF590000 CALL JMP.&ptc.#167__ptc_use_exceptions@0 ... --- snip ---
Stack allocator:
--- snip --- 004076D0 51 PUSH ECX 004076D1 3D 00100000 CMP EAX,1000 ; stack alloc size 004076D6 8D4C24 08 LEA ECX,DWORD PTR SS:[ESP+8] 004076DA 72 14 JB SHORT dotdot_T.004076F0 004076DC 81E9 00100000 SUB ECX,1000 004076E2 2D 00100000 SUB EAX,1000 004076E7 8501 TEST DWORD PTR DS:[ECX],EAX 004076E9 3D 00100000 CMP EAX,1000 004076EE 73 EC JNB SHORT dotdot_T.004076DC 004076F0 2BC8 SUB ECX,EAX 004076F2 8BC4 MOV EAX,ESP 004076F4 8501 TEST DWORD PTR DS:[ECX],EAX 004076F6 8BE1 MOV ESP,ECX ; new bottom 004076F8 8B08 MOV ECX,DWORD PTR DS:[EAX] 004076FA 8B40 04 MOV EAX,DWORD PTR DS:[EAX+4] 004076FD 50 PUSH EAX 004076FE C3 RETN --- snip ---
After that operation there is ~50 KB of stack space left for the main thread.
NVIDIA's driver and possibly others sometimes need 40-64 KB stack space on certain API calls.
Debugger session:
--- snip --- Wine-dbg> 2970 wined3d_adapter_init_limits(gl_info);
Wine-dbg>s 2972 if (gl_info->supported[ARB_VERTEX_PROGRAM] && test_arb_vs_offset_limit(gl_info))
Wine-dbg>
0x7e40a859 test_arb_vs_offset_limit+0xd5 [/home/focht/projects/wine/wine.repo/src/dlls/wined3d/directx.c:457] in wined3d: call *%eax 457 GL_EXTCALL(glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
...
Wine-dbg>n 453 if(!prog) { Wine-dbg>n 456 GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prog)); Wine-dbg>n 457 GL_EXTCALL(glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
Wine-dbg>bt
Backtrace: =>0 0x437b8d41 in libnvidia-glcore.so.331.67 (+0x1476d41) (0x0024bb78) 1 0x7e40285b test_arb_vs_offset_limit+0xd6(gl_info=0x12d71c) [/home/focht/projects/wine/wine.repo/src/dlls/wined3d/directx.c:457] in wined3d (0x0024bb78) 2 0x7e40ca1b wined3d_adapter_init_gl_caps+0xcc7(adapter=0x12d70c) [/home/focht/projects/wine/wine.repo/src/dlls/wined3d/directx.c:2972] in wined3d (0x0024bd58) 3 0x7e412877 wined3d_adapter_init+0x372(adapter=0x12d70c, ordinal=0) [/home/focht/projects/wine/wine.repo/src/dlls/wined3d/directx.c:5141] in wined3d (0x0024c168) 4 0x7e412dd0 wined3d_init+0xb3(wined3d=0x12d700, flags=0x5) [/home/focht/projects/wine/wine.repo/src/dlls/wined3d/directx.c:5233] in wined3d (0x0024c198) 5 0x7e4ba564 wined3d_create+0xc3(flags=<couldn't compute location>) [/home/focht/projects/wine/wine.repo/src/dlls/wined3d/wined3d_main.c:105] in wined3d (0x0024c208) 6 0x7e534f85 ddraw_init+0xa5(ddraw=0x11fb28, device_type=0) [/home/focht/projects/wine/wine.repo/src/dlls/ddraw/ddraw.c:4870] in ddraw (0x0024c3e8) 7 0x7e549038 DDRAW_Create+0x15f(guid=(nil), DD=0x855f74, UnkOuter=(nil), iid=0x7e576374) [/home/focht/projects/wine/wine.repo/src/dlls/ddraw/main.c:274] in ddraw (0x0024c458) 8 0x7e549249 DirectDrawCreate+0xac(driver_guid=<couldn't compute location>, ddraw=<couldn't compute location>, outer=<couldn't compute location>) [/home/focht/projects/wine/wine.repo/src/dlls/ddraw/main.c:309] in ddraw (0x0024c4a8) 9 0x00356cec in ptc (+0x16ceb) (0x0024c50c) 10 0x003514ed in ptc (+0x114ec) (0x00855f70) 11 0x00000000 (0x7e520000) 12 0x00000003 (0x00905a4d) ...
Wine-dbg>info reg Register dump: CS:0023 SS:002b DS:002b ES:002b FS:0063 GS:006b EIP:437b7e8b ESP:0024bab0 EBP:0024bb78 EFLAGS:00000202( - -- I - - - ) EAX:00000001 EBX:7e50e000 ECX:00008620 EDX:00000000 ESI:7e4d0e40 EDI:0012df04
Wine-dbg>bt Backtrace: =>0 0x43725bc0 in libnvidia-glcore.so.331.67 (+0x13e3bc0) (0x00000001) Wine-dbg>si 0x43725bc1: pushl %edi Wine-dbg> 0x43725bc2: pushl %esi Wine-dbg> 0x43725bc3: pushl %ebx Wine-dbg> 0x43725bc4: subl $0xb06c,%esp Wine-dbg> err:seh:setup_exception_record stack overflow 2304 bytes in thread 0039 eip 43725bca esp 00240a30 stack 0x240000-0x242000-0x340000 Process of pid=0038 has terminated --- snip ---
That "calculation" of course doesn't work with Wine due to the architectural differences to Windows (kernel/user components/gfx driver split).
There is a way to work around this stupid code though, making the demo still work.
Dump of PE optional header:
--- snip --- ->Optional Header Magic: 0x010B (HDR32_MAGIC) MajorLinkerVersion: 0x05 MinorLinkerVersion: 0x00 -> 5.00 SizeOfCode: 0x0000E000 SizeOfInitializedData: 0x00005E00 SizeOfUninitializedData: 0x00000000 AddressOfEntryPoint: 0x00007820 BaseOfCode: 0x00001000 BaseOfData: 0x0000F000 ImageBase: 0x00400000 SectionAlignment: 0x00001000 FileAlignment: 0x00000200 MajorOperatingSystemVersion: 0x0004 MinorOperatingSystemVersion: 0x0000 -> 4.00 MajorImageVersion: 0x0000 MinorImageVersion: 0x0000 -> 0.00 MajorSubsystemVersion: 0x0004 MinorSubsystemVersion: 0x0000 -> 4.00 Win32VersionValue: 0x00000000 SizeOfImage: 0x00016000 SizeOfHeaders: 0x00000400 CheckSum: 0x00000000 Subsystem: 0x0002 (WINDOWS_GUI) DllCharacteristics: 0x0000 SizeOfStackReserve: 0x00100000 SizeOfStackCommit: 0x00001000 SizeOfHeapReserve: 0x00100000 SizeOfHeapCommit: 0x00001000 LoaderFlags: 0x00000000 NumberOfRvaAndSizes: 0x00000010 --- snip ---
'SizeOfStackReserve' -> 0x100000 = 1MB thread stack (Windows default)
Use the following command to patch the executable PE optional header, changing 'SizeOfStackReserve' value to 2MB:
--- snip --- $ printf '\x20' | dd of=dotdot_TG1900Demo.exe bs=1 seek=226 count=1 conv=notrunc --- snip ---
$ sha1sum dotdot_non3d.zip 165674571849be7050208b622359821e36358ef0 dotdot_non3d.zip
$ du -sh dotdot_non3d.zip 3.8M dotdot_non3d.zip
$ wine --version wine-1.7.23
Regards