From: Charlie Gibbs on
In article
<1509753c-6b6d-4459-8db0-13597ede8843(a)h37g2000pra.googlegroups.com>,
rsharma.champ(a)gmail.com (Rahul) writes:

> Thanks Alf,
>
> So infinite recursion and large stack based array's seems to be the
> problem. But why does the default debugger not catch these crashes.
> I even tried on the system where Visual Studio was installed, It also
> failed to catch those exceptions (unless we run the program the inside
> debugger itself)
>
> Is there any way to catch these crashes without running the program in
> the debugger, and why are they not caught by the debugger by default
> (just for understanding the technical difficulty involved in this).

My favourite way of dealing with these things is to define a buffer
on either site of the local variables:

void myfunc ()
{
char buffer1[512];
... other local variables ...
char buffer2[512];

memset ((void *) buffer1, 0, sizeof (buffer1));
memset ((void *) buffer2, 0, sizeof (buffer2));
... code ...
}

Often that's enough to stop the mysterious disappearances. You can
then check "buffer1" and "buffer2" at various points in the code to
see whether they suddenly become nonzero. That should catch simple
overflows, but a truly wild pointer could clobber the stack far
enough away that nothing bad happens until the program exits.
Still, it's a start...

--
/~\ cgibbs(a)kltpzyxm.invalid (Charlie Gibbs)
\ / I'm really at ac.dekanfrus if you read it the right way.
X Top-posted messages will probably be ignored. See RFC1855.
/ \ HTML will DEFINITELY be ignored. Join the ASCII ribbon campaign!

From: Joseph M. Newcomer on
See below...
On 05 May 10 15:19:03 -0800, "Charlie Gibbs" <cgibbs(a)kltpzyxm.invalid> wrote:

>In article
><1509753c-6b6d-4459-8db0-13597ede8843(a)h37g2000pra.googlegroups.com>,
>rsharma.champ(a)gmail.com (Rahul) writes:
>
>> Thanks Alf,
>>
>> So infinite recursion and large stack based array's seems to be the
>> problem. But why does the default debugger not catch these crashes.
>> I even tried on the system where Visual Studio was installed, It also
>> failed to catch those exceptions (unless we run the program the inside
>> debugger itself)
>>
>> Is there any way to catch these crashes without running the program in
>> the debugger, and why are they not caught by the debugger by default
>> (just for understanding the technical difficulty involved in this).
>
>My favourite way of dealing with these things is to define a buffer
>on either site of the local variables:
>
>void myfunc ()
>{
> char buffer1[512];
****
Generally, a C++ programmer should never write a declaration of the form
type name[compile-time-constant-expression];
Not even for local buffers; I tend to do

CByteArray buffer;
buffer.SetSize(512);
ReadFile(f, buffer.GetData(), (DWORD)buffer.GetSize(), &bytesRead, NULL);

The data is not on the stack, and is automatically cleaned up when the variable leaves
scope. You can do an analogous trick with std::vector<BYTE>. It is always best to use
the BYTE data type for input buffers, since it eliminates any potential confusion that
might arise when Unicode comes into play.
*****
.....
> ... other local variables ...
> char buffer2[512];
>
> memset ((void *) buffer1, 0, sizeof (buffer1));
> memset ((void *) buffer2, 0, sizeof (buffer2));
****
This code is alwyas deeply suspect. Why memset to 0 something that is going to be
overwritten by input data? Bad programming style, generally. And use ::ZeroMemory
instead of the 1975 PDP-11 model taught by amateur teachers. Better still, don't do it at
all!

If the code is so badly written that the buffer MUST be zeroed out, note that I said "so
badly written". I find little excuse for doing the memset-to-zero as a substitute for
responsible programming.
joe
******
> ... code ...
>}
>
>Often that's enough to stop the mysterious disappearances. You can
>then check "buffer1" and "buffer2" at various points in the code to
>see whether they suddenly become nonzero. That should catch simple
>overflows, but a truly wild pointer could clobber the stack far
>enough away that nothing bad happens until the program exits.
>Still, it's a start...
****
Note that VS > 2003 will catch buffer overruns in debug mode; I fined no compelling reason
to use anitque versions of VS which have poor error detection in the marginally-correct
compilers that compile a language similar to, but not actually, C++.

