// -*- C++ -*- //============================================================================= /** * @file Stack_Trace.h * * @author Chris Cleeland (cleeland.ociweb.com) */ //============================================================================= #ifndef ACE_STACK_TRACE_H #define ACE_STACK_TRACE_H #include /**/ "ace/pre.h" #include "ace/ACE_export.h" #include "ace/Basic_Types.h" # if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once # endif /* ACE_LACKS_PRAGMA_ONCE */ # ifndef ACE_STACK_TRACE_SYMBUFSIZ # define ACE_STACK_TRACE_SYMBUFSIZ 4096 # endif ACE_BEGIN_VERSIONED_NAMESPACE_DECL /** * @class ACE_Stack_Trace * * @brief Encapsulate a string representation of a stack trace on supported platforms. * Stack traces for code built with optimize=1 (or "Release" configs on Visual * Studio) may be misleading (missng frames) due to inlining performed by the * compiler, which is indepenent of the inline=0 / inline=1 build option and * the __ACE_INLINE__ / ACE_NO_INLINE macros. * * A new conversion character, the question mark, was added to ACE_Log_Msg for stack * trace logging. The %? conversion character was added as a convenience so that users * need not instantiate an ACE_Stack_Trace instance solely for the purpose of printing * it in an ACE logging message. The following are functionally equivalent: * * \code * ACELIB_DEBUG((LM_DEBUG, "%?")); * * ACE_Stack_Trace st; * ACELIB_DEBUG ((LM_DEBUG, "%C", st.c_str() )); * \endcode * * These usage examples were shown in $ACE_ROOT/tests/Stack_Trace_Test.cpp. * * @note The stack trace functionality was currently supported on platforms: * - Any platform using glibc as its runtime library, or where ACE_HAS_EXECINFO_H is defined * (this covers Linux and Mac) and gcc version >= 3.3. * - VxWorks, both kernel and RTP * - Windows 32 and 64 bit (Visual C++) * * @note Since stack trace buffer size has limitation(@c ACE_STACK_TRACE_SYMBUFSIZ), you will not * get a complete stack trace if @c ACE_STACK_TRACE_SYMBUFSIZ value is less than actual stack * trace data length. To get a complete stack trace, you need set @c ACE_STACK_TRACE_SYMBUFSIZ * with a larger value that is enough for the stack trace data in your @c config.h file * and rebuild ACE. * * @note Using ACE logging mechanism (%?) to log the stack trace also has ACE_MAXLOGMSGLEN size limitation. * To get a complete stack trace, you could use different output method. Following is an example. * * \code * ACE_Stack_Trace st; * ACE_OS::printf("at [%s]\n", st.c_str()); * \endcode */ class ACE_Export ACE_Stack_Trace { public: /** * @brief Grab a snapshot of the current stack trace and hold it for later use. * * @param starting_frame_offset offset into the array of frames to start printing; 0 is the * platform-specific offset for the first frame, positive numbers give less frames, negative give * more frames * @param num_frames the number of stack frames to include (0 indicates platform-specific maximum) * */ explicit ACE_Stack_Trace (ssize_t starting_frame_offset = 0, size_t num_frames = 0); /** * @brief Return buffer as a C-style string. * @return C-style string with string representation of stack trace. * @note Lifecycle of string follows lifecycle of ACE_Stack_Trace instance. */ const char* c_str() const; static const size_t SYMBUFSIZ = ACE_STACK_TRACE_SYMBUFSIZ; private: char buf_[SYMBUFSIZ]; size_t buflen_; static const char UNSUPPORTED[]; static const char UNABLE_TO_GET_TRACE[]; void generate_trace (ssize_t starting_frame_offset, size_t num_frames); }; ACE_END_VERSIONED_NAMESPACE_DECL #include /**/ "ace/post.h" #endif /* ACE_STACK_TRACE_H */