[Bug 36737] Steel Armor: Blaze of War crashes on start with built-in msvcr80 (malloc and operator new are required to return memory on a 16-byte boundary)

wine-bugs at winehq.org wine-bugs at winehq.org
Sun Jun 15 12:48:29 CDT 2014


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

Anastasius Focht <focht at gmx.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |focht at gmx.net
            Summary|Steel Armor: Blaze of War   |Steel Armor: Blaze of War
                   |crashes on start with       |crashes on start with
                   |built-in msvcr80            |built-in msvcr80 (malloc
                   |                            |and operator new are
                   |                            |required to return memory
                   |                            |on a 16-byte boundary)

--- Comment #2 from Anastasius Focht <focht at gmx.net> ---
Hello folks,

confirming.

I found a distributed "backup" and debugged it.

--- snip ---
$ WINEDEBUG=+tid,+seh,+relay,+snoop,+msvcrt wine ./starter.exe
root/programs/topgame.progpack >>log.txt 2>&1
...
0024:Call KERNEL32.LoadLibraryA(0083a71d "bin\\rel\\x86\\adv_render.codelib")
ret=1000a810 
...
0024:Ret  KERNEL32.LoadLibraryA() retval=00c10000 ret=1000a810
...
0024:Call msvcr80._aligned_malloc(00000004,00000010) ret=00c28336
0024:trace:msvcrt:_aligned_malloc (4, 16)
0024:trace:msvcrt:_aligned_offset_malloc (4, 16, 0)
0024:Call ntdll.RtlAllocateHeap(00820000,00000000,00000018) ret=7e2f1515
0024:Ret  ntdll.RtlAllocateHeap() retval=0089ed00 ret=7e2f1515
0024:Ret  msvcr80._aligned_malloc() retval=0089ed10 ret=00c28336
0024:Call msvcr80._aligned_malloc(00000004,00000010) ret=00c3b2cd
0024:trace:msvcrt:_aligned_malloc (4, 16)
0024:trace:msvcrt:_aligned_offset_malloc (4, 16, 0)
0024:Call ntdll.RtlAllocateHeap(00820000,00000000,00000018) ret=7e2f1515
0024:Ret  ntdll.RtlAllocateHeap() retval=008a41f8 ret=7e2f1515
0024:Ret  msvcr80._aligned_malloc() retval=008a4200 ret=00c3b2cd
0024:Call msvcr80.memcpy(008a4200,00000000,00000000) ret=00c3b2e0
0024:Ret  msvcr80.memcpy() retval=008a4200 ret=00c3b2e0
0024:Call msvcr80.??2 at YAPAXI@Z(00000150) ret=00c24c6e
0024:Call ntdll.RtlAllocateHeap(00820000,00000000,00000150) ret=7e2f0c03
0024:Ret  ntdll.RtlAllocateHeap() retval=008a18b8 ret=7e2f0c03
0024:trace:msvcrt:MSVCRT_operator_new (336) returning 0x8a18b8
0024:Ret  msvcr80.??2 at YAPAXI@Z() retval=008a18b8 ret=00c24c6e
0024:trace:seh:raise_exception code=c0000005 flags=0 addr=0xc242b7 ip=00c242b7
tid=0024
0024:trace:seh:raise_exception  info[0]=00000000
0024:trace:seh:raise_exception  info[1]=ffffffff
0024:trace:seh:raise_exception  eax=008a18b8 ebx=00873950 ecx=008a4200
edx=7bcecbc8 esi=00000000 edi=00872960
0024:trace:seh:raise_exception  ebp=0081d4a0 esp=0081d3ec cs=0023 ds=002b
es=002b fs=0063 gs=006b flags=00010206
0024:trace:seh:call_stack_handlers calling handler at 0x3d4d00 code=c0000005
flags=0 
...
--- snip ---

Although the game engine makes explicit use of '_aligned_malloc' to ensure
16-byte alignment for SSE instructions it also uses traditional MSVCRT operator
'new'.

It seems that 'msvcr80.MSVCRT_operator_new' must return 16-byte aligned memory
chunks too.