A cause no one has mentioned is the horrendous technique of putting exit() calls into the
code to handle error conditions. This has never made sense in the history of programming,
in any language; it was a stupid idea in C on the PDP-11 and a more stupid idea in C++
and Windows. I've caught a number of "the program just disappears" bugs by finding all
exit() calls under various guises.
joe
*****
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Rahul on
On May 6, 6:18 am, Joseph M. Newcomer <newco...(a)flounder.com> wrote:
> See below...
> On 05 May 10 15:19:03 -0800, "Charlie Gibbs" <cgi...(a)kltpzyxm.invalid> wrote:
>
>
>
>
>
> >In article
> ><1509753c-6b6d-4459-8db0-13597ede8...(a)h37g2000pra.googlegroups.com>,
> >rsharma.ch...(a)gmail.com (Rahul) writes:
>
> >> Thanks Alf,
>
> >> So infinite recursion and large stack based array's seems to be the
> >> problem. But why does the default debugger not catch these crashes.
> >> I even tried on the system where Visual Studio was installed, It also
> >> failed to catch those exceptions (unless we run the program the inside
> >> debugger itself)
>
> >> Is there any way to catch these crashes without running the program in
> >> the debugger, and why are they not caught by the debugger by default
> >> (just for understanding the technical difficulty involved in this).
>
> >My favourite way of dealing with these things is to define a buffer
> >on either site of the local variables:
>
> >void myfunc ()
> >{
> >    char buffer1[512];
>
> ****
> Generally, a C++ programmer should never write  a declaration of the form
>         type name[compile-time-constant-expression];
> Not even for local buffers; I tend to do
>
>         CByteArray buffer;
>         buffer.SetSize(512);
>         ReadFile(f, buffer.GetData(), (DWORD)buffer.GetSize(), &bytesRead, NULL);
>
> The data is not on the stack, and is automatically cleaned up when the variable leaves
> scope.  You can do an analogous trick with std::vector<BYTE>.  It is always best to use
> the BYTE data type for input buffers, since it eliminates any potential confusion that
> might arise when Unicode comes into play.
> *****
>         .....>    ... other local variables ...
> >    char buffer2[512];
>
> >    memset ((void *) buffer1, 0, sizeof (buffer1));
> >    memset ((void *) buffer2, 0, sizeof (buffer2));
>
> ****
> This code is alwyas deeply suspect.   Why memset to 0 something that is going to be
> overwritten by input data?  Bad programming style, generally.  And use ::ZeroMemory
> instead of the 1975 PDP-11 model taught by amateur teachers.  Better still, don't do it at
> all!
>
> If the code is so badly written that the buffer MUST be zeroed out, note that I said "so
> badly written".  I find little excuse for doing the memset-to-zero as a substitute for
> responsible programming.
>                                 joe
> ******>    ... code ...
> >}
>
> >Often that's enough to stop the mysterious disappearances.  You can
> >then check "buffer1" and "buffer2" at various points in the code to
> >see whether they suddenly become nonzero.  That should catch simple
> >overflows, but a truly wild pointer could clobber the stack far
> >enough away that nothing bad happens until the program exits.
> >Still, it's a start...
>
> ****
> Note that VS > 2003 will catch buffer overruns in debug mode; I fined no compelling reason
> to use anitque versions of VS which have poor error detection in the marginally-correct
> compilers that compile a language similar to, but not actually, C++.
>
> A cause no one has mentioned is the horrendous technique of putting exit() calls into the
> code to handle error conditions.  This has never made sense in the history of programming,
> in any language;  it was a stupid idea in C on the PDP-11 and a more stupid idea in C++
> and Windows.  I've caught a number of "the program just disappears" bugs by finding all
> exit() calls under various guises.
>                                 joe
> *****
> Joseph M. Newcomer [MVP]
> email: newco...(a)flounder.com
> Web:http://www.flounder.com
> MVP Tips:http://www.flounder.com/mvp_tips.htm


I tried reproducing the issue and found that this happens sometimes
when the VM space exhausts. I was running the application in debugger
and at one point of time (When the virtual size was 1.84 GB) the
process suddenly hung, I tried breaking in the debugger but debugger
could not show any stack, Then I did a "Detach All" in VC++ debugger
and the process just vanished after 10-12 seconds.

As per the general behavior when some memory allocation fails then an
Access violation should happen which should get caught in the
debugger, but is there any way that memory exhaustion could cause the
application to vanish (may be depending on where the allocation
failure happened, perhaps in the kernel code etc.)

