AGX Dynamics 2.41.3.0
Loading...
Searching...
No Matches
debug.h
Go to the documentation of this file.
1/*
2Copyright 2007-2025. Algoryx Simulation AB.
3
4All AGX source code, intellectual property, documentation, sample code,
5tutorials, scene files and technical white papers, are copyrighted, proprietary
6and confidential material of Algoryx Simulation AB. You may not download, read,
7store, distribute, publish, copy or otherwise disseminate, use or expose this
8material unless having a written signed agreement with Algoryx Simulation AB, or having been
9advised so by Algoryx Simulation AB for a time limited evaluation, or having purchased a
10valid commercial license from Algoryx Simulation AB.
11
12Algoryx Simulation AB disclaims all responsibilities for loss or damage caused
13from using this software, unless otherwise stated in written agreements with
14Algoryx Simulation AB.
15*/
16
17#ifndef AGX_DEBUG_H
18#define AGX_DEBUG_H
19
20#include <cassert>
21#include <cstdlib>
22#include <stdexcept> // for std::runtime_error
23#include <cstdarg>
24#include <cstdio>
25#include <string>
26#include <agx/agxCore_export.h>
27
28
29#if defined(__GNUC__) || defined (__clang__)
30 #define AGX_NO_RETURN __attribute__((__noreturn__))
31#else
32 #define AGX_NO_RETURN
33#endif
34
35
36namespace agx
37{
39
40 AGXCORE_EXPORT std::string buildErrorString(const char *baseFormat, std::string msgFormat, ...);
41
42 AGXCORE_EXPORT const char *cStr(const char *str);
43 AGXCORE_EXPORT const char *cStr(const std::string& str);
44
45 AGXCORE_EXPORT void log_throw(const std::string& where, const char* what);
46
49
50 typedef std::runtime_error Error;
51}
52
53
54
55// Macro for defining a portable way of getting a nice function string including namespace::classname::method
56#ifdef _MSC_VER
57#define AGX_FUNCTION __FUNCTION__ // Won't include signature, i.e. will have trouble showing differences between overloaded functions
58//#define AGX_FUNCTION __FUNCSIG__ // Verbose signature - closer to __PRETTY_FUNCTION__
59#else
60#define AGX_FUNCTION __PRETTY_FUNCTION__
61#endif
62
63
64#define AGX_WHERE_AM_I agx::buildErrorString("[%s:%u (%s)]", "", __FILE__, __LINE__, AGX_FUNCTION)
65
66/*
67The 'Throw' macro: works like 'throw', but logs the message as well as file, line and function.
68*/
69
70#if 0
71// No need to use this path - the overhead of Throw is small, and exceptions (per definition) are rare
72#define agxThrow throw
73#else
74
76namespace agx_internal
77{
78 /*
79 template<typename E>
80 const char* decodeException(const E& e) { return e.what(); }
81 template<>
82 inline const char* decodeException(const char* const & e) { return e; }
83 */
84 inline const char* decodeException(const std::exception& e) { return e.what(); }
85 inline const char* decodeException(const char* e) { return e; } // Don't Throw these!
86 inline const char* decodeException(const std::string& e) { return e.c_str(); } // Don't Throw these!
87
88 class ExceptionDescriber
89 {
90 public:
91 ExceptionDescriber(const std::string& where)
92 : m_where(where) {}
93
94 template<typename E>
95 const E& operator%(const E& e) const
96 {
97 agx::log_throw(m_where, decodeException(e));
98 return e;
99 }
100
101 private:
102 std::string m_where;
103 };
104}
106
107
108// Acts like a normal Throw but logs where the exception was thrown from
109#define agxThrow throw agx_internal::ExceptionDescriber(AGX_WHERE_AM_I) %
110#endif // Throw or no Throw
111
112
113#undef __assert
114
115#if !defined(AGX_DEBUG) && !defined(NDEBUG)
116#define AGX_DEBUG
117#endif
118
119#ifdef _MSC_VER
120 // 0,0 "hack" needed for visual studio. Produces warnings with other compilers..
121 #define AGX_MACRO(x) do {x} while(0,0)
122 #define agx_snprintf _snprintf_s
123 #define agx_fprintf fprintf_s
124#else
125 #define AGX_MACRO(x) do {x} while(0)
126 #define agx_snprintf snprintf
127 #define agx_fprintf fprintf
128#endif
129
130// Verify state in both DEBUG and RELEASE build
131#define agxVerify(expr) AGX_MACRO(if (!(expr)) {fprintf(stderr, "%s\n", agx::buildErrorString("[%s:%u] agxVerify failed: `%s'", "", __FILE__, __LINE__, #expr).c_str()); agx::abort();})
132#define agxVerify1(expr, msg) AGX_MACRO(if (!(expr)) {fprintf(stderr, "%s\n", agx::buildErrorString("[%s:%u] agxVerify failed: `%s', ", "%s", __FILE__, __LINE__, #expr, agx::cStr(msg)).c_str()); agx::abort();})
133#define agxVerifyN(expr, format, ...) AGX_MACRO(if (!(expr)) {fprintf(stderr, "%s\n", agx::buildErrorString("[%s:%u] agxVerify failed: `%s', ", format, __FILE__, __LINE__, #expr, ##__VA_ARGS__).c_str()); agx::abort();})
134
135#define agxVerifyThrow(expr) AGX_MACRO(if (!(expr)) {std::string errorMessage = agx::buildErrorString("[%s:%u] agxVerify failed: `%s'", "", __FILE__, __LINE__, #expr); agxThrow agx::Error(errorMessage);})
136#define agxVerifyThrow1(expr, msg) AGX_MACRO(if (!(expr)) {std::string errorMessage = agx::buildErrorString("[%s:%u] agxVerify failed: `%s', ", "%s", __FILE__, __LINE__, #expr, agx::cStr(msg)); agxThrow agx::Error(errorMessage);})
137#define agxVerifyThrowN(expr, format, ...) AGX_MACRO(if (!(expr)) {std::string errorMessage = agx::buildErrorString("[%s:%u] agxVerify failed: `%s', ", format, __FILE__, __LINE__, #expr, ##__VA_ARGS__); agxThrow agx::Error(errorMessage);})
138
139
140
141#ifdef AGX_DEBUG
142#define agxAssertVoid() AGX_MACRO( {fprintf(stderr, "%s\n", agx::buildErrorString("[%s:%u] agxAssert failed: `%s'", "", __FILE__, __LINE__).c_str()); agx::abort();})
143#define agxAssert(expr) AGX_MACRO(if (!(expr)) {fprintf(stderr, "%s\n", agx::buildErrorString("[%s:%u] agxAssert failed: `%s'", "", __FILE__, __LINE__, #expr).c_str()); agx::abort();})
144#define agxAssert1(expr, msg ) AGX_MACRO(if (!(expr)) {fprintf(stderr, "%s\n", agx::buildErrorString("[%s:%u] agxAssert failed: `%s', ", "%s", __FILE__, __LINE__, #expr, agx::cStr(msg)).c_str()); agx::abort();})
145#define agxAssertN(expr, format, ... ) AGX_MACRO(if (!(expr)) {fprintf(stderr, "%s\n", agx::buildErrorString("[%s:%u] agxAssert failed: `%s', ", format, __FILE__, __LINE__, #expr, ##__VA_ARGS__).c_str()); agx::abort();})
146
147// Will always execute expr, but will only evaluate if AGX_DEBUG is set
148#define agxDebugVerify(expr) agxAssert(expr)
149#define agxDebugVerify1(expr, msg ) agxAssert1(expr, msg)
150#define agxDebugVerifyN(expr, format, ... ) agxAssertN(expr, format, __VA_ARGS__)
151#else
152#define agxAssertVoid() ((void)0)
153#define agxAssert(e) ((void)0)
154#define agxAssert1(e, msg) ((void)0)
155#define agxAssertN(e, format, ...) ((void)0)
156
157// Will always execute expr, but will only evaluate if AGX_DEBUG is set
158#define agxDebugVerify(expr) ((void)(expr))
159#define agxDebugVerify1( expr, msg ) ((void)(expr))
160#define agxDebugVerifyN( expr, format, ... ) ((void)(expr))
161
162#endif
163
164#define agxAbort( ) AGX_MACRO(fprintf(stderr, "%s\n", agx::buildErrorString("[%s:%u] agxAbort", "", __FILE__, __LINE__ ).c_str()); agx::abort();)
165#define agxAbort1(msg) AGX_MACRO(fprintf(stderr, "%s\n", agx::buildErrorString("[%s:%u] agxAbort: ", "%s", __FILE__, __LINE__, agx::cStr(msg)).c_str()); agx::abort();)
166#define agxAbortN(format, ... ) AGX_MACRO(fprintf(stderr, "%s\n", agx::buildErrorString("[%s:%u] agxAbort: ", format, __FILE__, __LINE__, ##__VA_ARGS__).c_str()); agx::abort();)
167
168
169#ifdef __GNUC__
170#define AGX_ASM_COMMENT(X) asm("#" X)
171#else
172#define AGX_ASM_COMMENT(X)
173#endif
174
175
176
177#endif /* _AGX_DEBUG_H_ */
#define AGXCORE_EXPORT
#define AGX_NO_RETURN
Definition: debug.h:32
#define DOXYGEN_END_INTERNAL_BLOCK()
Definition: macros.h:89
#define DOXYGEN_START_INTERNAL_BLOCK()
Definition: macros.h:88
The agx namespace contains the dynamics/math part of the AGX Dynamics API.
AGXCORE_EXPORT std::string buildErrorString(const char *baseFormat, std::string msgFormat,...)
AGXCORE_EXPORT void log_throw(const std::string &where, const char *what)
AGXCORE_EXPORT int setExceptionNotifyLevel(int level)
AGXCORE_EXPORT void abort() AGX_NO_RETURN
std::runtime_error Error
Definition: debug.h:50
AGXCORE_EXPORT const char * cStr(const char *str)
AGXCORE_EXPORT int getExceptionNotifyLevel()
STL namespace.