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 ARCH_STACKTRACE_H
25 #define ARCH_STACKTRACE_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 
43 
44 /// \addtogroup group_arch_Diagnostics
45 ///@{
46 
47 /// Dumps call-stack info to a file, and prints an informative message.
48 ///
49 /// The reason for the trace should be supplied in \p reason. This routine
50 /// can be slow and is intended to be called for a fatal error, such as a
51 /// caught coredump signal, but may be called at any time. 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 function is implemented by calling an external program. This is
56 /// suitable for times where the current process may be corrupted. In other
57 /// cases, using \c ArchPrintStackTrace() or other related functions would be
58 /// much faster.
59 ///
60 /// Note the use of \c char* as opposed to \c string: this is intentional,
61 /// because we are trying to use only async-safe function from here on and
62 /// malloc() is not async-safe.
65  const char* reason,
66  const char* message = nullptr,
67  const char* extraLogMsg = nullptr);
68 
69 /// Sets the command line that gathers call-stack info.
70 ///
71 /// This function sets the command line to execute to gather and log
72 /// call-stack info. \p argv must be NULL terminated. \p command and/or \p
73 /// argv may be NULL to suppress execution. Otherwise argv[0] must be the
74 /// full path to the program to execute, typically \p command or "$cmd" as
75 /// described below.
76 ///
77 /// \p command and \p argv are not copied and must remain valid until the next
78 /// call to \c ArchSetPostMortem.
79 ///
80 /// Simple substitution is supported on argv elements:
81 /// \li $cmd: Substitutes the command pathname, or $ARCH_POSTMORTEM if set
82 /// \li $pid: Substitutes the process id
83 /// \li $log: Substitutes the log pathname
84 /// \li $time: Substitutes the user time (if available, else wall time)
85 ///
86 /// \sa ArchLogPostMortem
88 void ArchSetPostMortem(const char* command, const char *const argv[]);
89 
90 /// Log session info.
91 ///
92 /// Optionally indicate that this is due to a crash by providing
93 /// the path to a file containing a stack trace in \p crashStackTrace.
94 ///
96 void ArchLogSessionInfo(const char *crashStackTrace=NULL);
97 
98 /// Sets the command line to log sessions.
99 ///
100 /// This function sets the command line to execute to log session info. \p
101 /// argv is used if no crash stack trace is provided, otherwise \p crashArgv
102 /// is used. Both must be NULL terminated. If \p command or \p argv is NULL
103 /// then non-crashes are not logged; if \p command or \p crashArgv is NULL
104 /// then crashes are not logged. If not NULL then argv[0] and crashArgv[0]
105 /// must be full path to the program to execute, typically \p command or
106 /// "$cmd" as described below.
107 ///
108 /// \p command, \p argv, and \p crashArgv are not copied and must remain valid
109 /// until the next call to \c ArchSetLogSession.
110 ///
111 /// Simple substitution is supported on argv elements:
112 /// \li $cmd: Substitutes the command pathname, or $ARCH_LOGSESSION if set
113 /// \li $prog Substitutes the program name
114 /// \li $pid: Substitutes the process id
115 /// \li $time: Substitutes the user time (if available, else wall time)
116 /// \li $stack: Substitutes the crash stack string (only in crashArgv)
117 ///
118 /// \sa ArchLogSessionInfo
119 ARCH_API
120 void ArchSetLogSession(const char* command,
121  const char* const argv[],
122  const char* const crashArgv[]);
123 
124 /// Register the callback to invoke logging at end of a successful session.
125 ///
126 /// This function registers ArchLogSessionInfo() and records the current
127 /// timestamp, to send up-time to the DB upon exiting.
128 ARCH_API
130 
131 /// Print a stack trace to the given FILE pointer.
132 ARCH_API
133 void ArchPrintStackTrace(FILE *fout,
134  const std::string& programName,
135  const std::string& reason);
136 
137 /// Print a stack trace to the given FILE pointer.
138 /// This function uses ArchGetProgramInfoForErrors as the \c programName.
139 /// \overload
140 ARCH_API
141 void ArchPrintStackTrace(FILE *fout, const std::string& reason);
142 
143 /// Print a stack trace to the given ostream.
144 /// \overload
145 ARCH_API
146 void ArchPrintStackTrace(std::ostream& out,
147  const std::string& programName,
148  const std::string& reason);
149 
150 /// Print a stack trace to the given ostream.
151 /// This function uses ArchGetProgramInfoForErrors as the \c programName.
152 /// \overload
153 ARCH_API
154 void ArchPrintStackTrace(std::ostream& out, const std::string& reason);
155 
156 /// A callback to get a symbolic representation of an address.
157 typedef std::function<std::string(uintptr_t address)> ArchStackTraceCallback;
158 
159 /// Sets a callback to get a symbolic representation of an address.
160 ///
161 /// The callback returns a string for an address in a stack trace, typically
162 /// including the name of the function containing the address. \p cb may be \c
163 /// NULL to use a default implementation.
164 ARCH_API
166 
167 /// Returns the callback to get a symbolic representation of an address.
168 /// \sa ArchSetStackTraceCallback
169 ARCH_API
171 
172 /// Returns the set value for the application's launch time.
173 /// The timestamp for this value is set when the arch library is initialized.
174 ARCH_API
175 time_t ArchGetAppLaunchTime();
176 
177 /// Enables or disables the automatic logging of crash information.
178 ///
179 /// This function controls whether the stack trace and build information is
180 /// automatically caught and stored to an internal database when a fatal crash
181 /// occurs.
182 ARCH_API
183 void ArchSetFatalStackLogging(bool flag);
184 
185 /// Returns whether automatic logging of fatal crashes is enabled
186 /// This is set to false by default.
187 /// \see ArchSetFatalStackLogging
188 ARCH_API
190 
191 /// Sets the program name to be used in diagnostic output
192 ///
193 /// The default value is initialized to ArchGetExecutablePath().
194 ARCH_API
195 void ArchSetProgramNameForErrors(const char * progName);
196 
197 /// Returns the currently set program name for reporting errors.
198 /// Defaults to ArchGetExecutablePath().
199 ARCH_API
200 const char * ArchGetProgramNameForErrors();
201 
202 /// Sets additional program info to be reported to the terminal in case of a
203 /// fatal error.
204 ARCH_API
205 void ArchSetProgramInfoForErrors( const std::string& key, const std::string& value );
206 
207 /// Returns currently set program info.
208 /// \see ArchSetExtraLogInfoForErrors
209 ARCH_API
211 
212 /// Stores (or removes if \p lines is nullptr) a pointer to additional log data
213 /// that will be output in the stack trace log in case of a fatal error. Note
214 /// that the pointer \p lines is copied, not the pointed-to data. In addition,
215 /// Arch might read the data pointed to by \p lines concurrently at any time.
216 /// Thus it is the caller's responsibility to ensure that \p lines is both valid
217 /// and not mutated until replacing or removing it by invoking this function
218 /// again with the same \p key and different \p lines.
219 ARCH_API
221  std::vector<std::string> const *lines);
222 
223 /// Logs a stack trace to a file in /var/tmp.
224 ///
225 /// This function is similar to \c ArchLogPostMortem(), but will not fork an
226 /// external process and only reports a stack trace. A file in /var/tmp is
227 /// created with the name \c st_APPNAME.XXXXXX, where \c mktemp is used to
228 /// make a unique extension for the file. If \c sessionLog is specified, then
229 /// it will be appended to this file. A message is printed to \c stderr
230 /// reporting that a stack trace has been taken and what file it has been
231 /// written to. And if \c fatal is true, then the stack trace will be added
232 /// to the stack_trace database table.
233 ARCH_API
234 void ArchLogStackTrace(const std::string& progName,
235  const std::string& reason,
236  bool fatal = false,
237  const std::string& sessionLog = "");
238 
239 /// Logs a stack trace to a file in /var/tmp.
240 ///
241 /// This function is similar to \c ArchLogPostMortem(), but will not fork an
242 /// external process and only reports a stack trace. A file in /var/tmp is
243 /// created with the name \c st_APPNAME.XXXXXX, where \c mktemp is used to
244 /// make a unique extension for the file. If \c sessionLog is specified,
245 /// then it will be appended to this file. A message is printed to \c stderr
246 /// reporting that a stack trace has been taken and what file it has been
247 /// written to. And if \c fatal is true, then the stack trace will be added
248 /// to the stack_trace database table.
249 ARCH_API
250 void ArchLogStackTrace(const std::string& reason,
251  bool fatal = false,
252  const std::string& sessionLog = "");
253 
254 /// Return stack trace.
255 ///
256 /// This function will return a vector of strings containing the current
257 /// stack. The vector will be of maximum size \p maxDepth.
258 ARCH_API
259 std::vector<std::string> ArchGetStackTrace(size_t maxDepth);
260 
261 
262 /// Save frames of current stack
263 ///
264 /// This function saves at maximum \c maxDepth frames of the current stack
265 /// into the vector \c frames.
266 ARCH_API
267 void ArchGetStackFrames(size_t maxDepth, std::vector<uintptr_t> *frames);
268 
269 /// Save frames of current stack.
270 ///
271 /// This function saves at maximum \p maxDepth frames of the current stack
272 /// into the vector \p frames, skipping the first \p numFramesToSkipAtTop
273 /// frames. The first frame will be at depth \p numFramesToSkipAtTop and the
274 /// last at depth \p numFramesToSkipAtTop + \p maxDepth - 1.
275 ARCH_API
276 void ArchGetStackFrames(size_t maxDepth, size_t numFramesToSkipAtTop,
277  std::vector<uintptr_t> *frames);
278 
279 /// Print stack frames to the given ostream.
280 ARCH_API
281 void ArchPrintStackFrames(std::ostream& out,
282  const std::vector<uintptr_t> &frames);
283 
284 /// Callback for handling crashes.
285 /// \see ArchCrashHandlerSystemv
286 typedef void (*ArchCrashHandlerSystemCB)(void* userData);
287 
288 /// Replacement for 'system' safe for a crash handler
289 ///
290 /// This function is a substitute for system() which does not allocate or free
291 /// any data, and times out after \c timeout seconds if the operation in \c
292 /// argv is not complete. Unlike system, it takes the full \c pathname of the
293 /// program to run, and won't search the path. Also unlike system, \c argv[]
294 /// are the separated arguments, starting with the program's name, as for
295 /// execv. \c callback is called every second. \c userData is passed to \c
296 /// callback. \c callback can be used, for example, to print a '.' repeatedly
297 /// to show progress. The alarm used in this function could interfere with
298 /// setitimer or other calls to alarm, and this function uses non-locking fork
299 /// and exec if available so should not generally be used except following a
300 /// catastrophe.
301 ARCH_API
302 int ArchCrashHandlerSystemv(const char* pathname, char *const argv[],
303  int timeout, ArchCrashHandlerSystemCB callback,
304  void* userData);
305 
306 /// Crash, to test crash behavior.
307 ///
308 /// This function causes the calling program to crash by doing bad malloc
309 /// and free things. If \c spawnthread is true, it spawns a thread which
310 /// remains alive during the crash. It aborts if it fails to crash.
311 ///
312 /// \private
313 ARCH_API
314 void ArchTestCrash(bool spawnthread);
315 
316 #if defined(ARCH_OS_DARWIN)
317 // macOS has no ETIME. ECANCELED seems to have about the closest meaning to
318 // the actual error here. The operation is timing out, not being explicitly
319 // canceled, but it is canceled.
320 #ifndef ETIME
321 #define ETIME ECANCELED
322 #endif // end ETIME
323 #endif // end ARCH_OS_DARWIN
324 
325 ///@}
326 
328 
329 #endif // ARCH_STACKTRACE_H
std::function< std::string(uintptr_t address)> ArchStackTraceCallback
A callback to get a symbolic representation of an address.
Definition: stackTrace.h:157
ARCH_API void ArchLogPostMortem(const char *reason, const char *message=nullptr, const char *extraLogMsg=nullptr)
ARCH_API void ArchGetStackFrames(size_t maxDepth, std::vector< uintptr_t > *frames)
ARCH_API int ArchCrashHandlerSystemv(const char *pathname, char *const argv[], int timeout, ArchCrashHandlerSystemCB callback, void *userData)
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 ArchSetPostMortem(const char *command, const char *const argv[])
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[])
ARCH_API void ArchGetStackTraceCallback(ArchStackTraceCallback *cb)
GLsizei GLenum GLuint GLuint GLsizei GLchar * message
Definition: glew.h:2581
void
Definition: png.h:1083
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)
GLsizei const GLchar *const * string
Definition: glew.h:1844
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1245
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:83
void(* ArchCrashHandlerSystemCB)(void *userData)
Definition: stackTrace.h:286
ARCH_API void ArchSetExtraLogInfoForErrors(const std::string &key, std::vector< std::string > const *lines)
ARCH_API std::vector< std::string > ArchGetStackTrace(size_t maxDepth)
#define ARCH_API
Definition: api.h:40
GLbitfield GLuint64 timeout
Definition: glew.h:6605
ARCH_API void ArchPrintStackFrames(std::ostream &out, const std::vector< uintptr_t > &frames)
Print stack frames to the given ostream.
GLsizei const GLfloat * value
Definition: glew.h:1849
ARCH_API time_t ArchGetAppLaunchTime()
ARCH_API void ArchEnableSessionLogging()
ARCH_API std::string ArchGetProgramInfoForErrors(const std::string &key)
ARCH_API void ArchSetFatalStackLogging(bool flag)