Regards
Rahul
From: r_z_aret on
On Wed, 5 May 2010 10:58:29 -0700 (PDT), Rahul
<rsharma.champ(a)gmail.com> wrote:

>Thanks Alf,
>
>So infinite recursion and large stack based array's seems to be the
>problem. But why does the default debugger not catch these crashes.
>I even tried on the system where Visual Studio was installed, It also
>failed to catch those exceptions (unless we run the program the inside
>debugger itself)
>
>Is there any way to catch these crashes without running the program in
>the debugger,

Adding ASSERTs to do sanity checks on pointers just before they are
used can trap many pointer problems. This is less painful if done
while coding. With luck and thought, you might be able to add them
iteratively now: add some in places most likely to trap an error, keep
adding until one triggers, then use the one that triggered to choose
where to add more. Repeat as necessary.

ASSERTs to test arrays that might be clobbered give less direct clues,
but are better than nothing. And some clues you see while running a
program point more directly to an array.

Adding some way to monitor progress of the program can help you find
the part of your source code that causes a crash. I've used calls to
MessageBox. I add at least one to code I'm pretty sure runs before the
crash and at least one to code I'm pretty sure runs after the crash.
And after each crash, I narrow the gap between calls. This is very low
tech, and seems painful. But often enough, I can rather quickly narrow
the gap enough for me to see the likely problem, blanket the code with
ASSERTs, and/or step through with a debugger.

>
>Thanks
>Rahul

-----------------------------------------
To reply to me, remove the underscores (_) from my email address (and please indicate which newsgroup and message).

Robert E. Zaret, MVP
PenFact, Inc.
20 Park Plaza, Suite 400
Boston, MA 02116
www.penfact.com
Useful reading (be sure to read its disclaimer first):
http://catb.org/~esr/faqs/smart-questions.html
From: Joseph M. Newcomer on
See below...
On Thu, 6 May 2010 06:08:33 -0700 (PDT), Rahul <rsharma.champ(a)gmail.com> wrote:

