Loading...
Searching...
No Matches
diagnosticMgr.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_TF_DIAGNOSTIC_MGR_H
25#define PXR_BASE_TF_DIAGNOSTIC_MGR_H
26
28
29#include "pxr/pxr.h"
31#include "pxr/base/tf/debug.h"
33#include "pxr/base/tf/error.h"
35#include "pxr/base/tf/status.h"
37#include "pxr/base/tf/warning.h"
38#include "pxr/base/tf/weakPtr.h"
39#include "pxr/base/tf/enum.h"
40#include "pxr/base/tf/api.h"
41
45
46#include <tbb/enumerable_thread_specific.h>
47#include <tbb/spin_rw_mutex.h>
48
49#include <atomic>
50#include <cstdarg>
51#include <list>
52#include <string>
53#include <vector>
54
55PXR_NAMESPACE_OPEN_SCOPE
56
58 TF_LOG_STACK_TRACE_ON_ERROR,
59 TF_LOG_STACK_TRACE_ON_WARNING,
60 TF_ERROR_MARK_TRACKING,
61 TF_PRINT_ALL_POSTED_ERRORS_TO_STDERR
62 );
63
64class TfError;
65class TfErrorMark;
66
72public:
73
74 typedef TfDiagnosticMgr This;
75
76 typedef std::list<TfError> ErrorList;
77
96 typedef ErrorList::iterator ErrorIterator;
97
99 TF_API
100 static std::string GetCodeName(const TfEnum &code);
101
106 TF_API
107 static std::string FormatDiagnostic(const TfEnum &code,
108 const TfCallContext &context, const std::string &msg,
109 const TfDiagnosticInfo &info);
110
128 class Delegate {
129 public:
130 TF_API
131 virtual ~Delegate() = 0;
132
134 virtual void IssueError(TfError const &err) = 0;
135
138 virtual void IssueFatalError(TfCallContext const &context,
139 std::string const &msg) = 0;
140
142 virtual void IssueStatus(TfStatus const &status) = 0;
143
145 virtual void IssueWarning(TfWarning const &warning) = 0;
146
147 protected:
151 TF_API
152 void _UnhandledAbort() const;
153 };
154
156 TF_API static This &GetInstance() {
158 }
159
167 TF_API
168 void AddDelegate(Delegate* delegate);
169
173 TF_API
174 void RemoveDelegate(Delegate* delegate);
175
178 TF_API
179 void SetQuiet(bool quiet) { _quiet = quiet; }
180
182 ErrorIterator GetErrorBegin() { return _errorList.local().begin(); }
183
185 ErrorIterator GetErrorEnd() { return _errorList.local().end(); }
186
189 TF_API
191
195 TF_API
197
202 TF_API
203 void AppendError(TfError const &e);
204
210 TF_API
211 void PostError(TfEnum errorCode, const char* errorCodeString,
212 TfCallContext const &context,
213 const std::string& commentary, TfDiagnosticInfo info,
214 bool quiet);
215
221 TF_API
222 void PostError(const TfDiagnosticBase& diagnostic);
223
228 TF_API
229 void PostWarning(TfEnum warningCode, const char *warningCodeString,
230 TfCallContext const &context, std::string const &commentary,
231 TfDiagnosticInfo info, bool quiet) const;
232
237 TF_API
238 void PostWarning(const TfDiagnosticBase& diagnostic) const;
239
244 TF_API
245 void PostStatus(TfEnum statusCode, const char *statusCodeString,
246 TfCallContext const &context, std::string const &commentary,
247 TfDiagnosticInfo info, bool quiet) const;
248
253 TF_API
254 void PostStatus(const TfDiagnosticBase& diagnostic) const;
255
260 [[noreturn]]
261 TF_API
262 void PostFatal(TfCallContext const &context, TfEnum statusCode,
263 std::string const &msg) const;
264
267 bool HasActiveErrorMark() { return _errorMarkCounts.local() > 0; }
268
269#if !defined(doxygen)
270 //
271 // Public, but *only* meant to be used by the TF_ERROR() macro.
272 //
274 class ErrorHelper {
275 public:
276 ErrorHelper(TfCallContext const &context, TfEnum errorCode,
277 const char* errorCodeString)
278 : _context(context), _errorCode(errorCode),
279 _errorCodeString(errorCodeString)
280 {
281 }
282
283 TF_API
284 void Post(const char* fmt, ...) const
286
287 TF_API
288 void PostQuietly(const char* fmt, ...) const
290
291 TF_API
292 void Post(const std::string& msg) const;
293
294 TF_API
295 void PostWithInfo(
296 const std::string& msg,
297 TfDiagnosticInfo info = TfDiagnosticInfo()) const;
298
299 TF_API
300 void PostQuietly(const std::string& msg,
301 TfDiagnosticInfo info = TfDiagnosticInfo()) const;
302
303 private:
304 TfCallContext _context;
305 TfEnum _errorCode;
306 const char *_errorCodeString;
307 };
308
309 struct WarningHelper {
310 WarningHelper(TfCallContext const &context, TfEnum warningCode,
311 const char *warningCodeString)
312 : _context(context), _warningCode(warningCode),
313 _warningCodeString(warningCodeString)
314 {
315 }
316
317 TF_API
318 void Post(const char* fmt, ...) const
320
321 TF_API
322 void PostQuietly(const char* fmt, ...) const
324
325 TF_API
326 void Post(const std::string &str) const;
327
328 TF_API
329 void PostWithInfo(
330 const std::string& msg,
331 TfDiagnosticInfo info = TfDiagnosticInfo()) const;
332
333 TF_API
334 void PostQuietly(const std::string& msg) const;
335
336 private:
337 TfCallContext _context;
338 TfEnum _warningCode;
339 const char *_warningCodeString;
340 };
341
342 struct StatusHelper {
343 StatusHelper(TfCallContext const &context, TfEnum statusCode,
344 const char *statusCodeString)
345 : _context(context), _statusCode(statusCode),
346 _statusCodeString(statusCodeString)
347 {
348 }
349
350 TF_API
351 void Post(const char* fmt, ...) const
353
354 TF_API
355 void PostQuietly(const char* fmt, ...) const
357
358 TF_API
359 void Post(const std::string &str) const;
360
361 TF_API
362 void PostWithInfo(
363 const std::string& msg,
364 TfDiagnosticInfo info = TfDiagnosticInfo()) const;
365
366 TF_API
367 void PostQuietly(const std::string& msg) const;
368
369 private:
370 TfCallContext _context;
371 TfEnum _statusCode;
372 const char *_statusCodeString;
373 };
374
375 struct FatalHelper {
376 FatalHelper(TfCallContext const &context, TfEnum statusCode)
377 : _context(context),
378 _statusCode(statusCode)
379 {
380 }
381 [[noreturn]]
382 void Post(const std::string &str) const {
383 This::GetInstance().PostFatal(_context, _statusCode, str);
384 }
385 private:
386 TfCallContext _context;
387 TfEnum _statusCode;
388 };
389
390#endif
391
392private:
393
395 virtual ~TfDiagnosticMgr();
396 friend class TfSingleton<This>;
397
398 // Return an iterator to the first error with serial number >= mark, or the
399 // past-the-end iterator, if no such errors exist.
400 TF_API
401 ErrorIterator _GetErrorMarkBegin(size_t mark, size_t *nErrors);
402
403 // Invoked by ErrorMark ctor.
404 inline void _CreateErrorMark() { ++_errorMarkCounts.local(); }
405
406 // Invoked by ErrorMark dtor.
407 inline bool _DestroyErrorMark() { return --_errorMarkCounts.local() == 0; }
408
409 // Report an error, either via delegate or print to stderr, and issue a
410 // notice if this thread of execution is the main thread.
411 void _ReportError(const TfError &err);
412
413 // Splice the errors in src into this thread's local list. Also reassign
414 // serial numbers to all the spliced errors to ensure they work correctly
415 // with local error marks.
416 void _SpliceErrors(ErrorList &src);
417
418 // Helper to append pending error messages to the crash log.
419 void _AppendErrorsToLogText(ErrorIterator i);
420
421 // Helper to fully rebuild the crash log error text when errors are erased
422 // from the middle.
423 void _RebuildErrorLogText();
424
425 // Helper to actually publish log text into the Arch crash handler.
426 void _SetLogInfoForErrors(std::vector<std::string> const &logText) const;
427
428 // A guard used to protect reentrency when adding/removing
429 // delegates as well as posting errors/warnings/statuses
430 mutable tbb::enumerable_thread_specific<bool> _reentrantGuard;
431
432 // The registered delegates.
433 std::vector<Delegate*> _delegates;
434
435 mutable tbb::spin_rw_mutex _delegatesMutex;
436
437 // Global serial number for sorting.
438 std::atomic<size_t> _nextSerial;
439
440 // Thread-specific error list.
441 tbb::enumerable_thread_specific<ErrorList> _errorList;
442
443 // Thread-specific diagnostic log text for pending errors.
444 struct _LogText {
445 void AppendAndPublish(ErrorIterator i, ErrorIterator end);
446 void RebuildAndPublish(ErrorIterator i, ErrorIterator end);
447
448 std::pair<std::vector<std::string>,
449 std::vector<std::string>> texts;
450 bool parity = false;
451 private:
452 void _AppendAndPublishImpl(bool clear,
453 ErrorIterator i, ErrorIterator end);
454 };
455 tbb::enumerable_thread_specific<_LogText> _logText;
456
457 // Thread-specific error mark counts. Use a native key for best performance
458 // here.
459 tbb::enumerable_thread_specific<
460 size_t, tbb::cache_aligned_allocator<size_t>,
461 tbb::ets_key_per_instance> _errorMarkCounts;
462
463 bool _quiet;
464
465 friend class TfError;
466 friend class TfErrorTransport;
467 friend class TfErrorMark;
468};
469
470TF_API_TEMPLATE_CLASS(TfSingleton<TfDiagnosticMgr>);
471
472PXR_NAMESPACE_CLOSE_SCOPE
473
474#endif // PXR_BASE_TF_DIAGNOSTIC_MGR_H
Define function attributes.
#define ARCH_PRINTF_FUNCTION(_fmt, _firstArg)
Macro used to indicate a function takes a printf-like specification.
Definition: attributes.h:51
Functions for recording call locations.
Represents the base class of an object representing a diagnostic message.
One may set a delegate with the TfDiagnosticMgr which will be called to respond to errors and diagnos...
virtual void IssueStatus(TfStatus const &status)=0
Called when a TF_STATUS() is issued.
virtual void IssueError(TfError const &err)=0
Called when a TfError is posted.
TF_API void _UnhandledAbort() const
Abort the program, but avoid the session logging mechanism.
virtual void IssueWarning(TfWarning const &warning)=0
Called when a TF_WARNING() is issued.
virtual void IssueFatalError(TfCallContext const &context, std::string const &msg)=0
Called when a TF_FATAL_ERROR is issued (or a failed TF_AXIOM).
Singleton class through which all errors and diagnostics pass.
Definition: diagnosticMgr.h:71
TF_API void RemoveDelegate(Delegate *delegate)
Removes all delegates equal to delegate from the current delegates.
TF_API void PostError(const TfDiagnosticBase &diagnostic)
This method will create a TfError, append it to the error list, and pass it to all delegates.
TF_API void AddDelegate(Delegate *delegate)
Add the delegate delegate to the list of current delegates.
TF_API void SetQuiet(bool quiet)
Set whether errors, warnings and status messages should be printed out to the terminal.
TF_API void PostError(TfEnum errorCode, const char *errorCodeString, TfCallContext const &context, const std::string &commentary, TfDiagnosticInfo info, bool quiet)
This method will create a TfError, append it to the error list, and pass it to all delegates.
TF_API ErrorIterator EraseError(ErrorIterator i)
Remove error specified by iterator i.
static TF_API This & GetInstance()
Return the singleton instance.
TF_API void PostFatal(TfCallContext const &context, TfEnum statusCode, std::string const &msg) const
This method will issue a fatal error to all delegates.
ErrorIterator GetErrorEnd()
Return an iterator to the end of this thread's error list.
TF_API void PostWarning(TfEnum warningCode, const char *warningCodeString, TfCallContext const &context, std::string const &commentary, TfDiagnosticInfo info, bool quiet) const
This method will create a TfWarning and pass it to all delegates.
TF_API void PostStatus(const TfDiagnosticBase &diagnostic) const
This method will create a TfStatus and pass it to all delegates.
TF_API void AppendError(TfError const &e)
Append an error to the list of active errors.
TF_API ErrorIterator EraseRange(ErrorIterator first, ErrorIterator last)
Remove all the errors in [first, last) from this thread's error stream.
bool HasActiveErrorMark()
Return true if an instance of TfErrorMark exists in the current thread of execution,...
TF_API void PostWarning(const TfDiagnosticBase &diagnostic) const
This method will create a TfWarning and pass it to all delegates.
TF_API void PostStatus(TfEnum statusCode, const char *statusCodeString, TfCallContext const &context, std::string const &commentary, TfDiagnosticInfo info, bool quiet) const
This method will create a TfStatus and pass it to all delegates.
ErrorList::iterator ErrorIterator
Synonym for standard STL iterator to traverse the error list.
Definition: diagnosticMgr.h:96
static TF_API std::string FormatDiagnostic(const TfEnum &code, const TfCallContext &context, const std::string &msg, const TfDiagnosticInfo &info)
Return a human-readable diagnostic message.
ErrorIterator GetErrorBegin()
Return an iterator to the beginning of this thread's error list.
static TF_API std::string GetCodeName(const TfEnum &code)
Returns the name of the given diagnostic code.
An enum class that records both enum type and enum value.
Definition: enum.h:137
Represents an object that contains error information.
Definition: error.h:49
Class used to record the end of the error-list.
Definition: errorMark.h:65
A facility for transporting errors from thread to thread.
Manage a single instance of an object (see.
Definition: singleton.h:122
static T & GetInstance()
Return a reference to an object of type T, creating it if necessary.
Definition: singleton.h:137
Represents an object that contains information about a status message.
Definition: status.h:45
Represents an object that contains information about a warning.
Definition: warning.h:45
Enable a concrete base class for use with TfWeakPtr.
Definition: weakBase.h:141
Conditional debugging output class and macros.
Stripped down version of diagnostic.h that doesn't define std::string.
Define preprocessor function name macros.
#define TF_DEBUG_CODES(...)
Define debugging symbols.
Definition: debug.h:393
Define integral types.
STL namespace.
Manage a single instance of an object.
Definitions of basic string utilities in tf.
Provide facilities for error handling in script.
Pointer storage with deletion detection.