From a6f31e9167c75982bb5eaba96ec6ac1f70ee31fb Mon Sep 17 00:00:00 2001 From: Brad Kittenbrink Date: Fri, 8 Mar 2019 13:39:56 -0800 Subject: Fixed variadic macro usage in LL_ERRS_IF and LL_WARNS_IF and improved LLError::shouldLogToStderr() behavior under xcode. --- indra/llcommon/llerror.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'indra/llcommon/llerror.h') diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h index 0a78229555..9613911531 100644 --- a/indra/llcommon/llerror.h +++ b/indra/llcommon/llerror.h @@ -381,8 +381,13 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG; #define LL_WARNS(...) lllog(LLError::LEVEL_WARN, false, ##__VA_ARGS__) #define LL_ERRS(...) lllog(LLError::LEVEL_ERROR, false, ##__VA_ARGS__) // alternative to llassert_always that prints explanatory message -#define LL_WARNS_IF(exp, ...) if (exp) LL_WARNS(##__VA_ARGS__) << "(" #exp ")" -#define LL_ERRS_IF(exp, ...) if (exp) LL_ERRS(##__VA_ARGS__) << "(" #exp ")" +// note ## token paste operator hack used above will only work in gcc following +// a comma and is completely unnecessary in VS since the comma is automatically +// suppressed +// https://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html +// https://docs.microsoft.com/en-us/cpp/preprocessor/variadic-macros?view=vs-2015 +#define LL_WARNS_IF(exp, ...) if (exp) LL_WARNS(__VA_ARGS__) << "(" #exp ")" +#define LL_ERRS_IF(exp, ...) if (exp) LL_ERRS(__VA_ARGS__) << "(" #exp ")" // Only print the log message once (good for warnings or infos that would otherwise // spam the log file over and over, such as tighter loops). -- cgit v1.2.3 From cc9bdbcf19354c323c3f090949636267f54851e0 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Mon, 18 Nov 2019 18:43:01 -0500 Subject: DRTVWR-476: Introduce LLStacktrace, a token to stream stack trace. LLStacktrace has no behavior except when you stream an instance to a std::ostream. Then it reports the current traceback at that point to the ostream. This bit of indirection is intended to avoid the boost/stacktrace.hpp header from being included everywhere. --- indra/llcommon/llerror.h | 54 +++++++++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 24 deletions(-) (limited to 'indra/llcommon/llerror.h') diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h index 9613911531..48162eca9e 100644 --- a/indra/llcommon/llerror.h +++ b/indra/llcommon/llerror.h @@ -262,30 +262,36 @@ namespace LLError class LL_COMMON_API NoClassInfo { }; // used to indicate no class info known for logging - //LLCallStacks keeps track of call stacks and output the call stacks to log file - //when LLAppViewer::handleViewerCrash() is triggered. - // - //Note: to be simple, efficient and necessary to keep track of correct call stacks, - //LLCallStacks is designed not to be thread-safe. - //so try not to use it in multiple parallel threads at same time. - //Used in a single thread at a time is fine. - class LL_COMMON_API LLCallStacks - { - private: - static char** sBuffer ; - static S32 sIndex ; - - static void allocateStackBuffer(); - static void freeStackBuffer(); - - public: - static void push(const char* function, const int line) ; - static std::ostringstream* insert(const char* function, const int line) ; - static void print() ; - static void clear() ; - static void end(std::ostringstream* _out) ; - static void cleanup(); - }; + //LLCallStacks keeps track of call stacks and output the call stacks to log file + //when LLAppViewer::handleViewerCrash() is triggered. + // + //Note: to be simple, efficient and necessary to keep track of correct call stacks, + //LLCallStacks is designed not to be thread-safe. + //so try not to use it in multiple parallel threads at same time. + //Used in a single thread at a time is fine. + class LL_COMMON_API LLCallStacks + { + private: + static char** sBuffer ; + static S32 sIndex ; + + static void allocateStackBuffer(); + static void freeStackBuffer(); + + public: + static void push(const char* function, const int line) ; + static std::ostringstream* insert(const char* function, const int line) ; + static void print() ; + static void clear() ; + static void end(std::ostringstream* _out) ; + static void cleanup(); + }; + + // class which, when streamed, inserts the current stack trace + struct LLStacktrace + { + friend std::ostream& operator<<(std::ostream& out, const LLStacktrace&); + }; } //this is cheaper than llcallstacks if no need to output other variables to call stacks. -- cgit v1.2.3 From dc07509f296661cf7a4d4bceb88a1a897757de98 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 3 Apr 2020 10:38:53 -0400 Subject: DRTVWR-476: Cherry-pick debug aids from commit 77b0c53 (fiber-mutex) --- indra/llcommon/llerror.h | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'indra/llcommon/llerror.h') diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h index 48162eca9e..3cdd051ac7 100644 --- a/indra/llcommon/llerror.h +++ b/indra/llcommon/llerror.h @@ -191,9 +191,9 @@ namespace LLError The classes CallSite and Log are used by the logging macros below. They are not intended for general use. */ - + struct CallSite; - + class LL_COMMON_API Log { public: @@ -202,8 +202,17 @@ namespace LLError static void flush(std::ostringstream* out, char* message); static void flush(std::ostringstream*, const CallSite&); static std::string demangle(const char* mangled); + /// classname() + template + static std::string classname() { return demangle(typeid(T).name()); } + /// classname(some_pointer) + template + static std::string classname(const T* ptr) { return demangle(typeid(*ptr).name()); } + /// classname(some_reference) + template + static std::string classname(const T& obj) { return demangle(typeid(obj).name()); } }; - + struct LL_COMMON_API CallSite { // Represents a specific place in the code where a message is logged -- cgit v1.2.3 From 6e5242f0a4e8a2e9cd9f21e89fae4870d1acceca Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 14 May 2020 08:50:39 -0400 Subject: DRTVWR-476: Fix LLError::Log::classname(T*) template function. First, the signature classname(const T*) was wrong: that function could only accept a pointer to const T. The expression classname(someptr) where someptr was a pointer to non-const SomeType displayed "SomeType*" because it could only match classname(const T&), where T was SomeType*. classname(T* const) is what we should have written, meaning "const pointer to T" rather than "pointer to const T." Second, the previous implementation failed to handle the case in which the pointer was nullptr. --- indra/llcommon/llerror.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llcommon/llerror.h') diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h index 3cdd051ac7..ffaa464d77 100644 --- a/indra/llcommon/llerror.h +++ b/indra/llcommon/llerror.h @@ -207,7 +207,7 @@ namespace LLError static std::string classname() { return demangle(typeid(T).name()); } /// classname(some_pointer) template - static std::string classname(const T* ptr) { return demangle(typeid(*ptr).name()); } + static std::string classname(T* const ptr) { return ptr? demangle(typeid(*ptr).name()) : "nullptr"; } /// classname(some_reference) template static std::string classname(const T& obj) { return demangle(typeid(obj).name()); } -- cgit v1.2.3