>On May 6, 6:18�am, Joseph M. Newcomer <newco...(a)flounder.com> wrote:
>> See below...
>> On 05 May 10 15:19:03 -0800, "Charlie Gibbs" <cgi...(a)kltpzyxm.invalid> wrote:
>>
>>
>>
>>
>>
>> >In article
>> ><1509753c-6b6d-4459-8db0-13597ede8...(a)h37g2000pra.googlegroups.com>,
>> >rsharma.ch...(a)gmail.com (Rahul) writes:
>>
>> >> Thanks Alf,
>>
>> >> So infinite recursion and large stack based array's seems to be the
>> >> problem. But why does the default debugger not catch these crashes.
>> >> I even tried on the system where Visual Studio was installed, It also
>> >> failed to catch those exceptions (unless we run the program the inside
>> >> debugger itself)
>>
>> >> Is there any way to catch these crashes without running the program in
>> >> the debugger, and why are they not caught by the debugger by default
>> >> (just for understanding the technical difficulty involved in this).
>>
>> >My favourite way of dealing with these things is to define a buffer
>> >on either site of the local variables:
>>
>> >void myfunc ()
>> >{
>> > � �char buffer1[512];
>>
>> ****
>> Generally, a C++ programmer should never write �a declaration of the form
>> � � � � type name[compile-time-constant-expression];
>> Not even for local buffers; I tend to do
>>
>> � � � � CByteArray buffer;
>> � � � � buffer.SetSize(512);
>> � � � � ReadFile(f, buffer.GetData(), (DWORD)buffer.GetSize(), &bytesRead, NULL);
>>
>> The data is not on the stack, and is automatically cleaned up when the variable leaves
>> scope. �You can do an analogous trick with std::vector<BYTE>. �It is always best to use
>> the BYTE data type for input buffers, since it eliminates any potential confusion that
>> might arise when Unicode comes into play.
>> *****
>> � � � � .....> � �... other local variables ...
>> > � �char buffer2[512];
>>
>> > � �memset ((void *) buffer1, 0, sizeof (buffer1));
>> > � �memset ((void *) buffer2, 0, sizeof (buffer2));
>>
>> ****
>> This code is alwyas deeply suspect. � Why memset to 0 something that is going to be
>> overwritten by input data? �Bad programming style, generally. �And use ::ZeroMemory
>> instead of the 1975 PDP-11 model taught by amateur teachers. �Better still, don't do it at
>> all!
>>
>> If the code is so badly written that the buffer MUST be zeroed out, note that I said "so
>> badly written". �I find little excuse for doing the memset-to-zero as a substitute for
>> responsible programming.
>> � � � � � � � � � � � � � � � � joe
>> ******> � �... code ...
>> >}
>>
>> >Often that's enough to stop the mysterious disappearances. �You can
>> >then check "buffer1" and "buffer2" at various points in the code to
>> >see whether they suddenly become nonzero. �That should catch simple
>> >overflows, but a truly wild pointer could clobber the stack far
>> >enough away that nothing bad happens until the program exits.
>> >Still, it's a start...
>>
>> ****
>> Note that VS > 2003 will catch buffer overruns in debug mode; I fined no compelling reason
>> to use anitque versions of VS which have poor error detection in the marginally-correct
>> compilers that compile a language similar to, but not actually, C++.
>>
>> A cause no one has mentioned is the horrendous technique of putting exit() calls into the
>> code to handle error conditions. �This has never made sense in the history of programming,
>> in any language; �it was a stupid idea in C on the PDP-11 and a more stupid idea in C++
>> and Windows. �I've caught a number of "the program just disappears" bugs by finding all
>> exit() calls under various guises.
>> � � � � � � � � � � � � � � � � joe
>> *****
>> Joseph M. Newcomer [MVP]
>> email: newco...(a)flounder.com
>> Web:http://www.flounder.com
>> MVP Tips:http://www.flounder.com/mvp_tips.htm
>
>
>I tried reproducing the issue and found that this happens sometimes
>when the VM space exhausts. I was running the application in debugger
>and at one point of time (When the virtual size was 1.84 GB) the
>process suddenly hung, I tried breaking in the debugger but debugger
>could not show any stack, Then I did a "Detach All" in VC++ debugger
>and the process just vanished after 10-12 seconds.
****
Under these conditions, I would try setting a breakpoint at the return from malloc, and
make it conditional on the return value being NULL. From this point, I would try
single-stepping to see who is not handling a NULL return value correctly. Note that the
first recipient of NULL might do reasonable things, but the NEXT call that fails would
trigger the failure you are seeing.

I hate these kinds of bugs; they are extremely hard to track down.
****
>
>As per the general behavior when some memory allocation fails then an
>Access violation should happen which should get caught in the
>debugger, but is there any way that memory exhaustion could cause the
>application to vanish (may be depending on where the allocation
>failure happened, perhaps in the kernel code etc.)
****
Given that C++ will throw a C++ exception, there are potential cascading bug issues here.
There would not necessarily be an access fault. Also, go into the Debug>Exceptions and
enable for ALL exceptions, especially C++ exceptions.

As I said, these are difficult bugs to track down. In many cases, I would find code like
this

something * p = (something *)malloc(sizeof(something));
if(!p) exit(1);

This is caused by children who never once learned how to program correctly, probably
because they had been taught by amateur programmers. In the world of C++ and Windows we
don't usually encounter code this bad, but those two lines are classics from C on
workstations in the 1980s, and the kind of people who wrote that code ended up writing
Windows apps (and the people who taught them that code like that is even acceptable were
still teaching in the 1990s!)

But exceptions which are improperly handled can result in serious disasters. These
include stack overflow and what are called "double bus" errors [the term is from another
culture] where the attempt to handle an exception generates a second exception. This
usually results in silent disappearance of an app.

The absence of a crash dump is always suspicious; this suggests the app deliberately
exited (thus not creating a crash-dump-acceptable situation), and there are a lot of
reasons this can happen. But I have seen bad exception handling run wild in the stack
during recovery and result in serious problems. In one case, the programmer was in an
overridden function and meant to call the superclass handler, and wrote

void CSomeClass::SomeFunction(...parameters...)
{
try {
}
catch(CSomeException * e)
{
SomeFunction(...parameters);
e->Delete();
}

The intention was to have written either
__super::SomeFunction(...parameters...)
or
CSomeClassSuperclass::SomeFunctio(...parameters...)

but it was incorrectly coded, and the result was a stack overflow that would only show up
when the exception was thrown, which happened about once every four months in the field.
joe
`
>
>Regards
>Rahul
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm