Data corruption with SDL + Visual C++ 2k8 Optimizations
I'm getting data corruption on my program when using SDL with Visual C++ 2008 compiler optimizations. For example, issuing the call
tr->generatePerlinNoise ( 4, 0.1 );
fails because the generatePerlinNoise method gets a garbage value (e.g 498542) as actual parameter. This does not occur when using no-optimization compilation. Also, argc and argv become garbage as well.
I'm using SDL 1.2 built from sources in VC++2008 (no errors).
Let's see this code section:
int main(int argc, char** argv)
{
CTerrain * tr = new CTerrain(384);
tr->generatePerlinNoise ( 4, 0.1 );
delete tr;
return 0;
}
With no optimizations, correct output code is generated:
int main(int argc, char* argv[])
{
00411F70 push ebp
00411F71 mov ebp,esp
00411F73 sub esp,1A0h
00411F79 push ebx
00411F7A push esi
00411F7B push edi
00411F7C lea edi,[ebp-1A0h]
00411F82 mov ecx,68h
00411F87 mov eax,0CCCCCCCCh
00411F8C rep stos dword ptr es:[edi]
CGfxcore* gfxc = new CGfxcore();
00411F8E push 4
00411F90 call operator new (41150Ah)
00411F95 add esp,4
00411F98 mov dword ptr [ebp-18Ch],eax
00411F9E cmp dword ptr [ebp-18Ch],0
00411FA5 je SDL_main+4Ah (411FBAh)
00411FA7 mov ecx,dword ptr [ebp-18Ch]
00411FAD call CGfxcore::CGfxcore (4111F9h)
00411FB2 mov dword ptr [ebp-1A0h],eax
00411FB8 jmp SDL_main+54h (411FC4h)
00411FBA mov dword ptr [ebp-1A0h],0
00411FC4 mov eax,dword ptr [ebp-1A0h]
00411FCA mov dword ptr [ebp-198h],eax
00411FD0 mov ecx,dword ptr [ebp-198h]
00411FD6 mov dword ptr [gfxc],ecx
SDL_Event ev;
bool running = true;
00411FD9 mov byte ptr [running],1
atexit (SDL_Quit);
00411FDD push offset @ILT+60(_SDL_Quit) (411041h)
00411FE2 call @ILT+490(_atexit) (4111EFh)
00411FE7 add esp,4
if (!(gfxc->initialize(640,480,32)))
00411FEA push 20h
00411FEC push 1E0h
00411FF1 push 280h
00411FF6 mov ecx,dword ptr [gfxc]
00411FF9 call CGfxcore::initialize (41104Bh)
00411FFE movzx eax,al
00412001 test eax,eax
00412003 jne SDL_main+0F1h (412061h)
{
printf("Error initializing SDL\n");
00412005 mov esi,esp
00412007 push offset string "Error initializing SDL\n" (41E84Ch)
0041200C call dword ptr [__imp__printf (423584h)]
00412012 add esp,4
00412015 cmp esi,esp
00412017 call @ILT+1075(__RTC_CheckEsp) (411438h)
delete gfxc;
0041201C mov eax,dword ptr [gfxc]
0041201F mov dword ptr [ebp-174h],eax
00412025 mov ecx,dword ptr [ebp-174h]
0041202B mov dword ptr [ebp-180h],ecx
00412031 cmp dword ptr [ebp-180h],0
00412038 je SDL_main+0DFh (41204Fh)
0041203A push 1
0041203C mov ecx,dword ptr [ebp-180h]
00412042 call CGfxcore::`scalar deleting destructor' (411366h)
00412047 mov dword ptr [ebp-1A0h],eax
0041204D jmp SDL_main+0E9h (412059h)
0041204F mov dword ptr [ebp-1A0h],0
return -1;
00412059 or eax,0FFFFFFFFh
0041205C jmp SDL_main+2C0h (412230h)
}
CTerrain * tr = new CTerrain(384);
00412061 push 8
00412063 call operator new (41150Ah)
00412068 add esp,4
0041206B mov dword ptr [ebp-15Ch],eax
00412071 cmp dword ptr [ebp-15Ch],0
00412078 je SDL_main+122h (412092h)
0041207A push 180h
0041207F mov ecx,dword ptr [ebp-15Ch]
00412085 call CTerrain::CTerrain (411172h)
0041208A mov dword ptr [ebp-1A0h],eax
00412090 jmp SDL_main+12Ch (41209Ch)
00412092 mov dword ptr [ebp-1A0h],0
0041209C mov eax,dword ptr [ebp-1A0h]
004120A2 mov dword ptr [ebp-168h],eax
004120A8 mov ecx,dword ptr [ebp-168h]
004120AE mov dword ptr [tr],ecx
tr->generatePerlinNoise ( 1, 0.25 );
004120B1 sub esp,8
004120B4 fld qword ptr [__real@3fd0000000000000 (41E840h)]
004120BA fstp qword ptr [esp]
004120BD push 1
004120BF mov ecx,dword ptr [tr]
004120C2 call CTerrain::generatePerlinNoise (411564h)
Now see the mess with optimizations enabled (Optimize for speed):
--- c:\documents and settings\hernan\mis documentos\visual studio 2008\projects\sdl1\sdl1\main.cpp
00401002 in al,dx
00401003 and esp,0FFFFFFC0h
00401006 sub esp,30h
00401009 push ebx
0040100A push ebp
0040100B push esi
0040100C push edi
CGfxcore* gfxc = new CGfxcore();
0040100D push 4
0040100F call operator new (4017D4h)
00401014 add esp,4
SDL_Event ev;
bool running = true;
atexit (SDL_Quit);
00401017 push offset SDL_Quit (401F7Eh)
0040101C mov ebp,eax
0040101E mov byte ptr [esp+27h],1
00401023 call atexit (4017B6h)
00401028 add esp,4
if (!(gfxc->initialize(640,480,32)))
0040102B push 100020h
00401030 call SDL_Init (401F6Ch)
00401035 add esp,4
00401038 test eax,eax
0040103A jne SDL_main+86h (401086h)
0040103C push 40000001h
00401041 push 20h
00401043 push 1E0h
00401048 push 280h
0040104D call SDL_SetVideoMode (401F72h)
00401052 add esp,10h
#endif
extern "C" int main(int argc, char* argv[])
{
CGfxcore* gfxc = new CGfxcore();
SDL_Event ev;
bool running = true;
atexit (SDL_Quit);
if (!(gfxc->initialize(640,480,32)))
{
printf("Error initializing SDL\n");
delete gfxc;
return -1;
}
CTerrain * tr = new CTerrain(384);
00401055 push 8
00401057 mov dword ptr [ebp],eax
0040105A call operator new (4017D4h)
0040105F mov esi,eax
00401061 xor ebx,ebx
00401063 add esp,4
00401066 cmp esi,ebx
00401068 je SDL_main+0C1h (4010C1h)
0040106A push 24000h
0040106F mov dword ptr [esi+4],180h
00401076 call operator new (4017D4h)
0040107B add esp,4
0040107E mov dword ptr [esi],eax
00401080 mov dword ptr [esp+28h],esi
00401084 jmp SDL_main+0C7h (4010C7h)
{
printf("Error initializing SDL\n");
00401086 push 403288h
0040108B call dword ptr [__imp__printf (4030F4h)]
00401091 add esp,4
delete gfxc;
00401094 test ebp,ebp
00401096 je SDL_main+0B6h (4010B6h)
00401098 mov eax,dword ptr [ebp]
0040109B test eax,eax
0040109D je SDL_main+0A8h (4010A8h)
0040109F push eax
004010A0 call SDL_FreeSurface (401F84h)
004010A5 add esp,4
004010A8 call SDL_Quit (401F7Eh)
004010AD push ebp
004010AE call operator delete (4017CEh)
004010B3 add esp,4
return -1;
004010B6 or eax,0FFFFFFFFh
while (running)
{
SDL_PollEvent(&ev);
if (ev.type == SDL_KEYDOWN)
if (ev.key.keysym.sym == SDLK_ESCAPE )
running = false;
//glClear(GL_COLOR_BUFFER_BIT);
SDL_Flip(gfxc->getSurface());
//SDL_GL_SwapBuffers();
}
delete gfxc;
delete tr;
return 0;
}
004010B9 pop edi
004010BA pop esi
004010BB pop ebp
004010BC pop ebx
004010BD mov esp,ebp
004010BF pop ebp
004010C0 ret
}
CTerrain * tr = new CTerrain(384);
004010C1 mov dword ptr [esp+28h],ebx
004010C5 mov esi,ebx
tr->generatePerlinNoise ( 1, 0.25 );
004010C7 fld qword ptr [__real@3fd0000000000000 (4032D0h)]
004010CD sub esp,8
004010D0 fstp qword ptr [esp]
004010D3 call CTerrain::generatePerlinNoise (4015B0h)
Anyone suffered this problem in this or previous versions of VC++?
thanks in advance.
If you're using the debugger to inspect the variables themselves in release code you're going to see garbage values, because the variables are usually not where the debugger expects them to be due to said optimizations. This doesn't mean your code is broken, it just means you can't use this feature of the debugger on release code and expect accurate results.
Having said that, those values do look broken. The integer parameter doesn't seem to be on the stack and the this pointer isn't being set up at all. The only way that could work is if the generatePerlinNoise has been compiled significantly differently, eg. as a static function rather than a member, and ignoring the first parameter somehow.
(Note to original poster: the code you compiled is not exactly the code you posted at the start - ( 4, 0.1 ) vs ( 1, 0.25 ). )
(Note to original poster: the code you compiled is not exactly the code you posted at the start - ( 4, 0.1 ) vs ( 1, 0.25 ). )
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement