|
||||||||||||||||||
Add Forum to Favorites | Send Topic To a Friend | View Forum FAQ | Track this topic |
Last Thread Next Thread ![]() |
| General Purpose Call Stack Tracer |
|
![]() daerid Member since: 8/13/2001 From: Sunland, CA, United States |
||||
|
|
||||
| Something I forgot to mention, that this thing will DIE (in a horrible, greusome death) if used in any level of recursion. So basically, if you're not using recursive functions, have a blast Otherwise, a dynamically allocated solution would be better. |
||||
|
||||
![]() Blaster Member since: 5/31/2001 From: Montreal, Canada |
||||
|
|
||||
| What if you have more than one return point in a function? You'd have to place the macro before all the returns. This could be error prone; what if you forget one. There could be a macro that call the other macro and returns the specified value, but you'd have to remember not to use the normal return. A simple object on the stack that calls enter in the constructor and leave in the destructor would be good. I'm sure everyone already thought about that, and I'm not introducing anything new here, but I know it would help. On the other hand, I can see where it would fail: exceptions. Since C++ is nice and it calls the destructors when an exception is thrown, it would call the destructor of the auto object, rendering the system useless. So that leaves us with the return macro. ---------------- Blaster Computer game programmer and part time human being Strategy First - http://www.strategyfirst.com BlasterSoft - http://www.blastersoft.com [edited by - Blaster on October 25, 2002 1:07:58 PM] |
||||
|
||||
![]() Sly Member since: 7/28/2000 From: Brisbane, Australia |
||||
|
|
||||
| What we have is a class and a CALLSTACK macro. The macro declares a static instance of the class. The constructor of the class registers the function name on the callstack. The destructor of the class removes the function name from the callstack. The destructor is automatically called when the object goes out of scope, ie. when you leave the function. So all we need is the following... void MyFunc(int param) { CALLSTACK("MyFunc"); // code } |
||||
|
||||
![]() Blaster Member since: 5/31/2001 From: Montreal, Canada |
||||
|
|
||||
| Sly : yes, that's the kind of "auto" object I was talking about. But as I said, you loose the callstack when an exception is thrown, because the destructors of the auto objects are called. ---------------- Blaster Computer game programmer and part time human being Strategy First - http://www.strategyfirst.com BlasterSoft - http://www.blastersoft.com |
||||
|
||||
![]() david_williams Member since: 9/3/2001 From: United Kingdom |
||||
|
|
||||
| Why does it die if used in a recursive fashion? |
||||
|
||||
![]() __tunjin__ Member since: 3/13/2002 |
||||
|
|
||||
| why not use __FUNCTION__ instead of a param? |
||||
|
||||
![]() david_williams Member since: 9/3/2001 From: United Kingdom |
||||
|
|
||||
| Is __FUNCTION__ standard C++? I hadn't heard of it before. [edited by - david_williams on November 21, 2002 6:26:38 PM] |
||||
|
||||
![]() daerid Member since: 8/13/2001 From: Sunland, CA, United States |
||||
|
|
||||
| My new version uses __FUNCTION__, and uses templates to avoid the inclusion of a .cpp file Also, it handles exceptions by using the std::uncaught_exception() function in the dtor of the auto_object It also only requires the use of a single macro at the beginning of the function |
||||
|
||||
![]() Yamaha Member since: 7/31/2003 |
||||
|
|
||||
| I got a compile error at callstacktrace.cpp(72) : fatal error C1010.Please help!!! |
||||
|
||||
![]() Anonymous Poster |
||||
|
||||
quote: Yamaha, you'd add both provided source files (callstacktrace.cpp and callstacktrace.h) to your project, and include the callstacktrace.h in your files where you want to use the tracing functionality. Detailed description is provided with the source (see top section of header file). |
||||
|
||||
![]() Anonymous Poster |
||||
|
||||
quote: I managed to write my own CallStack tracer class, using stack instead of double linked lists. I also use std::uncaught_exception() in the dtor of the CallStackTrace. There is a problem with VC6, as this function is not correctly implemented - it always returns false... |
||||
|
||||
![]() Anonymous Poster |
||||
|
||||
quote: __FUNCTION__ is not ANSI C++ predefined macro name, so I would not use it. I pass the function name as you did in your original source. |
||||
|
||||
![]() Anonymous Poster |
||||
|
||||
| The macro for tracing the program can easily be changed flow even in recursive-called functions. For example like this: class CDbgFlowTrace{ static CString m_strCurrentStack; CString m_strMyContribution; public: CDbgFlowTrace(CString strMyContribution) { m_strMyContribution=strMyContribution; m_strCurrentStack +=strMyContribution+";"; //and possibly write m_strCurrentStack into file }; ~CDbgFlowTrace() {m_strCurrentStack.RemoveEndChars(strMyContribution.GetLength);}; };// CDbgFlowTrace #define FLOW_TRACE(x) CDbgFlowTrace x(x) void f1() { FLOW_TRACE(ENTERED_f1) // code FLOW_TRACE(IN_MIDDLE_OF_f1) // code2 } ----------------- It is true that this does not tell me, which dtors were called AFTER the exception has been raised. (My experience says that "interval dividing" enables to find the problem very quickly.) But I am very sorry than in the Microsoft Visual C++ the uncaught_exception is implemented like {return false;}; Life would be much easier :-) (A very witty article about this is http://world.std.com/~swmcd/steven/ms/bugs.html.) ---------------------- Pavel pjel@centrum.cz |
||||
|
||||
![]() Anonymous Poster |
||||
|
||||
| I'll add a small correction - it should be #define FLOW_TRACE(x) CDbgFlowTrace x(#x); |
||||
|
||||
![]() doynax Member since: 1/8/2004 From: Sweden |
||||
|
|
||||
| If you're only going to use this for debugging purposes then why not use StackWalk API instead? I guess it could be useful for identifying certain key functions but it still seems like a lot of work to add function calls all over the place when the information can be deduced from the actual call stack. |
||||
|
||||
All times are ET (US)![]() |
Last Thread Next Thread ![]() |
|