how to stop VS 2005 handling a buffer overrun exception

This topic is 3570 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

i am purposely causing buffer overrun in the following code. what i want to know is there a way i can stop VS2005 to handle this exception for which it shows a pop-up screen when i run the code in debug mode ? i want to run the code normally, like it would run from an exe file. the code itself catches the exception and VS2005 doesn't interfere by showing that exception pop-up screen. anyone can help me this ?
void myMethod(char * pStr)
{
char pBuff[10];

int nCount = 0;

strcpy_s(pBuff, pStr);
}

int main(void)
{
char *pStr = "this should cause a buffer overrun";
try
{
myMethod(pStr);
}
catch(exception &e)
{
cout << "C++ exception caught!";
}

cout<<"All went good!! ";
getch();
}


Share on other sites
Over-allocate. That's the only "safe" way to overflow.

This approach is used by aligned allocators. They allocate a block +4/8/16/32 bytes. This way, they can then serve aligned addresses that could cause overflow.

Real overrun however is undefined behavior. No matter how much you try, exception is the least of your problems. In release mode, it'll just behave in many unusual ways, even if you think you're handling them.

Another thing of notice, what you're actually doing is overflowing on stack, which is much worse than overflowing the heap.

But.... What are you trying to do?

Share on other sites
I'm not sure why you want to, but go into the project properties and look in C/C++->Code Generation. You probably want to set "Buffer Security Check" to "No".

HTH.

Share on other sites
you could just check the length for an overflow exception:

enum E_EXCEPTIONS{   BUFFER_OVERFLOW};void myMethod(char *pStr) {    #define BUFFER_SIZE 10    char pBuff[BUFFER_SIZE];    if(strlen(pStr) > BUFFER_SIZE)       throw BUFFER_OVERFLOW;    else    {       int nCount = 0;	strcpy_s(pBuff, pStr);    }}int main(){   try   {      myMethod("this should cause a buffer overrun");   } catch (E_EXCEPTIONS e)   {      switch(e)      {      case BUFFER_OVERFLOW:         std::cout << "C++ exception caught!\n";         break;      }   }}

Share on other sites
Your code, as posted, does not cause an exception. It triggers an assertion. This isn't handled by the debugger; the code to bring up the dialog box is actually part of your executable.

Share on other sites
C++ doesn't throw exceptions when you overflow plain arrays like that.

The "normal behavior" of your code if MSVC wasn't detecting it would most likely be to crash because your stack is now corrupt. Other perfectly normal behaviors would be to "work" in debug and crash in retail, mysteriously crash later on in some unpredictable place for no apparent reason, and just plain have variables go all wrong on you.

You can't really catch such things and have your program continue to work reliably.

Share on other sites
it seems that it wouldn't work by catching the exception.

here is my scenario which is causing the problem.

i have a server which runs my core application providing many services. Every now and then my team put up new dlls into it. the core is basically a services application server. what happens is, that i cannot keep track of every new dlls that has been deployed on to the server. but sometimes because of bad programming in new dlls, the core application crashes. its true that since exception handling in C++ is difficult and there is no general class to catch all possible exception. so i cannot determine what exception may cause application server to halt.

now since its not a desktop machine, its a server machine where the core and other dlls are deployed and they all runs as different services. when the above crash occurs, it holds the core application into a paused state and shows:

in runtime: Windows error reporting message is shown(where user have to select "Send Error Report" or "Don't Send")

in debug mode: that visual studio pop-up shows up(where user have to select "Abort" or "Retry" or "Ignore")

either way, an input is always required. and since this all is on a server machine, its obvious that nobody would be monitoring it all day.
i have even deployed a script to check if the core application is in stop mode, it would restart the system and start the core application again. but the script is of no use as well, since this input form is opened right after anything goes wrong. and it needs an input from the user and unless an input is provided, the core application stays in running state, which makes the script totally useless.

so my question,
is there any way i can disable these input forms
or
a way to detect the error without any human involvement.

Share on other sites
Have a look at SetErrorMode and see if it helps in any way. http://msdn.microsoft.com/en-us/library/ms680621(VS.85).aspx

Share on other sites
nope the pop-up is still appearing.

it would be better if i can detect the pop-up showing up for my application, and run a script which would restart the application services.

any idea how i can do this ?

Share on other sites
You could do wrap the whole program in a structured exception handler. Something like:

int main(void){  __try { real_main(); }  __finally { return 0; }}

See http://msdn.microsoft.com/en-us/library/s58ftw19(VS.80).aspx for details.

Note that doing anything other than exiting when you hit the exception is probably a bad thing because the program will be in an unknown state. In fact just catching structured exceptions and restarting the app can cause security issues.

What you should probably do instead is to get hold of the minidump the app makes when it crashes, and use that to debug and fix the error. You could even run it under a debugger using the standard remote debug tools that come with Visual Studio.

Share on other sites

What's happening in the retail case is that the OS is detecting you crashed and is offering to run a debugger for you. Since you don't have a debugger configured it runs Watson to do some automatic reporting. You should do the AutoExclusionList stuff if you can or if you can't you can just register a dummy "debugger" that doesn't actually do anything so that you app will crash silently.

Actually the really cool thing to do would be to install the SDK debuggers and configure aedebug to generate a minidump before shutting down the process. Then you at least have a hope of doing some post-mortem debugging.

The debug case is completely different. Here it's runtime code in the process itself detecting that you've done something bad. VC comes with source for the CRT so there may be something in there that allows you to hook the dialog, I don't know.

Share on other sites
There's quite a bit of misinformation in this thread. strcpy_s performs parameter validation. If it determines that the given buffer is not large enough for the source string then it calls the invalid parameter handler. In debug mode the default invalid parameter handler displays an assert message and then invokes Watson crash reporting. In release mode the default invalid parameter handler invokes Watson crash reporting without displaying an assert.

The correct solution to this problem then is either to install a different invalid parameter handler or to not use strcpy_s.

Σnigma

Share on other sites
Enigma:
that first code i used as an example, i described my problem in detail later. read that and you will understand what its about. hopefully you wont be confused then.
because i wouldn't know what sort of exception or bad coding is done on dlls, i can't keep track of all the new dlls. so all i can hope is to find a way to restart my core service(or the whole server)without human intervention as soon as something goes wrong.

Anon Mike:
your solution makes a lot of sense. ill try it out today. :)
lets see.

Share on other sites
I think the structured exception handling catch suggested by Adam_42 should work, but I'd recommend taking a look at this for a more complete solution. I've yet to use it in a newer version of VC, but it was brilliant for tracking down crashes that happen on other people's computers. No debugger required.