We help IT Professionals succeed at work.

Stack Dump

sector asked
Last Modified: 2008-02-26

How can i ( in programmically way ) can get the stack trace of the processes.
( For Debugging issuses ).

Watch Question

Most debuggers would provide this infomation for you automatically and would be much easier for you to use.  

But I can post a little class that will help you to obtain the information.

continues (in a few minutes)

class PrcDat // Priocedure Data
   string PrcNam; // Procedure name.
   string FilNam; // File name.
   int LinNum; // Line number.
   PrcDat(const string &Prc, const string &Fil, int Lin) :
       PrcNam(Prc), FilNam(Fil), LinNum(Lin) {};

// A globally delcared stack for storing the call
// stack information.  Could be made a static member
// of one of these classes.
deque<PrcDat> CllStk; // Call stack.

class PrcIns // Procedure instance
   PrcIns(const string &Prc, const string &Fil, int Lin)

Now the PrcDat class is used to store info for a particular procedure.  CllStk class is used to record the call stack and the PrcIns class is used to help you maintain the call stack.  Each procedure needs to make a single instance of the PrcIns class right at the start of the procedure.  This will add info for the procedure to the call stack, when the procedure ends the entry for the procedure will automatically be removed by the PrcIns class's destructor, like

int SomeProc(int i)
   PrcIns APrcIns("SomeProc",__FILE__,__INT__);

   // procedure code.

Now it can be a bit painful to specify those ugly __FILE__ and __LINE__ and you probably don't want this for a release version so you can use the Pre-processor to help you.  Like

#ifdef DEBUG // If this is a debug version
#define AddCllStk(Nam)    PrcIns APrcIns(Nam,__FILE__,__INT__);
#else // Otherwise, if release version
#define AddCllStk(Nam)    

You would use this like

int SomeProc(int i)

   // procedure code.

Let me know if you have any questions.

This is the question that was answered, look here!

There's no need to do it this way. The compiler emits code that creates a chain of function calls right on the stack--it's easy to walk it backwards.

If you're using VC++, take a look at the AfxDumpStack() function. Even if you're not using MFC, it's really to steal the code from DUMPSTAK.CPP in the MFC source directory.

..B ekiM

I think he is looking for symbolic information.  And this is not necessarily for VC or even x86/windows--unless you know something I don't about sector's programming environment.


mikeblas got right what i was looking for. How do i give the points to him ??
And i have another related question :
Can i add to the stackWalk to print local vars and pointers status ?

You could just reject my answer then select his comment as an answer.

But I'll withdraw mine now, you can then accept his.
Be warned: AfxDumpStack() relies on IMAGEHLP.DLL. If that DLL isn't available, the function will display an error message.

