Debug Error ESP not properly saved across functions

Started by
7 comments, last by MaulingMonkey 19 years, 7 months ago
Ok, when I run my program (using VC++ 6.0), the program generates a windows box error saying the following: Debug Error! Program:\Debug\MyProg.exe Module: File: i386\chkesp.c Line: 42 The value of ESP was not properly saved accross a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention. (press Retry to debug the application) [Abort][Retry][Ignore] Now then, what the heck does that mean? Where should I even start to debug my program? Let me tell you something about my program. I have a const varible in my global.h file called this: extern const int MaxMapHexes = 50; When I change the number to say, 40, I don't get the error. But I do get the error at 50. I also have a class using this varible like this:

class MyClass
{
// a bunch of functions and data
CHexCoords  hex[MaxMapHexes][MaxMapHexes]; // CHexCoord is a basic class containing two int varibles.
};

I also have another class which creates a STL List of MyClass. The only thing I can think of is an error when it copies the MyClass into the list using push_back? But I tried commenting out the push_back part of my functions, etc... I dont use any function pointers (unless <list> uses them). Please help me determine how to find the error! Some people from previous posts have said that it might be a calling convention, but I never use different calling conventions (to my knowledge). Please let me know what I can do to solve this problem.
Advertisement
Additional, I have double checked and triple checked my program. I always use MaxMapHexes, and have been extremly careful not to use "40" itself.

I am using VC++ 6.0, with win xp. I also am using the following headers: windows header, string, ctime, list, fstream, etc...

I have #pragma once in my StdAfx.h file...

I am trying to think of anything else you guys might need to help me determine the problem.

Fully rebuild the whole project including all libraries and DLLs.
How do I rebuild whole project? By selecting "clean" and then "rebuild all"?

If so, that didnt work.
Ok, I found out some information that may apply from Microsoft.

http://support.microsoft.com/default.aspx?scid=kb;en-us;822039&Product=vcc

According to them, the condition applies when the following conditions are true:

1) You call a function that does not use the __cdecl modifier.
2) The function contains parameters that are larger than 64 kilobytes (KB).
3) You compile your application in the Debug mode and with the /RTCs compiler option enabled.

Ok, I changed my MaxMapHexes back to 40, and sizeof(MyClass) was 57648. When MaxMapHexes was 50, sizeof(MyClass) is 90048. MyClass is passed as a parameter to a STL List (which I am guessing does not use __cdecl modifier.

Everyone with me so far?

Ok, my new question is this...
MyClass also contains string functions... if I have a MyClass with a long string value in a string (such as half a page of text or something), will this cause the program to crash when passed to a STL list, or are strings dynamic storage that is not part of the true class (just a pointer).
If the latter, then I can change the value to 40 and work with it... if the former, then my game is likely to crash during runtime if a string gets too big... Someone please advise on the best solution to this problem!
Yet again, I answered my own question! (heehee)

I created MyClass objects with different string values stored in them, and they all returned the same size! I guess I should have known that a STL string was really a single pointer and not a full blown value of what is inside.

This allows me to now rearange MyClass's data structure to stay within the "parameters" (pun intended).

By the way, noone answering my posts is bitter sweet.

Bitter = noone is helping me (except coffeemug)...

Sweet = I found the answer on my own, and maybe someone out there will benefit from it (plus I learned a bit myself).

Thanks.
Just out of curiosity, why the (*$^(#) are you passing that by value? That's 90KB that it has to copy every time you call that function!!!

The reason nobody's helping you is that nobody uses 90KB worth of function parameters, and thus don't know what the heck is wrong either.

The workaround would be to pass by reference or pointer. References are like pointers, but look just like normal variables. Observe:

void print_times5( int i ){    i *= 5; //multiply by 5    cout << i << endl;}void print_25( void ){    int i = 5;    print_times5( i ); //prints 25    assert( i == 5 );}


Can become:

void print_times5( int & i ) //<-- declaring a REFERENCE{    i *= 5; //multiply by 5    cout << i << endl;}void print_25( void ){     int i = 5;     print_times5( i );     assert( i == 25 ); //<-- ALERT!!! Because we used a REFERENCE, that "i *= 5;" actually modified the variable}


So it won't work if you're modifying the class in your function but don't want the class you're passing as an argument to be modified... unless you do something like:

void print_times5( int & i_ ){    int i = i_;    //rest of the code...}


On a 32 bit system, even if MyClass is 90KB in size, the functon:

void my_function( MyClass & myclass )


will only take 4 bytes worth of arguments.

You might want to take a look at std::vector, a resizable, dynamicly allocated array, which means you won't have to use up sizeof(CHexCoords) * MaxMapHexes * MaxMapHexes... instead, you'll use up sizeof(CHexCoords) * UsedMaxHexes * UsedMaxHexes + a little overhead for std::vector.
Your ranting and raving may have some points...

I pass by reference whenever I can (even though the project doesn't have to run at a 30 fps speed, it would be nice to do some animations...).

I was under the impression that STL List was the problem and was the thing doing the passing (and the one thing not using the standard calling convention like everything else in my code is)... which I can't control.

I am going to double check my code and ensure that I am not copy things that shouldn't be copied on the heap.

Thanks.

PS: Try and cheer up, man. Geez, I'm new at this. Cut me some slack. At least I can figure out my own errors, and this one was a doozy. :P
Quote:Original post by TheSkywise
Your ranting and raving may have some points...

I pass by reference whenever I can (even though the project doesn't have to run at a 30 fps speed, it would be nice to do some animations...).

I was under the impression that STL List was the problem and was the thing doing the passing (and the one thing not using the standard calling convention like everything else in my code is)... which I can't control.

I am going to double check my code and ensure that I am not copy things that shouldn't be copied on the heap.


You should allways be able to pass at least by const referance ( const MyClass & const_reference_to_my_class )... which should then allways allow you to copy to the heap if you need to modify any variables. I'm guessing the issue arises from a different default calling convention being used for functions with > 64kb of parameters that the debuger is not aware of, and thus goes bezerk when it dosn't understand what's going on.

Quote:PS: Try and cheer up, man. Geez, I'm new at this. Cut me some slack. At least I can figure out my own errors, and this one was a doozy. :P


If I was serious, I wouldn't have @(#$*%@!#( ed out my words ;-). Plus, it got the point across... didn't it? Oh yeah, and remaining girlfriendless for my 2nd year running gives me the right to stay a grouch... so there! :p

Also, switching to vectors should solve your array problem too, as the data is allocated dynamically and referenced as a pointer. It will still copy all the data (and incur that performance hit), however. Arrays of Max*Length size are really holdbacks from the old C syntaxes anyways, something I really prefer to avoid.

This topic is closed to new replies.

Advertisement