--- snip ---
...
00C04C5E   8BF0                  MOV ESI,EAX
00C04C60   68 50010000           PUSH 150
00C04C65   897424 30             MOV DWORD PTR SS:[ESP+30],ESI
00C04C69   E8 207D0100           CALL <JMP.&MSVCR80.??2 at YAPAXI@Z>
00C04C6E   83C4 04               ADD ESP,4
00C04C71   85C0                  TEST EAX,EAX
00C04C73   74 07                 JE SHORT adv_rend.00C04C7C
00C04C75   E8 36F6FFFF           CALL adv_rend.00C042B0
00C04C7A   EB 02                 JMP SHORT adv_rend.00C04C7E
00C04C7C   33C0                  XOR EAX,EAX
...
00C042B0   0F2805 F0CEC200       MOVAPS XMM0,DQWORD PTR DS:[C2CEF0]
00C042B7   0F2900                MOVAPS DQWORD PTR DS:[EAX],XMM0      ; boom
00C042BA   0F280D 00CFC200       MOVAPS XMM1,DQWORD PTR DS:[C2CF00]
00C042C1   0F2948 10             MOVAPS DQWORD PTR DS:[EAX+10],XMM1
00C042C5   0F2815 10CFC200       MOVAPS XMM2,DQWORD PTR DS:[C2CF10]
00C042CC   0F2950 20             MOVAPS DQWORD PTR DS:[EAX+20],XMM2
00C042D0   0F281D 20CFC200       MOVAPS XMM3,DQWORD PTR DS:[C2CF20]
00C042D7   0F2958 30             MOVAPS DQWORD PTR DS:[EAX+30],XMM3
00C042DB   0F2940 40             MOVAPS DQWORD PTR DS:[EAX+40],XMM0
00C042DF   0F2948 50             MOVAPS DQWORD PTR DS:[EAX+50],XMM1
00C042E3   0F2950 60             MOVAPS DQWORD PTR DS:[EAX+60],XMM2
00C042E7   0F2958 70             MOVAPS DQWORD PTR DS:[EAX+70],XMM3
00C042EB   F3:0F1005 0CE5C200    MOVSS XMM0,DWORD PTR DS:[C2E50C]
00C042F3   F3:0F1180 80000000    MOVSS DWORD PTR DS:[EAX+80],XMM0
00C042FB   F3:0F1180 84000000    MOVSS DWORD PTR DS:[EAX+84],XMM0
--- snip ---

Interestingly the MSDN pages for various Visual Studio versions make different
statements regarding 'malloc' alignment:

http://msdn.microsoft.com/en-us/library/ycsb6wwf%28vs.95%29.aspx

--- quote ---
malloc Alignment

Visual Studio 2005

malloc is required to return memory on a 16-byte boundary.
--- quote ---

http://msdn.microsoft.com/en-us/library/ycsb6wwf%28vs.90%29.aspx

--- quote ---
malloc Alignment

Visual Studio 2008

malloc is required to return memory on a 16-byte boundary.
--- quote ---

http://msdn.microsoft.com/en-us/library/ycsb6wwf%28vs.100%29.aspx

--- quote ---
malloc Alignment

Visual Studio 2010

malloc is guaranteed to return memory that's aligned on a boundary that's
suitable for storing any object that could fit in the amount of memory that's
allocated. For example, a four-byte allocation is aligned on a boundary that
supports any four-byte or smaller object. Memory alignment on a boundary that's
suitable for an object that's larger than will fit in the allocation is not
guaranteed.
--- quote ---

http://msdn.microsoft.com/en-us/library/ycsb6wwf%28vs.110%29.aspx

--- quote ---
malloc Alignment

Visual Studio 2012

malloc is guaranteed to return memory that's aligned on a boundary that's
suitable for storing any object that could fit in the amount of memory that's
allocated. For example, a four-byte allocation would be aligned on a boundary
that supports any four-byte or smaller object. Memory alignment on a boundary
that's suitable for a larger object than will fit in the allocation is not
guaranteed.
--- quote ---

http://msdn.microsoft.com/en-us/library/ycsb6wwf.aspx

--- quote ---
malloc Alignment

Visual Studio 2013

malloc is guaranteed to return memory that's suitably aligned for storing any
object that has a fundamental alignment and that could fit in the amount of
memory that's allocated. A fundamental alignment is an alignment that's less
than or equal to the largest alignment that's supported by the implementation
without an alignment specification. (In Visual C++, this is the alignment
that's required for a double, or 8 bytes. In code that targets 64-bit
platforms, it’s 16 bytes.) For example, a four-byte allocation would be aligned
on a boundary that supports any four-byte or smaller object.
--- quote ---

With that part fixed the game runs further.

Regards

-- 
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