Re: Problem with std::vector bounds checking in VS 2005
sdiverdi schrieb:
I'm having some trouble with the bounds checking for stl::vector in VS
2005. When running code with an out of bounds error
(vector::operator[] with an index of say, -1), in debug mode, without
changing the defaults for _SCL_SECURE and _SCL_SECURE_THROW, as I
understand, there should be a debug assertion failed on the out of
bounds access. I wrote a small test program to see what happens, and
on the error, VS beeps and raises a dialog that says debug assertion
failed, and gives abort, retry and fail options. Clicking retry
causes a breakpoint to be triggered at the correct line. That's
great.
However, in my larger, more complicated programs, the behavior is not
as nice. One of two things happens on an out of bounds error. Option
one is I hear the beep, and the debug assertion failed dialog flashes
up on the screen very quickly (fast enough that I can't read it, I
just assume it's the correct error), and then the code jumps to a
(seemingly random) other assertion in my code (another function,
another file, etc.), and then raises a breakpoint. This was
frustrating for a while because I didn't realize that the assertion
where the breakpoint occurred wasn't actually the one that caused the
error. The other option is I hear the beep and the debug assertion
failed dialog comes up, but I can't click on the buttons. The dialog
stays up for maybe 10sec, and then the program terminates.
I don't really have any idea what might be causing the funny
behavior.
Your porblem is not the bounds check but how the runtime library handles the
asserts. What basically happens is that the assert call shows the dialog
allowing you to hit abort, retry or cancel. Problem is that this does not halt
the application, only the current thread, and for GUI apps it is even worse
because that dialog contains its own message loop letting even the current
thread continue to run. This can mess up the logic of your application,
generating additional failures in unrelated pieces of code, or even run into the
same assert recursively.
The solution depends on what type of application you are worling on: GUI or
Console. There are some API functions to change the default behaviiour. Have a
look at _CrtSetReportMode or _set_error_mode for a start.
In most cases I would be interested in the first failur cause and have the
application stop on the first assert ever. To do this, I set a break point on
the assert function itself. Either load the crt\src\assert.c file in the
debugger and set a breakpoint on the opening brace of the function _assert or
_wassert, or just write an assert(false) at the beginning of your function,
select the retry button, and locate _(w)assert on the call stack.
You do have the runtime library source code installed, don't you?
Norbert
It's a large program I'm testing, with multiple projects
compiled into libraries, external dependencies, lots of build
settings, etc. I'm hoping to avoid going through the (daunting) task
of paring down the large project to get a minimal set that reproduces
the behavior. Has anyone experienced something similar and have any
suggestions for how to get the proper debugging behavior working
again? I wasted a day and a half tracking down an out of bounds error
because of the bad reporting, when a correct error would have let me
fix it in a few minutes...
Thanks!
-stephen diverdi
-stephen.diverdi@gmail.com