Re: Memory corruption and Dump Stack trace
On Jul 6, 4:12 pm, Joseph M. Newcomer <newco...@flounder.com> wrote:
See below...
On Fri, 06 Jul 2007 15:47:44 -0000, "karen.b....@gmail.com" <karen.b....@gmail.com> wrote:
On Jul 6, 11:35 am, "karen.b....@gmail.com" <karen.b....@gmail.com>
wrote:
On Jul 1, 3:46 pm, Joseph M. Newcomer <newco...@flounder.com> wrote:
Memory damage bugs rank among the most difficult and intractable bugs that exist. There
is nothing good about them. The worst part is what you observed, that they are random and
hard to reproduce.
First, if this is happening post-deployment, the simplest method is to use DrWatson to
create a dump file. This would be one of the first things I would try. If it happens on
your development machine, you can use JIT (Just-In-Time) debugging to invoke the debugger
at the point of crash.
One way to deal with dangling pointers is to make sure that after every delete you set the
pointer to the thing you deleted to NULL. This doesn't help you if there are multiple
pointers, alas.
One thing I did some years ago (when I used to get these all the time) was create a
"honeypot" object, an intermediate object that represented my object. It's a bit ugly and
wasteful of storage, but what I did was convert all references of the form
thing->field
to
thing->honeypot->value->field
and when I did a free (not delete, since this was pre-C++ for me) I would do
free(thing->honeypot->value);
and set
thing->honeypot->value = NULL;
now I'd get a NULL-pointer access failure if I used the dangling pointer. My approach was
a bit more elaborate, in that I would require that no one ever actually call free
directly, but instead it would be
FreeThing(thing);
#define FreeThing(x) _FreeThing(x, __FILE__, __LINE__)
where
void _FreeThing(Thing * thing, char * file, int line)
{
thing->honeypot->freepoint.file = file;
thing->honeypot->freepoint.line = line;
free(thing->honeypot->value;
thing->honypot->value = NULL;
}
Now if I got a null-pointer access, the freepoint struct gave me the file and line.
Honeypots just accumulated, and were never freed, so the program would grow and grow, but
since this would reasonably quickly find the problem, it didn't matter. A bit of
finagling of macros and #ifdef _DEBUG meant that in the release version, the honeypot got
deleted also. Today in C++ I could hide a lot of that inside classes.
Another solution, often simpler, is simply to add the following to your OnIdle handler:
ASSERT(_heapchk() == HEAPOK);
(check the docs for the correct spellings here...I'm typing this from memory). That way
if there is any heap damage, you catch it early, insted of waiting for it to nuke you much
later.
joe
On Sun, 01 Jul 2007 11:55:54 -0700, "karen.b....@gmail.com" <karen.b....@gmail.com> wrote:
Hi everyone,
my application has danging pointer, either pointing at something
that's deleted, or the memory was used by someone else. It causes
crashes very randomly and thus hard to reproduce the crash. I
narrowed it down to memory corruption because it crashed at calling a
pointer->doubleValue ...
Is there a way to produce a stack dump in MFC? I want to see who was
trying to delete the object. If anyone has better solution in looking
at this, please help!
Thanks!
Joseph M. Newcomer [MVP]
email: newco...@flounder.com
Web:http://www.flounder.com
MVP Tips:http://www.flounder.com/mvp_tips.htm
Hi, Thanks for the tip. Did something along the line as you
suggested. However since the crash is so random, we still to need to
crash this thing and see what addresses go wrong. Does anyone know
how to use
AfxDumpStack(AFX_STACK_DUMP_TARGET_DEFAULT);
I need to use dbghelp.dll or imagehlp.dll to generate image of the
stack. I want to dump the stack when my destructor is called so I can
track who goes in and out to delete my objects. Any idea how I can
use these dll files (and possible .dbg, .pdb files?) with Visual C++?
Thanks in advance~- Hide quoted text -
- Show quoted text -
This is what I've tried:
in Project -> Settings -> Debug -> Additional DLL
I put in
C:\windows\system32\imagehlp.dll
C:\windows\system32\dbghelp.dll
****
It sounds like you are using VS6. The "Additional DLLs" feature is there only to specify
that certain DLLs will be more readily debuggable, and has absolutely nothing to do with
making them available to your program for use. Therefore, neither of these would do any
good unless you plan to set breakpoints in these DLLs, which seems unlikely.
You have to call the methods of these DLLs, and link with the appropriate .lib files as
described ni the documentation.
dbghelp.dll is a particularly poor piece of code; I've been using it, and other than minor
details like it doesn't work right, or at all, and you need to have the very latest
dbghelp.dll that comes with the download of WinDbg, and even then its correctness is
marginal, and it isn't all that helpful, there's nothihng wrong with using it.
As far as I can tell, there is just enough code there to allay people attacking Microsoft
for being a "closed" architecture with no third-party interfaces, but in fact it cannot be
really trusted and only kind-of-works on a good day. I have this from an independent
email from someone who should know what is going on, but I don't think I can say who sent
it or who told the person who sent it to me that it basically doesn't work, but this is
not my opinion, but the opinion of someone who is in a position to know with a great
degree of certainty that it doesn't work. My followup question, "So what do we do if we
need symbols", remains unanswered.
*****
and also
C:\windows\system32\dll\dbghelp.pdb
****
Why? It does you no good to have the .pdb file there, and it isn't a DLL, so mentioning
it in the "Additional DLLs" is somewhere between irrelevant and erroneous
****
When I run the debugger, it says "C:\windows\system32\dbghelp.dll does
not contain debugging information" (same for the imagehlp.dll)
****
And so what? You aren't debugging THESE DLLs, so why would you care in the slightest if
their symbols are not present? And how does this different from any of the the two dozen
or more DLLs a real program might be using, NONE of which have debugging information?
*****>and for the pdb file, it says "The target platform of C:\windows
\system32\dll\dbghelp.pdb does not match the current target platform"
*****
OK, I amend my above comment. It is not irrelevant, it is merely erroneous. Why would
you expect it to think that some random data file is an executable image?
*****
No idea what they mean ...
*****
They mean that (a) you cannot debug the debug DLLs because there are no symbols for you to
use to set symbolic breakpoints and (b) a .pdb file is not an executable image.
Neither of these have any significance whatsoever to what you are trying to solve. You
may remove all of these files from the "Additional DLLs"
*****
My program does generate a pdb file. How do I put all of these
together?
*****
You don't. Your debugger does. If you are deploying a product, the "debugger" is
DrWatson. If you want to call a method such as a stack trace routine (which I think is a
really bad idea because of the cost), you call it. You link correctly, the correct DLLs
are loaded, and the DLLs are responsible for finding the .pdb file.
joe
*****
Joseph M. Newcomer [MVP]
email: newco...@flounder.com
Web:http://www.flounder.com
MVP Tips:http://www.flounder.com/mvp_tips.htm- Hide quoted text -
- Show quoted text -
Ok, I really NEED to get the call stack at the destructor. There are
so many places where it's called, I tried breakpointing at it, and
marked down all the possible places which I *think* it was calling the
destructor. However there's something else that's deleting the object
and leaving a dangling pointer somewhere else. I have a collection
that collects object addresses at the constructor. In the destructor,
it removes the address from the collection. So at the place that
crashes (I got it from Dr.Watson) - i put a check to see if my
collection has that address or not. If it doesn't, then I know
someone has already deleted it. And it is the case looking from my
log. Now I really don't know who deletes it. So I need to get the
call stack when I'm at the destructor.
I know that I cannot just let the current thread dump the stack there,
need to fake an exception and catch it, then print it. But i did lots
of research and still couldn't print out the call stack. The call
stack I want to see is, like in VC++ 6.0, you breakpoint it, and shows
you the call stack in the call stack window (in debug mode)
Thanks lots!
------------------------------------------------------------------ A
snipet of my logs
------------------------------------------------------------------
****** a BOMBInstrument is CREATED ... dumping address
*****
BombInstrument ID: 0 @0x1046b558 -- BOMBImntRT=NULL
....
....
Before creating BOMBRiskTweak ... dumping
address
BombInstrument ID: 2802 @0x1046b558 -- BOMBImntRT: 0xaf2
undimnt address in Tweak object:
0x1046b558
<--- when puting it in another object (which will be the dangling
pointer)
....
....
****** a BOMBInstrument is DELETED ... dumping address
***** <---
someone goes in and deletes it ... (don't know who)
BombInstrument ID: 2802 @0x1046b558 -- BOMBImntRT: 0xaf2
....
....
IMNT WAS DELETED BEFORE !!!!!
0x1046b558
<--- the dangling pointer is referenced and causing a crash
PORTFOLIO RANGE-WORST-EX
POSITION 3836649