Also, IMAGEHLP is unable to walk the stack on Win95 (I haven't tested on Win98).

The _technique_ can be done without IMAGEHLP.DLL.  And IMAGEHLP does work on 95.
I know the _technique_ can be done on Win9x - see http://www.microsoft.com/msj/backissues97.asp, April issue, Under the Hood article. That's why I said "IMAGEHLP is unable to walk the stack..."

When I used IMAGEHLP (v5.00.1678.1) on a Win95 PC, SymInitialize() failed - which I thought meant it couldn't walk the stack (so I reverted to the technique in the URL above).
This one is on us!
(Get your first solution completely free - no credit card required)


I am talking about generating this stack dump on the release version of the software and i have 2 questions :

1. Is it available on release mode.
2. How to get the function names to apeare on the stack dump and not just a pointer.

The stack trace itself is, sure. But in release mode, you have no symbols and will only see addresses.

..B ekiM


Then how can i get this information any way, Is there a way of dooing it ?


Then how can i get this information any way, Is there a way of dooing it ?

>>  Then how can i get this information any way,
>> Is there a way of dooing it ?
The symbolic information, the names of the functions, is not recorded in a release version.  Its not there for you to obtain.  (Actually in VC you can create a release version that has debug symbols, but that pretty much is a debug version.)

That is one reason why I suggest the use of classes.  (Also because its OS/compiler indipendant.)
As the other experts have stated, there is no way to get the function names directly from a release build (with out debug information).

However, you can work out the function names (including source/line numbers) given a list of the stack addresses.

I use this technique to help debug 'in the field' crashes: when my program crashes, it writes the stack trace to a report file which the user sends to me. I can then use the addresses in the report file to work out where the program crashed and what it was doing.

Is this close to what you need?


abancroft :

How can you get function names , files and line from a stack dump that is based on pointer information ?

You can't with just that information.  But if you have a map file that was created when the program was compiled and lined you can look up addresses in the  map file and figure out which function each stack frame is in.
When you make a release build:
1. Turn debug symbols on - place them in a seperate PDB file. This will increase the size of each EXE/DLL by about 1k. Obviously, you don't distribute the PDB files.
2. Rebase all your DLL's, so you know where they'll be loaded in memory.

Then use a handy tool written by one of the MSJ columnists: given the release DLL's, PDB files & an address it can look up the source file &line number. See http://www.mv.com/ipusers/robbins/ and http://www.microsoft.com/msj/backissues98.asp (August Bugslayer column).

nietod> (Actually in VC you can create a release version that has debug
 nietod> symbols, but that pretty much is a debug version.)

No, no no! A debug build has optimizations completely disabled, has extra code enabled, and might link against different supporting libraries. A release build with symbols is just that--a release build with symbols.

..B ekiM

Right, like I said.

> Right, like I said.

Not even close. A "release version that has debug symbols" is _not even close_ to being "pretty much a debug version".

Pleae reread my posting of Tuesday, March 07 2000 at 7:27am PST for the reasons why!

..B ekiM

Right.  pretty close.  Not the same, but close.

What is the criteria?  You can certainly choose criteria were they are totally different.  You can chose criteria where they are pretty close.  

A release version with debug symbols can be debugged easily and easily reverse engineered etc.  As far as I am concerned that is pretty close to a debug version.  Yes despite the fact that I am clueless about almost everything in the programming world, I do know that there are differences.  That is why I said they were close. That is why I didn't suggest he use a debug verison instead.  (Not that I suggest he release a release version with debug symbols either.)

Note, the question about criteria is retorical. no need to answer if you don't want to.  


How do i create a release version with only symbols ?


What is the difference between the release exe with debug info and the release with out debug info.
I can still switch on any optimization I want in the release with the debug info.

> How do i create a release version with only symbols ?

Tell VC++ you want a new build target. Base it on your release build target. Ask the compiler to generate debug info (in the C/C++ tab). Ask the linker to generate debug info (in the linker tab).  That's all!

 > What is the difference between the release exe with debug info
 > and the release with out debug info.

Debug info. The EXE will be a couple of kilobytes bigger because it will contain a record that points to the symbol files. But all the symbols are in the *.PDB file, which will be separate and not necessary to run the application.

 > I can still switch on any optimization I want in the
 > release with the debug info.

Yes, you can.

..B ekiM


should i state the PDB:/NONE option in the linker option not to create the PDB file and enter the info into the exe, because when i create a pdb file the dump stack tell me it can't find functions symbol.


1. If the PDB is not created and the debug info is insterted into the project exe then the file size changes from 20K to 1.3MB.
2. If i use external PDB file then the file size remains 20K but the stack dump can't find the symbol info then i get no symbol in the stack dump.

I prefer keepping the exeas much as possible smaller , but how can i put the two together : small file with external PDB file and stack trace with symbols in it.


Adjusted points to 250

Are you going to want this stack trace feature in the release version and are you going to be willing to distribute your release version with debug symbols (either in the executable files or as a seperate file)?

>> small file with external PDB file
Under "project settings" go to the "link" tab
Select the "customize" category
Check "Use Program Database"

You will have to distribute this database with your app, if you want the feature in the distributed application.  


i will distribute the exe and PDB file.


The PDB file is created but no connection is done during the stack dump with the PDB file.
Is this connection done automatically ?
Does it need the use of a API PE.

I don't undestand.  What do you mean by "connection"?  What is "API PE"? Portable executable?


The symbol info does not apear on the AfxStackDump log file when i am using an seperate PDB file and the debug info is not generated inside the EXE.
Are you using VC6?

If so:
1. Locate the MSPDB60.DLL file.
2. Copy it to somewhere in your path (e.g. WINNT\SYSTEM32 or WINDOWS\SYSTEM)& rename it to MSPDB50.DLL. YOU MUST RENAME IT.

Try again.


i am working with VC6 and this is not working even aftet i have located the DLL and placed it in the system32 dir.
This is what i get :

=== begin AfxDumpStack output ===
77F67A2B: WINNT\System32\ntdll.dll! NtGetContextThread + 11 bytes
004013B6: MyProjects\TraceTest\Release\TraceTest.exe! <no symbol>
5F402AF0: WINNT\System32\MFC42.DLL! Ordinal4424 + 281 bytes

00040025: <no module><no symbol>
=== end AfxDumpStack() output ===
And you renamed the DLL to 'Mspdb50.dll'?

Here's my relevent project settings:
1. C++, General, Debug Info: Program Database.
2. Link, Customize. Use program database is ON. Program database name is "Release/myapp.pdb".
3. Link, Project Options. Added /OPT:REF.


OK, THanks , i forgot to rename the DLL.
How do i give YOU the points.
Reject the answer & then select my comment as an answer.

You said that you are going to distribute the PDB files with the program. Do you realise that:
1. They are BIG (a lot bigger than the program).
2. It'll make it a lot easier to reverse engineer your program.

If this is an alpha/beta test with a limited number of trusted users then this may be OK.
Also, remember to distribute IMAGEHLP.DLL & MSPDB50.DLL with your app - they can go in the same folder as your EXE.

Also remember that other experts have contributed (argued?) to this.


How do i know when the application has crashed , in other words what is the trigger that activates the AfxStackDump method.
Do i have to work with SEH Exceptions, if yes then the program will not crash anyway.
Sounds like you are trying to do what I described in an earlier post: when your app crashes, write some info to a file that will help you debug it.

I use the API call SetUnhandledExceptionFilter() to add a top-level exception handler.

Within my handler, I write a report file (that includes the stack) and then either pass control onto the previoulsy installed handler or return EXCEPTION_CONTINUE_SEARCH.


// The exception handler
LONG __stdcall ExceptionHandler(PEXCEPTION_POINTERS pExceptionInfo)
  // Do report stuff here

  if ( s_gpPrevEFilter )
      return s_gpPrevEFilter( pExceptionInfo );

// Previous handler

// Setup our handler
s_gpPrevEFilter = SetUnhandledExceptionFilter(ExceptionHandler);

That way, the app still 'crashes' like it would without the handler.

>> OK, THanks , i forgot to rename the DLL.
>> How do i give YOU the points.
The choice of who gets the points is entirely up to you, but usually they awarded to the person who proposed the solution first.  That would be mikeblas, in this case.  But the choice is yours.

> Do i have to work with SEH Exceptions, if yes then the
 > program will not crash anyway.

No--it's just that, by the time the exception handler has been called, the program has _already_ crashed. You should dump the stack then abort the image by calling ExitProcess().

..B ekiM


1. But is the exception is for example deviding with 0 , that the program will not crash if i handle it with local exception handling.
What are the cases that exception handling will not work.


How can i get from the AfxStackDump method to print also the variables that are on the stack ?
It prints only the method names.

> 1. But is the exception is for example deviding with 0 , that
 > the program will not crash if i handle it with local
 > exception handling.

I guess we have different definitions of "Crashing".

If you perform an invalid operation, like writing to memory you don't own or dividing by zero, your thread will throw an exception. If you don't have an exception handler, the program will show the user a message box saying that an exception was thrown but not handled and your program will be thrown out of memory by the operating system.

If you _do_ have a local handler designed to take care of the problem, you'll be able to handle it: recover and react.  If your backstop handler is called, you can't generically handle the problem and, effectively, you'll have crashed. You must dump the stack and close the app, just like the operating system does.

 > What are the cases that exception
 > handling will not work.

Will not work for what?  I can't understand that question.

 > How can i get from the AfxStackDump method to print also the
 > variables that are on the stack ?  It prints only the method names.

You can't. The format of the debug info that describes the stack frame is not documented, and not accesible by any documented APIs. (Besides, some locals are in registers, and you can't see 'em.)

..B ekiM


Any more opinions about my last question ???
I agree with Mike - AFAIK you can't.


I realy don't understand why cant i see the variables because they are there on the stack and i am walking on this stack, so what is the problem ?

That stack contains only the data stored in the variable.  It does not contain any symbolic information (the name of the variables.)  It doesn't even say how the data shoudl be interpreted. (Is it is int a pointer, a structure....)

Gain unlimited access to on-demand training courses with an Experts Exchange subscription.

Get Access
Why Experts Exchange?

Experts Exchange always has the answer, or at the least points me in the correct direction! It is like having another employee that is extremely experienced.

Jim Murphy
Programmer at Smart IT Solutions

When asked, what has been your best career decision?

Deciding to stick with EE.

Mohamed Asif
Technical Department Head

Being involved with EE helped me to grow personally and professionally.

Carl Webster
CTP, Sr Infrastructure Consultant
Empower Your Career
Did You Know?

We've partnered with two important charities to provide clean water and computer science education to those who need it most. READ MORE

Ask ANY Question

Connect with Certified Experts to gain insight and support on specific technology challenges including:

  • Troubleshooting
  • Research
  • Professional Opinions
Unlock the solution to this question.
Join our community and discover your potential

Experts Exchange is the only place where you can interact directly with leading experts in the technology field. Become a member today and access the collective knowledge of thousands of technology experts.

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.


Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.