HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
stackTrace.h
Go to the documentation of this file.
1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #ifndef PXR_BASE_ARCH_STACK_TRACE_H
25 #define PXR_BASE_ARCH_STACK_TRACE_H
26 
27 /// \file arch/stackTrace.h
28 /// \ingroup group_arch_Diagnostics
29 /// Architecture-specific call-stack tracing routines.
30 
31 #include "pxr/pxr.h"
32 #include "pxr/base/arch/api.h"
33 #include "pxr/base/arch/defines.h"
34 
35 #include <inttypes.h>
36 #include <stdio.h>
37 #include <functional>
38 #include <vector>
39 #include <string>
40 #include <iosfwd>
41 #include <ctime>
42 
44 
45 /// \addtogroup group_arch_Diagnostics
46 ///@{
47 
48 /// Dumps call-stack info to a file, prints a message to the terminal, and
49 /// invokes crash handling script.
50 ///
51 /// The reason for the trace should be supplied in \p reason. An additional
52 /// message may be provided in \p message. If \p reason is \c NULL then this
53 /// function only writes \p message to the banner (if any).
54 ///
55 /// This routine can be slow and is intended to be called for a fatal error,
56 /// such as a caught coredump signal. While it can theoretically be called at
57 /// any time, \c ArchLogCurrentProcessState() should be used for nonfatal cases.
58 ///
59 /// This function is implemented by calling an external program. This is
60 /// suitable for times where the current process may be corrupted. In other
61 /// cases, using \c ArchPrintStackTrace() or other related functions would be
62 /// much faster.
63 ///
64 /// Note the use of \c char* as opposed to \c string: this is intentional,
65 /// because we are trying to use only async-safe function from here on and
66 /// malloc() is not async-safe.
68 void ArchLogFatalProcessState(const char* reason,
69  const char* message = nullptr,
70  const char* extraLogMsg = nullptr);
71 
72 /// Dumps call-stack info to a file, and prints an informative message.
73 ///
74 /// The reason for the trace should be supplied in \p reason. An additional
75 /// message may be provided in \p message. If \p reason is \c NULL then this
76 /// function only writes \p message to the banner (if any).
77 ///
78 /// This function is nearly identical to ArchLogFatalProcessState, including
79 /// calling an external program. However, it is intended for cases that may
80 /// simulate or require the output info from a full fatal crash, but are
81 /// not truly fatal errors. For cases where that is not necessary,
82 /// using \c ArchPrintStackTrace() or other related functions would be
83 /// much faster.
84 ///
85 /// Note the use of \c char* as opposed to \c string: this is intentional,
86 /// because we are trying to use only async-safe function from here on and
87 /// malloc() is not async-safe.
89 void ArchLogCurrentProcessState(const char* reason,
90  const char* message = nullptr,
91  const char* extraLogMsg = nullptr);
92 
93 /// Sets command line that gets call-stack info and triggers crash handling
94 /// script.
95 ///
96 /// This function sets the command line to execute to gather and log
97 /// call-stack info. \p argv must be NULL terminated. If \p command and/or \p
98 /// argv (or \p fatalArgv in the case of a fatal crash) are NULL, then
99 /// the command will not be executed. Otherwise argv[0] and fatalArgv[0] must be
100 /// the full path to the program to execute, typically \p command or "$cmd" as
101 /// described below.
102 ///
103 /// \p command, \p argv, and \p fatalArgv are not copied and must remain valid
104 /// until the next call to \c ArchSetProcessStateLogCommand.
105 ///
106 /// Simple substitution is supported on argv elements:
107 /// \li $cmd: Substitutes the command pathname, or $ARCH_POSTMORTEM if set
108 /// \li $pid: Substitutes the process id
109 /// \li $log: Substitutes the log pathname
110 /// \li $time: Substitutes the user time (if available, else wall time)
111 /// \li $reason: Substitutes the reason string for the crash
112 ///
113 /// \sa ArchLogFatalProcessState
114 ARCH_API
115 void ArchSetProcessStateLogCommand(const char* command,
116  const char *const argv[],
117  const char* const fatalArgv[]);
118 
119 /// Returns true if the fatal signal handler ArchLogFatalProcessState
120 /// has been invoked.
121 ARCH_API
122 bool ArchIsAppCrashing();
123 
124 /// Log session info.
125 ///
126 /// Optionally indicate that this is due to a crash by providing
127 /// the path to a file containing a stack trace in \p crashStackTrace.
128 ///
129 ARCH_API
130 void ArchLogSessionInfo(const char *crashStackTrace=NULL);
131 
132 /// Sets the command line to log sessions.
133 ///
134 /// This function sets the command line to execute to log session info. \p
135 /// argv is used if no crash stack trace is provided, otherwise \p crashArgv
136 /// is used. Both must be NULL terminated. If \p command or \p argv is NULL
137 /// then non-crashes are not logged; if \p command or \p crashArgv is NULL
138 /// then crashes are not logged. If not NULL then argv[0] and crashArgv[0]
139 /// must be full path to the program to execute, typically \p command or
140 /// "$cmd" as described below.
141 ///
142 /// \p command, \p argv, and \p crashArgv are not copied and must remain valid
143 /// until the next call to \c ArchSetLogSession.
144 ///
145 /// Simple substitution is supported on argv elements:
146 /// \li $cmd: Substitutes the command pathname, or $ARCH_LOGSESSION if set
147 /// \li $prog Substitutes the program name
148 /// \li $pid: Substitutes the process id
149 /// \li $time: Substitutes the user time (if available, else wall time)
150 /// \li $stack: Substitutes the crash stack string (only in crashArgv)
151 ///
152 /// \sa ArchLogSessionInfo
153 ARCH_API
154 void ArchSetLogSession(const char* command,
155  const char* const argv[],
156  const char* const crashArgv[]);
157 
158 /// Register the callback to invoke logging at end of a successful session.
159 ///
160 /// This function registers ArchLogSessionInfo() and records the current
161 /// timestamp, to send up-time to the DB upon exiting.
162 ARCH_API
164 
165 /// Print a stack trace to the given FILE pointer.
166 ARCH_API
167 void ArchPrintStackTrace(FILE *fout,
168  const std::string& programName,
169  const std::string& reason);
170 
171 /// Print a stack trace to the given FILE pointer.
172 /// This function uses ArchGetProgramInfoForErrors as the \c programName.
173 /// \overload
174 ARCH_API
175 void ArchPrintStackTrace(FILE *fout, const std::string& reason);
176 
177 /// Print a stack trace to the given ostream.
178 /// \overload
179 ARCH_API
180 void ArchPrintStackTrace(std::ostream& out,
181  const std::string& programName,
182  const std::string& reason);
183 
184 /// Print a stack trace to the given ostream.
185 /// This function uses ArchGetProgramInfoForErrors as the \c programName.
186 /// \overload
187 ARCH_API
188 void ArchPrintStackTrace(std::ostream& out, const std::string& reason);
189 
190 /// A callback to get a symbolic representation of an address.
191 typedef std::function<std::string(uintptr_t address)> ArchStackTraceCallback;
192 
193 /// Sets a callback to get a symbolic representation of an address.
194 ///
195 /// The callback returns a string for an address in a stack trace, typically
196 /// including the name of the function containing the address. \p cb may be \c
197 /// NULL to use a default implementation.
198 ARCH_API
200 
201 /// Returns the callback to get a symbolic representation of an address.
202 /// \sa ArchSetStackTraceCallback
203 ARCH_API
205 
206 /// Returns the set value for the application's launch time.
207 /// The timestamp for this value is set when the arch library is initialized.
208 ARCH_API
209 time_t ArchGetAppLaunchTime();
210 
211 /// Enables or disables the automatic logging of crash information.
212 ///
213 /// This function controls whether the stack trace and build information is
214 /// automatically caught and stored to an internal database when a fatal crash
215 /// occurs.
216 ARCH_API
217 void ArchSetFatalStackLogging(bool flag);
218 
219 /// Returns whether automatic logging of fatal crashes is enabled
220 /// This is set to false by default.
221 /// \see ArchSetFatalStackLogging
222 ARCH_API
224 
225 /// Sets the program name to be used in diagnostic output
226 ///
227 /// The default value is initialized to ArchGetExecutablePath().
228 ARCH_API
229 void ArchSetProgramNameForErrors(const char * progName);
230 
231 /// Returns the currently set program name for reporting errors.
232 /// Defaults to ArchGetExecutablePath().
233 ARCH_API
234 const char * ArchGetProgramNameForErrors();
235 
236 /// Sets additional program info to be reported to the terminal in case of a
237 /// fatal error.
238 ARCH_API
239 void ArchSetProgramInfoForErrors( const std::string& key, const std::string& value );
240 
241 /// Returns currently set program info.
242 /// \see ArchSetExtraLogInfoForErrors
243 ARCH_API
245 
246 /// Stores (or removes if \p lines is nullptr) a pointer to additional log data
247 /// that will be output in the stack trace log in case of a fatal error. Note
248 /// that the pointer \p lines is copied, not the pointed-to data. In addition,
249 /// Arch might read the data pointed to by \p lines concurrently at any time.
250 /// Thus it is the caller's responsibility to ensure that \p lines is both valid
251 /// and not mutated until replacing or removing it by invoking this function
252 /// again with the same \p key and different \p lines.
253 ARCH_API
255  std::vector<std::string> const *lines);
256 
257 /// Logs a stack trace to a file in /var/tmp.
258 ///
259 /// This function is similar to \c ArchLogPostMortem(), but will not fork an
260 /// external process and only reports a stack trace. A file in /var/tmp is
261 /// created with the name \c st_APPNAME.XXXXXX, where \c mktemp is used to
262 /// make a unique extension for the file. If \c sessionLog is specified, then
263 /// it will be appended to this file. A message is printed to \c stderr
264 /// reporting that a stack trace has been taken and what file it has been
265 /// written to. And if \c fatal is true, then the stack trace will be added
266 /// to the stack_trace database table.
267 ARCH_API
268 void ArchLogStackTrace(const std::string& progName,
269  const std::string& reason,
270  bool fatal = false,
271  const std::string& sessionLog = "");
272 
273 /// Logs a stack trace to a file in /var/tmp.
274 ///
275 /// This function is similar to \c ArchLogPostMortem(), but will not fork an
276 /// external process and only reports a stack trace. A file in /var/tmp is
277 /// created with the name \c st_APPNAME.XXXXXX, where \c mktemp is used to
278 /// make a unique extension for the file. If \c sessionLog is specified,
279 /// then it will be appended to this file. A message is printed to \c stderr
280 /// reporting that a stack trace has been taken and what file it has been
281 /// written to. And if \c fatal is true, then the stack trace will be added
282 /// to the stack_trace database table.
283 ARCH_API
284 void ArchLogStackTrace(const std::string& reason,
285  bool fatal = false,
286  const std::string& sessionLog = "");
287 
288 /// Return stack trace.
289 ///
290 /// This function will return a vector of strings containing the current
291 /// stack. The vector will be of maximum size \p maxDepth.
292 ARCH_API
293 std::vector<std::string> ArchGetStackTrace(size_t maxDepth);
294 
295 
296 /// Save frames of current stack
297 ///
298 /// This function saves at maximum \c maxDepth frames of the current stack
299 /// into the vector \c frames.
300 ARCH_API
301 void ArchGetStackFrames(size_t maxDepth, std::vector<uintptr_t> *frames);
302 
303 /// Store at most \p maxDepth frames of the current stack into \p frames.
304 /// Return the number of stack frames written to \p frames.
305 ARCH_API
306 size_t ArchGetStackFrames(size_t maxDepth, uintptr_t *frames);
307 
308 /// Save frames of current stack.
309 ///
310 /// This function saves at maximum \p maxDepth frames of the current stack
311 /// into the vector \p frames, skipping the first \p numFramesToSkipAtTop
312 /// frames. The first frame will be at depth \p numFramesToSkipAtTop and the
313 /// last at depth \p numFramesToSkipAtTop + \p maxDepth - 1.
314 ARCH_API
315 void ArchGetStackFrames(size_t maxDepth, size_t numFramesToSkipAtTop,
316  std::vector<uintptr_t> *frames);
317 
318 /// Store at most \p maxDepth frames of the current stack into \p frames,
319 /// skipping the first \p numFramesToSkipAtTop frames. Return the number of
320 /// stack frames written to \p frames.
321 ARCH_API
322 size_t ArchGetStackFrames(size_t maxDepth, size_t numFramesToSkipAtTop,
323  uintptr_t *frames);
324 
325 
326 /// Print stack frames to the given ostream.
327 ARCH_API
328 void ArchPrintStackFrames(std::ostream& out,
329  const std::vector<uintptr_t> &frames,
330  bool skipUnknownFrames = false);
331 
332 /// Callback for handling crashes.
333 /// \see ArchCrashHandlerSystemv
334 typedef void (*ArchCrashHandlerSystemCB)(void* userData);
335 
336 /// Replacement for 'system' safe for a crash handler
337 ///
338 /// This function is a substitute for system() which does not allocate or free
339 /// any data, and times out after \c timeout seconds if the operation in \c
340 /// argv is not complete. Unlike system, it takes the full \c pathname of the
341 /// program to run, and won't search the path. Also unlike system, \c argv[]
342 /// are the separated arguments, starting with the program's name, as for
343 /// execv. \c callback is called every second. \c userData is passed to \c
344 /// callback. \c callback can be used, for example, to print a '.' repeatedly
345 /// to show progress. The alarm used in this function could interfere with
346 /// setitimer or other calls to alarm, and this function uses non-locking fork
347 /// and exec if available so should not generally be used except following a
348 /// catastrophe.
349 ARCH_API
350 int ArchCrashHandlerSystemv(const char* pathname, char *const argv[],
351  int timeout, ArchCrashHandlerSystemCB callback,
352  void* userData);
353 
354 #if defined(ARCH_OS_DARWIN)
355 // macOS has no ETIME. ECANCELED seems to have about the closest meaning to
356 // the actual error here. The operation is timing out, not being explicitly
357 // canceled, but it is canceled.
358 #ifndef ETIME
359 #define ETIME ECANCELED
360 #endif // end ETIME
361 #endif // end ARCH_OS_DARWIN
362 
363 ///@}
364 
366 
367 #endif // PXR_BASE_ARCH_STACK_TRACE_H
std::function< std::string(uintptr_t address)> ArchStackTraceCallback
A callback to get a symbolic representation of an address.
Definition: stackTrace.h:191
GLuint GLsizei const GLchar * message
Definition: glcorearb.h:2543
ARCH_API void ArchSetProcessStateLogCommand(const char *command, const char *const argv[], const char *const fatalArgv[])
ARCH_API void ArchGetStackFrames(size_t maxDepth, std::vector< uintptr_t > *frames)
void
Definition: png.h:1083
ARCH_API int ArchCrashHandlerSystemv(const char *pathname, char *const argv[], int timeout, ArchCrashHandlerSystemCB callback, void *userData)
GLsizei const GLchar *const * string
Definition: glcorearb.h:814
ARCH_API void ArchLogFatalProcessState(const char *reason, const char *message=nullptr, const char *extraLogMsg=nullptr)
fallback_uintptr uintptr_t
Definition: format.h:295
ARCH_API bool ArchIsAppCrashing()
ARCH_API void ArchSetProgramNameForErrors(const char *progName)
ARCH_API void ArchLogSessionInfo(const char *crashStackTrace=NULL)
ARCH_API void ArchPrintStackTrace(FILE *fout, const std::string &programName, const std::string &reason)
Print a stack trace to the given FILE pointer.
ARCH_API void ArchLogStackTrace(const std::string &progName, const std::string &reason, bool fatal=false, const std::string &sessionLog="")
ARCH_API void ArchSetLogSession(const char *command, const char *const argv[], const char *const crashArgv[])
GLbitfield GLuint64 timeout
Definition: glcorearb.h:1599
ARCH_API void ArchLogCurrentProcessState(const char *reason, const char *message=nullptr, const char *extraLogMsg=nullptr)
ARCH_API void ArchGetStackTraceCallback(ArchStackTraceCallback *cb)
ARCH_API void ArchSetStackTraceCallback(const ArchStackTraceCallback &cb)
ARCH_API const char * ArchGetProgramNameForErrors()
ARCH_API bool ArchGetFatalStackLogging()
ARCH_API void ArchSetProgramInfoForErrors(const std::string &key, const std::string &value)
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1441
ARCH_API void ArchPrintStackFrames(std::ostream &out, const std::vector< uintptr_t > &frames, bool skipUnknownFrames=false)
Print stack frames to the given ostream.
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
void(* ArchCrashHandlerSystemCB)(void *userData)
Definition: stackTrace.h:334
ARCH_API void ArchSetExtraLogInfoForErrors(const std::string &key, std::vector< std::string > const *lines)
Definition: core.h:1131
ARCH_API std::vector< std::string > ArchGetStackTrace(size_t maxDepth)
#define ARCH_API
Definition: api.h:40
ARCH_API time_t ArchGetAppLaunchTime()
ARCH_API void ArchEnableSessionLogging()
ARCH_API std::string ArchGetProgramInfoForErrors(const std::string &key)
ARCH_API void ArchSetFatalStackLogging(bool flag)