BDE 4.14.0 Production release
Loading...
Searching...
No Matches
balst_stacktraceprintutil.h
Go to the documentation of this file.
1/// @file balst_stacktraceprintutil.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// balst_stacktraceprintutil.h -*-C++-*-
8#ifndef INCLUDED_BALST_STACKTRACEPRINTUTIL
9#define INCLUDED_BALST_STACKTRACEPRINTUTIL
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup balst_stacktraceprintutil balst_stacktraceprintutil
15/// @brief Provide a single function to perform and print a stack trace.
16/// @addtogroup bal
17/// @{
18/// @addtogroup balst
19/// @{
20/// @addtogroup balst_stacktraceprintutil
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#balst_stacktraceprintutil-purpose"> Purpose</a>
25/// * <a href="#balst_stacktraceprintutil-classes"> Classes </a>
26/// * <a href="#balst_stacktraceprintutil-description"> Description </a>
27/// * <a href="#balst_stacktraceprintutil-logexceptionstacktrace"> logExceptionStackTrace </a>
28/// * <a href="#balst_stacktraceprintutil-usage"> Usage </a>
29/// * <a href="#balst_stacktraceprintutil-example-1-printing-a-stack-trace"> Example 1: Printing a Stack Trace </a>
30///
31/// # Purpose {#balst_stacktraceprintutil-purpose}
32/// Provide a single function to perform and print a stack trace.
33///
34/// # Classes {#balst_stacktraceprintutil-classes}
35///
36/// - balst::StackTracePrintUtil: namespace for functions to print a stack trace
37///
38/// @see balst_stacktraceutil
39///
40/// # Description {#balst_stacktraceprintutil-description}
41/// This component defines a namespace `struct`,
42/// `balst::StackTracePrintUtil`, containing static platform-independent
43/// functions that will perform a stack trace and print it to a supplied stream.
44/// Not all properties of a stack trace are printed on all platforms because the
45/// set of properties describing a stack trace that are obtainable varies
46/// according to both the platform and build parameters. For example, on
47/// Solaris, source file names and line numbers are not provided. Function
48/// names and addresses are provided on all platforms. The `printStackTrace`
49/// function always prints a description of the stack of the calling thread.
50///
51/// ## logExceptionStackTrace {#balst_stacktraceprintutil-logexceptionstacktrace}
52///
53///
54/// The function `StackTracePrintUtil::logExceptionStackTrace` is meant to be
55/// passed as a function pointer to the `bslstl::StdExceptUtil::set*Hook`
56/// functions and will result in a stack trace being logged with fatal severity
57/// prior to the respective exception being thrown. It is a substitute for the
58/// function `bslstl::StdExceptUtil::logCheapStackTrace` that takes longer to
59/// run but provides far superior output.
60///
61/// ## Usage {#balst_stacktraceprintutil-usage}
62///
63///
64/// This section illustrates intended use of this component.
65///
66/// ### Example 1: Printing a Stack Trace {#balst_stacktraceprintutil-example-1-printing-a-stack-trace}
67///
68///
69/// This example shows how to obtain a stack trace and print it to a stream, all
70/// by calling just the static function
71/// `balst::StackTracePrintUtil::printStackTrace`.
72///
73/// First, we define a recursive function `recurseAndPrintStack` that recurses
74/// to the specified `depth`, then calls
75/// `balst::StackTracePrintUtil::printStackTrace` to obtain a stack trace and
76/// print it to `cout`. When we call `printStackTrace`, neither of the optional
77/// arguments corresponding to `maxFrames` or `demanglingPreferredFlag` are
78/// supplied; `maxFrames` defaults to at least 1024 (which is more than we
79/// need), and `demanglingPreferredFlag` defaults to `true`.
80/// @code
81/// static
82/// void recurseAndPrintStack(int *depth)
83/// // Recurse to the specified 'depth', then print out the stack trace to
84/// // 'cout'.
85/// {
86/// if (--*depth > 0) {
87/// recurseAndPrintStack(depth);
88/// }
89/// else {
90/// balst::StackTracePrintUtil::printStackTrace(cout);
91/// }
92///
93/// ++*depth; // Prevent compiler from optimizing tail recursion as a
94/// // loop.
95/// }
96/// @endcode
97/// Then, we call `recurseAndPrintStack` from the main program.
98/// @code
99/// int main()
100/// {
101/// int depth = 5;
102/// recurseAndPrintStack(&depth);
103/// assert(5 == depth);
104/// }
105/// @endcode
106/// Now, invoking the main program on AIX produces the following output:
107/// @code
108/// (0): BloombergLP::balst::StackTracePrintUtil::.printStackTrace(
109/// std::basic_ostream<char,std::char_traits<char> >&,int,bool)+0x170 at
110/// 0x1000a2c8 source:balst_stacktraceprintutil.cpp:52 in
111/// balst_stacktraceprintutil.t.dbg_
112/// (1): .recurseAndPrintStack(int*)+0x58 at 0x1000a118
113/// source:balst_stacktraceprintutil.t.cpp:652 in
114/// balst_stacktraceprintutil.t.dbg_
115/// (2): .recurseAndPrintStack(int*)+0x40 at 0x1000a100
116/// source:balst_stacktraceprintutil.t.cpp:650
117/// in balst_stacktraceprintutil.t.dbg_
118/// (3): .recurseAndPrintStack(int*)+0x40 at 0x1000a100
119/// source:balst_stacktraceprintutil.t.cpp:650 in
120/// balst_stacktraceprintutil.t.dbg_
121/// (4): .recurseAndPrintStack(int*)+0x40 at 0x1000a100
122/// source:balst_stacktraceprintutil.t.cpp:650 in
123/// balst_stacktraceprintutil.t.dbg_
124/// (5): .recurseAndPrintStack(int*)+0x40 at 0x1000a100
125/// source:balst_stacktraceprintutil.t.cpp:650 in
126/// balst_stacktraceprintutil.t.dbg_
127/// (6): .main+0x2f4 at 0x10000a4c source:balst_stacktraceprintutil.t.cpp:724
128/// in balst_stacktraceprintutil.t.dbg_
129/// (7): .__start+0x6c at 0x1000020c source:crt0main.s in
130/// balst_stacktraceprintutil.t.dbg_
131/// @endcode
132/// Finally, we observe the following about the above output to `cout`. Notice
133/// that since the actual output would write each stack trace frame all on a
134/// single line, and all the lines here were longer than 80 characters, it has
135/// been manually edited to wrap and have every line be less than 80 columns.
136/// Also note the program name is truncated to 32 characters in length.
137/// @}
138/** @} */
139/** @} */
140
141/** @addtogroup bal
142 * @{
143 */
144/** @addtogroup balst
145 * @{
146 */
147/** @addtogroup balst_stacktraceprintutil
148 * @{
149 */
150
151#include <balscm_version.h>
152
153#include <bslma_allocator.h>
155
156#include <bsl_iosfwd.h>
157#include <bsl_sstream.h>
158#include <bsl_string.h>
159
160
161
162namespace balst {
163 // =========================
164 // class StackTracePrintUtil
165 // =========================
166
167/// This `struct` serves as a namespace for static methods that perform and
168/// print a description of a stack trace.
170
171 // CLASS METHODS
172
173 /// Obtain a trace of the stack and print it to the specified `stream`.
174 /// Optionally specify `maxFrames` indicating the maximum number of
175 /// frames from the top of the stack that will be printed. If
176 /// `maxFrames` is not specified, a value of at least 1024 is used.
177 /// Optionally specify `demanglingPreferredFlag`, indicating a
178 /// preference whether to attempt to demangle function names. If
179 /// `damanglingPreferredFlag` is not specified, an attempt to demangle
180 /// is assumed. If an error occurs, a single-line error message is
181 /// printed to `stream`. Optionally specify `additionalIgnoreFrames`
182 /// which is added to `bsls::StackAddressUtil::k_IGNORE_FRAMES` to
183 /// ignore frames of the caller. Return a reference to 'stream. The
184 /// behavior is undefined unless `-1 <= maxFrames` and
185 /// `0 <= additionalIgnoreFrames`. Note that attempting to demangle
186 /// symbol names could involve calling `malloc`, and that symbol names
187 /// are always demangled on the Windows platform.
188 static bsl::ostream& printStackTrace(
189 bsl::ostream& stream,
190 int maxFrames = -1,
191 bool demanglingPreferredFlag = true,
192 int additionalIgnoreFrames = 0);
193
194 /// Log a message using `BSLS_LOG` consisting of "About to throw
195 /// <exceptionName>. <message>" followed by a stack trace. This
196 /// function is to be set as an exception "pre throw hook" for the
197 /// component @ref bslstl_stdexceptutil . If this funciton is set as the
198 /// pre throw hook, it will be called prior to exceptions being thrown,
199 /// Note that this function requires considerable disk access and is
200 /// therefore slow, so it should not be used for frequently-occurring
201 /// exceptions that are expected to be caught and recovered from.
202 static void logExceptionStackTrace(const char *exceptionName,
203 const char *message);
204};
205
206 // ==============================
207 // class StackTracePrintUtil_Test
208 // ==============================
209
210/// This `struct` is not intended for use by clients of this component; it
211/// exists only for testing purposes.
213
214 // CLASS METHODS
215
216 /// Obtain a stack trace and assign a description of the stack to the
217 /// specified `string`. Note that this method is for testing only, and
218 /// must be declared inline in an include file in order to test source
219 /// file name resolution of a routine in an include file.
220 static void printStackTraceToString(bsl::string *string);
221};
222
223// ============================================================================
224// INLINE FUNCTION DEFINITIONS
225// ============================================================================
226
227 // -------------------------------
228 // struct StackTracePrintUtil_Test
229 // -------------------------------
230
231// CLASS METHOD
232inline
234{
235 bslma::Allocator *a = string->get_allocator().mechanism();
237
240 *string = os.str();
241}
242
243} // close package namespace
244
245
246#endif
247
248// ----------------------------------------------------------------------------
249// Copyright 2015 Bloomberg Finance L.P.
250//
251// Licensed under the Apache License, Version 2.0 (the "License");
252// you may not use this file except in compliance with the License.
253// You may obtain a copy of the License at
254//
255// http://www.apache.org/licenses/LICENSE-2.0
256//
257// Unless required by applicable law or agreed to in writing, software
258// distributed under the License is distributed on an "AS IS" BASIS,
259// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
260// See the License for the specific language governing permissions and
261// limitations under the License.
262// ----------------------------- END-OF-FILE ----------------------------------
263
264/** @} */
265/** @} */
266/** @} */
Definition bslstl_ostringstream.h:175
void str(const StringType &value)
Definition bslstl_ostringstream.h:581
Definition bslstl_string.h:1281
Definition bslma_allocator.h:457
Definition bslma_defaultallocatorguard.h:186
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition balst_objectfileformat.h:161
Definition balst_stacktraceprintutil.h:212
static void printStackTraceToString(bsl::string *string)
Definition balst_stacktraceprintutil.h:233
Definition balst_stacktraceprintutil.h:169
static bsl::ostream & printStackTrace(bsl::ostream &stream, int maxFrames=-1, bool demanglingPreferredFlag=true, int additionalIgnoreFrames=0)
static void logExceptionStackTrace(const char *exceptionName, const char *message)