BDE 4.14.0 Production release
Loading...
Searching...
No Matches
balst_stacktraceprinter.h
Go to the documentation of this file.
1/// @file balst_stacktraceprinter.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// balst_stacktraceprinter.h -*-C++-*-
8#ifndef INCLUDED_BALST_STACKTRACEPRINTER
9#define INCLUDED_BALST_STACKTRACEPRINTER
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup balst_stacktraceprinter balst_stacktraceprinter
15/// @brief Provide an object for streaming the current stack trace.
16/// @addtogroup bal
17/// @{
18/// @addtogroup balst
19/// @{
20/// @addtogroup balst_stacktraceprinter
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#balst_stacktraceprinter-purpose"> Purpose</a>
25/// * <a href="#balst_stacktraceprinter-classes"> Classes </a>
26/// * <a href="#balst_stacktraceprinter-description"> Description </a>
27/// * <a href="#balst_stacktraceprinter-usage"> Usage </a>
28/// * <a href="#balst_stacktraceprinter-example-1-streaming-to-ball"> Example 1: Streaming to BALL </a>
29///
30/// # Purpose {#balst_stacktraceprinter-purpose}
31/// Provide an object for streaming the current stack trace.
32///
33/// # Classes {#balst_stacktraceprinter-classes}
34///
35/// - balst::StackTracePrinter: object for streaming the current stack trace
36///
37/// @see balst_stacktraceprintutil
38///
39/// # Description {#balst_stacktraceprinter-description}
40/// This component provides a mechanism,
41/// `balst::StackTracePrinter`, that when streamed (using a streaming operator)
42/// renders a description of the current call-stack to the supplied stream.
43/// This class can, at construction, be passed up to 3 optional arguments to
44/// drive the details with which the stack trace is to be performed. Not all
45/// properties of a stack trace are printed on all platforms because the set of
46/// properties describing a stack trace that are obtainable varies according to
47/// both the platform and build parameters. For example, on Solaris, source
48/// file names and line numbers are not provided. Function names and addresses
49/// are provided on all platforms. Streaming a `balst::StackTracePrinter`
50/// always prints a description of the stack of the calling thread.
51///
52/// ## Usage {#balst_stacktraceprinter-usage}
53///
54///
55/// In this section we show the intended usage of this component.
56///
57/// ### Example 1: Streaming to BALL {#balst_stacktraceprinter-example-1-streaming-to-ball}
58///
59///
60/// First, we define a recursive function `recurseAndPrintStack` that recurses 4
61/// times, then calls `<< StackTracePrinter()` to obtain a stack trace and print
62/// it to `BALL_LOG_FATAL`:
63/// @code
64/// BALL_LOG_SET_NAMESPACE_CATEGORY("MY.CATEGORY");
65///
66/// void recurseAndStreamStackDefault()
67/// // Recurse 4 times and print a stack trace to 'BALL_LOG_FATAL'.
68/// {
69/// static int recurseCount = 0;
70///
71/// if (recurseCount++ < 4) {
72/// recurseAndStreamStackDefault();
73/// }
74/// else {
75/// BALL_LOG_FATAL << balst::StackTracePrinter();
76/// }
77/// }
78/// @endcode
79/// which, on Linux, produces the output:
80/// @code
81/// 02SEP2021_21:55:58.619290 21325 140602555295616 FATAL /bb/.../balst_stacktr
82/// aceprinter.t.cpp 733 UNINITIALIZED_LOGGER_MANAGER
83/// (0): recurseAndStreamStackDefault()+0xcf at 0x408acc source:balst_stacktrac
84/// eprinter.t.cpp:733 in balst_stacktraceprinter.t
85/// (1): recurseAndStreamStackDefault()+0x2a at 0x408a27 source:balst_stacktrac
86/// eprinter.t.cpp:735 in balst_stacktraceprinter.t
87/// (2): recurseAndStreamStackDefault()+0x2a at 0x408a27 source:balst_stacktrac
88/// eprinter.t.cpp:735 in balst_stacktraceprinter.t
89/// (3): recurseAndStreamStackDefault()+0x2a at 0x408a27 source:balst_stacktrac
90/// eprinter.t.cpp:735 in balst_stacktraceprinter.t
91/// (4): recurseAndStreamStackDefault()+0x2a at 0x408a27 source:balst_stacktrac
92/// eprinter.t.cpp:735 in balst_stacktraceprinter.t
93/// (5): main+0x1a7 at 0x408ff8 source:balst_stacktraceprinter.t.cpp:901 in bal
94/// st_stacktraceprinter.t
95/// (6): __libc_start_main+0xf5 at 0x7fe0943de495 in /lib64/libc.so.6
96/// (7): --unknown-- at 0x4074c5 in balst_stacktraceprinter.t
97/// @endcode
98/// Note that long lines of output here have been hand-wrapped to fit into
99/// comments in this 79-column source file. Also note that if the full path of
100/// the executable or library is too long, only the basename will be displayed
101/// by the facility, while if it is short, then the full path will be displayed.
102///
103/// Then we define a similar recursive function, except that when we construct
104/// the `StackTracePrinter` object, we pass 2 to the `maxFrames` argument,
105/// indicating, for some reason, that we want to see only the top two stack
106/// frames:
107/// @code
108/// void recurseAndStreamStackMaxFrames2()
109/// // Recurse 4 times and print a stack trace to 'BALL_LOG_FATAL'.
110/// {
111/// static int recurseCount = 0;
112///
113/// if (recurseCount++ < 4) {
114/// recurseAndStreamStackMaxFrames2();
115/// }
116/// else {
117/// BALL_LOG_FATAL << balst::StackTracePrinter(2);
118/// }
119/// }
120/// @endcode
121/// which produces the output:
122/// @code
123/// 02SEP2021_21:55:58.624623 21325 140602555295616 FATAL /bb/.../balst_stacktr
124/// aceprinter.t.cpp 773 UNINITIALIZED_LOGGER_MANAGER
125/// (0): recurseAndStreamStackMaxFrames2()+0xcf at 0x408be1 source:balst_stackt
126/// raceprinter.t.cpp:773 in balst_stacktraceprinter.t
127/// (1): recurseAndStreamStackMaxFrames2()+0x2a at 0x408b3c source:balst_stackt
128/// raceprinter.t.cpp:775 in balst_stacktraceprinter.t
129/// @endcode
130/// Now, we define another similar recursive function, except that when we
131/// construct the `StackTracePrinter` object, we default `maxFrames` to a large
132/// value by passing it -1, and turn off demangling by passing `false` to the
133/// `damanglingPreferredFlag` argument:
134/// @code
135/// void recurseAndStreamStackNoDemangle()
136/// // Recurse 4 times and print a stack trace to 'BALL_LOG_FATAL'.
137/// {
138/// static int recurseCount = 0;
139///
140/// if (recurseCount++ < 4) {
141/// recurseAndStreamStackNoDemangle();
142/// }
143/// else {
144/// BALL_LOG_FATAL << balst::StackTracePrinter(-1, false);
145/// }
146/// }
147/// @endcode
148/// which produces the output:
149/// @code
150/// 02SEP2021_21:55:58.636414 21325 140602555295616 FATAL /bb/.../balst_stacktr
151/// aceprinter.t.cpp 798 UNINITIALIZED_LOGGER_MANAGER
152/// (0): _Z31recurseAndStreamStackNoDemanglev+0xcf at 0x408cf6 source:balst_sta
153/// cktraceprinter.t.cpp:798 in balst_stacktraceprinter.t
154/// (1): _Z31recurseAndStreamStackNoDemanglev+0x2a at 0x408c51 source:balst_sta
155/// cktraceprinter.t.cpp:800 in balst_stacktraceprinter.t
156/// (2): _Z31recurseAndStreamStackNoDemanglev+0x2a at 0x408c51 source:balst_sta
157/// cktraceprinter.t.cpp:800 in balst_stacktraceprinter.t
158/// (3): _Z31recurseAndStreamStackNoDemanglev+0x2a at 0x408c51 source:balst_sta
159/// cktraceprinter.t.cpp:800 in balst_stacktraceprinter.t
160/// (4): _Z31recurseAndStreamStackNoDemanglev+0x2a at 0x408c51 source:balst_sta
161/// cktraceprinter.t.cpp:800 in balst_stacktraceprinter.t
162/// (5): main+0x1b1 at 0x409002 source:balst_stacktraceprinter.t.cpp:903 in bal
163/// st_stacktraceprinter.t
164/// (6): __libc_start_main+0xf5 at 0x7fe0943de495 in /lib64/libc.so.6
165/// (7): --unknown-- at 0x4074c5 in balst_stacktraceprinter.t
166/// @endcode
167/// Finally, we define another similar recursive function, except that we pass
168/// default values to the first 2 arguments of the `StackTracePrinter` and pass
169/// 5 to the third `additionalIgnoreFrames` argument. This indicates a number
170/// of frames from the top of the stack to be ignored, which may be desired if
171/// the caller wants to do the streaming from within their own stack trace
172/// facility, in which case the top couple of frames would be within that stack
173/// trace facility, and unwanted and distracting for clients of that facility:
174/// @code
175/// void recurseAndStreamStackAddIgnore5()
176/// // Recurse 4 times and print a stack trace to 'BALL_LOG_FATAL'.
177/// {
178/// static int recurseCount = 0;
179///
180/// if (recurseCount++ < 4) {
181/// recurseAndStreamStackAddIgnore5();
182/// }
183/// else {
184/// BALL_LOG_FATAL << balst::StackTracePrinter(-1, true, 5);
185/// }
186/// }
187/// @endcode
188/// which produces the output:
189/// @code
190/// 02SEP2021_21:55:58.647501 21325 140602555295616 FATAL /bb/.../balst_stacktr
191/// aceprinter.t.cpp 836 UNINITIALIZED_LOGGER_MANAGER
192/// (0): main+0x1b6 at 0x409007 source:balst_stacktraceprinter.t.cpp:904 in bal
193/// st_stacktraceprinter.t
194/// (1): __libc_start_main+0xf5 at 0x7fe0943de495 in /lib64/libc.so.6
195/// (2): --unknown-- at 0x4074c5 in balst_stacktraceprinter.t
196/// @endcode
197/// @}
198/** @} */
199/** @} */
200
201/** @addtogroup bal
202 * @{
203 */
204/** @addtogroup balst
205 * @{
206 */
207/** @addtogroup balst_stacktraceprinter
208 * @{
209 */
210
211#include <balscm_version.h>
212
214
215#include <bsl_ostream.h>
216
217
218namespace balst {
219
220 // =======================
221 // class StackTracePrinter
222 // =======================
223
224/// This `class` defines an object that, if streamed to a `bsl::ostream`,
225/// will output a stack trace to that stream.
226///
227/// See @ref balst_stacktraceprinter
229
230 // PRIVATE TYPES
231 enum { k_DEFAULT_MAX_FRAMES = 1024 };
232
233 // DATA
234 int d_maxFrames; // maximum # of frames to show
235
236 bool d_demanglingPreferredFlag;
237 // whether symbols are to be demangled
238
239 int d_additionalIgnoreFrames;
240 // the number of the frames on the top of
241 // the stack that are not to be displayed,
242 // in addition to
243 // 'bsls::StackAddressUtil::k_IGNORE_FRAMES'
244
245 // FRIENDS
246 friend bsl::ostream& operator<<(bsl::ostream&, const StackTracePrinter&);
247
248 private:
249 // NOT IMPLEMENTED
250 StackTracePrinter& operator=(const StackTracePrinter&);
251
252 public:
253 // CREATORS
254
255 /// Create a `StackTracePrinter` object that will, if streamed, render a
256 /// description of the current call stack to the stream. Optionally
257 /// specify `maxFrames` indicating maximum number of frames to dispay.
258 /// If `maxFrames` is -1 or unspecified, use a value of at least 1024.
259 /// The optionally specified `demanglingPreferredFlag` determines
260 /// whether demangling occurs, on platforms where demangling is
261 /// available and optional. Optionally specify `additionalIgnoreFrames`
262 /// which is added to `bsls::StackAddressUtil::k_IGNORE_FRAMES` to
263 /// ignore the topmost frames of the caller. Return a reference to
264 /// `stream`. The behavior is undefined unless `-1 == maxFrames` or
265 /// `0 <= maxFrames`, and unless `0 <= additionalIgnoreFrames`.
266 explicit StackTracePrinter(int maxFrames = -1,
267 bool demanglingPreferredFlag = true,
268 int additionalIgnoreFrames = 0);
269
270#ifdef BSLS_COMPILERFEATURES_SUPPORT_DEFAULTED_FUNCTIONS
271 StackTracePrinter(const StackTracePrinter& original) = default;
272#endif
273 // Create a copy of the specified 'original'. Default the copy
274 // constructor to work around a bug on the Aix compiler that generates
275 // warnings every time an object of this type is passed to 'operator<<'
276 // if this constructor is deleted or private.
277};
278
279/// Stream a newline followed by a multiline stack trace according to the
280/// parameters passed to the specified `object` at its creation to the
281/// specified `stream`.
282bsl::ostream& operator<<(bsl::ostream& stream,
283 const StackTracePrinter& object);
284
285} // close package namespace
286
287
288#endif
289
290// ----------------------------------------------------------------------------
291// Copyright 2021 Bloomberg Finance L.P.
292//
293// Licensed under the Apache License, Version 2.0 (the "License");
294// you may not use this file except in compliance with the License.
295// You may obtain a copy of the License at
296//
297// http://www.apache.org/licenses/LICENSE-2.0
298//
299// Unless required by applicable law or agreed to in writing, software
300// distributed under the License is distributed on an "AS IS" BASIS,
301// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
302// See the License for the specific language governing permissions and
303// limitations under the License.
304// ----------------------------- END-OF-FILE ----------------------------------
305
306/** @} */
307/** @} */
308/** @} */
Definition balst_stacktraceprinter.h:228
friend bsl::ostream & operator<<(bsl::ostream &, const StackTracePrinter &)
StackTracePrinter(int maxFrames=-1, bool demanglingPreferredFlag=true, int additionalIgnoreFrames=0)
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition balst_objectfileformat.h:161
bsl::ostream & operator<<(bsl::ostream &stream, const StackTrace &object)