Solved

Stack Dump

Posted on 2000-03-05
53
755 Views
Last Modified: 2008-02-26
Hi.

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


                            Sector.
0
Comment
Question by:sector
  • 20
  • 15
  • 10
  • +1
53 Comments
 
LVL 22

Expert Comment

by:nietod
ID: 2585093
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)
0
 
LVL 22

Expert Comment

by:nietod
ID: 2585111
class PrcDat // Priocedure Data
{
public:
   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
{
public:
   PrcIns(const string &Prc, const string &Fil, int Lin)
   {
      Cllstk.push_back(PrcDat(Prc,Fil,Lin));
   };
   ~PrcIns()
   {
      CllsStk.PopBck();
   }
};
0
 
LVL 22

Expert Comment

by:nietod
ID: 2585125
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)    
#endif

You would use this like

int SomeProc(int i)
{
    AddCllStk("SomeProc");

   // procedure code.
};


Let me know if you have any questions.
0
 
LVL 22

Expert Comment

by:nietod
ID: 2585155
This is the question that was answered, look here!
0
 
LVL 11

Expert Comment

by:mikeblas
ID: 2585412
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
0
 
LVL 22

Expert Comment

by:nietod
ID: 2585435
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.
0
 

Author Comment

by:sector
ID: 2587006
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 ?
0
 
LVL 22

Expert Comment

by:nietod
ID: 2587265
You could just reject my answer then select his comment as an answer.

But I'll withdraw mine now, you can then accept his.
0
 
LVL 4

Expert Comment

by:abancroft
ID: 2588083
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).
0
 
LVL 22

Expert Comment

by:nietod
ID: 2588118
The _technique_ can be done without IMAGEHLP.DLL.  And IMAGEHLP does work on 95.
0
 
LVL 4

Expert Comment

by:abancroft
ID: 2588183
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).
0
 
LVL 11

Accepted Solution

by:
mikeblas earned 250 total points
ID: 2590342
> Can i add to the stackWalk to print local vars and pointers status ?

No.  That part of the debug information isn't publicly documented.

..B ekiM
0
 

Author Comment

by:sector
ID: 2590572
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.
0
 
LVL 11

Expert Comment

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

..B ekiM
0
 

Author Comment

by:sector
ID: 2591114
Then how can i get this information any way, Is there a way of dooing it ?
0
 

Author Comment

by:sector
ID: 2591122
Then how can i get this information any way, Is there a way of dooing it ?
0
 
LVL 22

Expert Comment

by:nietod
ID: 2591440
>>  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.)
0
 
LVL 4

Expert Comment

by:abancroft
ID: 2591756
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?
0
 

Author Comment

by:sector
ID: 2591850
abancroft :

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

Expert Comment

by:nietod
ID: 2591869
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.
0
 
LVL 4

Expert Comment

by:abancroft
ID: 2591902
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).
0
 
LVL 11

Expert Comment

by:mikeblas
ID: 2592164
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
0
 
LVL 22

Expert Comment

by:nietod
ID: 2592206
Right, like I said.
0
 
LVL 11

Expert Comment

by:mikeblas
ID: 2594078
> 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
0
 
LVL 22

Expert Comment

by:nietod
ID: 2594130
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.  
0
 

Author Comment

by:sector
ID: 2594871
How do i create a release version with only symbols ?
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 

Author Comment

by:sector
ID: 2594954
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.
0
 
LVL 11

Expert Comment

by:mikeblas
ID: 2594970
> 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
0
 

Author Comment

by:sector
ID: 2595006
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.
0
 

Author Comment

by:sector
ID: 2595560
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.
0
 

Author Comment

by:sector
ID: 2595599
Adjusted points to 250
0
 
LVL 22

Expert Comment

by:nietod
ID: 2595638
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.  
0
 

Author Comment

by:sector
ID: 2595751
yes.
i will distribute the exe and PDB file.
0
 

Author Comment

by:sector
ID: 2595767
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.
0
 
LVL 22

Expert Comment

by:nietod
ID: 2595817
I don't undestand.  What do you mean by "connection"?  What is "API PE"? Portable executable?
0
 

Author Comment

by:sector
ID: 2596013
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.
0
 
LVL 4

Expert Comment

by:abancroft
ID: 2596381
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.
0
 

Author Comment

by:sector
ID: 2596611
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 ===
0
 
LVL 4

Expert Comment

by:abancroft
ID: 2596646
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.
0
 

Author Comment

by:sector
ID: 2596877
OK, THanks , i forgot to rename the DLL.
How do i give YOU the points.
0
 
LVL 4

Expert Comment

by:abancroft
ID: 2596922
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.
0
 
LVL 4

Expert Comment

by:abancroft
ID: 2596962
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.
0
 

Author Comment

by:sector
ID: 2597133
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.
0
 
LVL 4

Expert Comment

by:abancroft
ID: 2597162
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.

e.g.

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

  if ( s_gpPrevEFilter )
      return s_gpPrevEFilter( pExceptionInfo );
  else
      return EXCEPTION_CONTINUE_SEARCH;
}

// Previous handler
LPTOP_LEVEL_EXCEPTION_FILTER s_gpPrevEFilter;

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

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

Expert Comment

by:nietod
ID: 2597414
>> 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.
0
 
LVL 11

Expert Comment

by:mikeblas
ID: 2599102
> 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
0
 

Author Comment

by:sector
ID: 2600239
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.

0
 

Author Comment

by:sector
ID: 2601025
How can i get from the AfxStackDump method to print also the variables that are on the stack ?
It prints only the method names.
0
 
LVL 11

Expert Comment

by:mikeblas
ID: 2601176
> 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
0
 

Author Comment

by:sector
ID: 2601367
Any more opinions about my last question ???
0
 
LVL 4

Expert Comment

by:abancroft
ID: 2601382
I agree with Mike - AFAIK you can't.
0
 

Author Comment

by:sector
ID: 2601571
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 ?
0
 
LVL 22

Expert Comment

by:nietod
ID: 2601742
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....)
0

Featured Post

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

746 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now