diff options
Diffstat (limited to 'indra/llcommon/llerror.h')
| -rw-r--r-- | indra/llcommon/llerror.h | 416 | 
1 files changed, 208 insertions, 208 deletions
diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h index a70b5cef3a..7353a36c5f 100644 --- a/indra/llcommon/llerror.h +++ b/indra/llcommon/llerror.h @@ -79,16 +79,16 @@ const int LL_ERR_NOERR = 0;  #define llassert_always_msg(func, msg) if (LL_UNLIKELY(!(func))) LL_ERRS() << "ASSERT (" << msg << ")" << LL_ENDL -#define llassert_always(func)	llassert_always_msg(func, #func) +#define llassert_always(func)   llassert_always_msg(func, #func)  #ifdef SHOW_ASSERT -#define llassert(func)			llassert_always_msg(func, #func) -#define llassert_msg(func, msg)	llassert_always_msg(func, msg) -#define llverify(func)			llassert_always_msg(func, #func) +#define llassert(func)          llassert_always_msg(func, #func) +#define llassert_msg(func, msg) llassert_always_msg(func, msg) +#define llverify(func)          llassert_always_msg(func, #func)  #else  #define llassert(func)  #define llassert_msg(func, msg) -#define llverify(func)			do {if (func) {}} while(0) +#define llverify(func)          do {if (func) {}} while(0)  #endif  #ifdef LL_WINDOWS @@ -107,58 +107,58 @@ const int LL_ERR_NOERR = 0;  /** Error Logging Facility -	Information for most users: +    Information for most users: -	Code can log messages with constructions like this: +    Code can log messages with constructions like this: -		LL_INFOS("StringTag") << "request to fizzbip agent " << agent_id -			<< " denied due to timeout" << LL_ENDL; +        LL_INFOS("StringTag") << "request to fizzbip agent " << agent_id +            << " denied due to timeout" << LL_ENDL; -	Messages can be logged to one of four increasing levels of concern, -	using one of four "streams": +    Messages can be logged to one of four increasing levels of concern, +    using one of four "streams": -		LL_DEBUGS("StringTag")	- debug messages that are normally suppressed -		LL_INFOS("StringTag")	- informational messages that are normal shown -		LL_WARNS("StringTag")	- warning messages that signal a problem -		LL_ERRS("StringTag")	- error messages that are major, unrecoverable failures +        LL_DEBUGS("StringTag")  - debug messages that are normally suppressed +        LL_INFOS("StringTag")   - informational messages that are normal shown +        LL_WARNS("StringTag")   - warning messages that signal a problem +        LL_ERRS("StringTag")    - error messages that are major, unrecoverable failures -	The later (LL_ERRS("StringTag")) automatically crashes the process after the message -	is logged. +    The later (LL_ERRS("StringTag")) automatically crashes the process after the message +    is logged. -	Note that these "streams" are actually #define magic.  Rules for use: -		* they cannot be used as normal streams, only to start a message -		* messages written to them MUST be terminated with LL_ENDL -		* between the opening and closing, the << operator is indeed -		  writing onto a std::ostream, so all conversions and stream -		  formating are available +    Note that these "streams" are actually #define magic.  Rules for use: +        * they cannot be used as normal streams, only to start a message +        * messages written to them MUST be terminated with LL_ENDL +        * between the opening and closing, the << operator is indeed +          writing onto a std::ostream, so all conversions and stream +          formating are available -	These messages are automatically logged with function name, and (if enabled) -	file and line of the message.  (Note: Existing messages that already include -	the function name don't get name printed twice.) +    These messages are automatically logged with function name, and (if enabled) +    file and line of the message.  (Note: Existing messages that already include +    the function name don't get name printed twice.) -	If you have a class, adding LOG_CLASS line to the declaration will cause -	all messages emitted from member functions (normal and static) to be tagged -	with the proper class name as well as the function name: +    If you have a class, adding LOG_CLASS line to the declaration will cause +    all messages emitted from member functions (normal and static) to be tagged +    with the proper class name as well as the function name: -		class LLFoo -		{ -			LOG_CLASS(LLFoo); -		public: -			... -		}; +        class LLFoo +        { +            LOG_CLASS(LLFoo); +        public: +            ... +        }; -		void LLFoo::doSomething(int i) -		{ -			if (i > 100) -			{ -				LL_WARNS("FooBarTag") << "called with a big value for i: " << i << LL_ENDL; -			} -			... -		} +        void LLFoo::doSomething(int i) +        { +            if (i > 100) +            { +                LL_WARNS("FooBarTag") << "called with a big value for i: " << i << LL_ENDL; +            } +            ... +        } -	will result in messages like: +    will result in messages like: -		WARN #FooBarTag# llcommon/llfoo(100) LLFoo::doSomething : called with a big value for i: 283 +        WARN #FooBarTag# llcommon/llfoo(100) LLFoo::doSomething : called with a big value for i: 283      the syntax is:          <timestamp> SPACE <level> SPACE <tags> SPACE <location> SPACE <function> SPACE COLON SPACE <message> @@ -169,117 +169,117 @@ const int LL_ERR_NOERR = 0;      The tags must be a single word (may not contain a space); if more than one tag is specified,      they are all surrounded by '#' ( #FooTag#BarTag# ). -	Which messages are logged and which are suppressed can be controlled at run -	time from the configuration file. The default configuration is in newview/app_settings/logcontrol.xml +    Which messages are logged and which are suppressed can be controlled at run +    time from the configuration file. The default configuration is in newview/app_settings/logcontrol.xml      A copy of that file named logcontrol-dev.xml can be made in the users personal settings      directory; that will override the installed default file.  See the logcontrol.xml      file or http://wiki.secondlife.com/wiki/Logging_System_Overview for configuration details. -	Lastly, logging is now very efficient in both compiled code and execution -	when skipped.  There is no need to wrap messages, even debugging ones, in -	#ifdef _DEBUG constructs.  LL_DEBUGS("StringTag") messages are compiled into all builds, -	even release.  Which means you can use them to help debug even when deployed -	to a real grid. +    Lastly, logging is now very efficient in both compiled code and execution +    when skipped.  There is no need to wrap messages, even debugging ones, in +    #ifdef _DEBUG constructs.  LL_DEBUGS("StringTag") messages are compiled into all builds, +    even release.  Which means you can use them to help debug even when deployed +    to a real grid.  */  namespace LLError  { -	enum ELevel -	{ -		LEVEL_ALL = 0, -			// used to indicate that all messages should be logged - -		LEVEL_DEBUG = 0, -		LEVEL_INFO = 1, -		LEVEL_WARN = 2, -		LEVEL_ERROR = 3,	// used to be called FATAL - -		LEVEL_NONE = 4 -			// not really a level -			// used to indicate that no messages should be logged -	}; -	// If you change ELevel, please update llvlog() macro below. - -	/*	Macro support -		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: -		static bool shouldLog(CallSite&); -		static void flush(const std::ostringstream&, const CallSite&); -		static std::string demangle(const char* mangled); -		/// classname<TYPE>() -		template <typename T> -		static std::string classname()             { return demangle(typeid(T).name()); } -		/// classname(some_pointer) -		template <typename T> -		static std::string classname(T* const ptr) { return ptr? demangle(typeid(*ptr).name()) : "nullptr"; } -		/// classname(some_reference) -		template <typename T> -		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 -		// This is public because it is used by the macros below.  It is not -		// intended for public use. -		CallSite(ELevel level, -				const char* file, -				int line, -				const std::type_info& class_info, -				const char* function, -				bool print_once, -				const char** tags, -				size_t tag_count); - -		~CallSite(); +    enum ELevel +    { +        LEVEL_ALL = 0, +            // used to indicate that all messages should be logged + +        LEVEL_DEBUG = 0, +        LEVEL_INFO = 1, +        LEVEL_WARN = 2, +        LEVEL_ERROR = 3,    // used to be called FATAL + +        LEVEL_NONE = 4 +            // not really a level +            // used to indicate that no messages should be logged +    }; +    // If you change ELevel, please update llvlog() macro below. + +    /*  Macro support +        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: +        static bool shouldLog(CallSite&); +        static void flush(const std::ostringstream&, const CallSite&); +        static std::string demangle(const char* mangled); +        /// classname<TYPE>() +        template <typename T> +        static std::string classname()             { return demangle(typeid(T).name()); } +        /// classname(some_pointer) +        template <typename T> +        static std::string classname(T* const ptr) { return ptr? demangle(typeid(*ptr).name()) : "nullptr"; } +        /// classname(some_reference) +        template <typename T> +        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 +        // This is public because it is used by the macros below.  It is not +        // intended for public use. +        CallSite(ELevel level, +                const char* file, +                int line, +                const std::type_info& class_info, +                const char* function, +                bool print_once, +                const char** tags, +                size_t tag_count); + +        ~CallSite();  #ifdef LL_LIBRARY_INCLUDE -		bool shouldLog(); +        bool shouldLog();  #else // LL_LIBRARY_INCLUDE -		bool shouldLog() -		{ -			return mCached -					? mShouldLog -					: Log::shouldLog(*this); -		} -			// this member function needs to be in-line for efficiency +        bool shouldLog() +        { +            return mCached +                    ? mShouldLog +                    : Log::shouldLog(*this); +        } +            // this member function needs to be in-line for efficiency  #endif // LL_LIBRARY_INCLUDE -		void invalidate(); - -		// these describe the call site and never change -		const ELevel			mLevel; -		const char* const		mFile; -		const int				mLine; -		const std::type_info&   mClassInfo; -		const char* const		mFunction; -		const char**			mTags; -		size_t					mTagCount; -		const bool				mPrintOnce; -		const char*				mLevelString; -		std::string				mLocationString, -								mFunctionString, -								mTagString; -		bool					mCached, -								mShouldLog; - -		friend class Log; -	}; +        void invalidate(); + +        // these describe the call site and never change +        const ELevel            mLevel; +        const char* const       mFile; +        const int               mLine; +        const std::type_info&   mClassInfo; +        const char* const       mFunction; +        const char**            mTags; +        size_t                  mTagCount; +        const bool              mPrintOnce; +        const char*             mLevelString; +        std::string             mLocationString, +                                mFunctionString, +                                mTagString; +        bool                    mCached, +                                mShouldLog; + +        friend class Log; +    }; -	class End { }; -	inline std::ostream& operator<<(std::ostream& s, const End&) -		{ return s; } -		// used to indicate the end of a message +    class End { }; +    inline std::ostream& operator<<(std::ostream& s, const End&) +        { return s; } +        // used to indicate the end of a message -	class LL_COMMON_API NoClassInfo { }; -		// used to indicate no class info known for logging +    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      // @@ -335,30 +335,30 @@ namespace LLError  #define LL_PUSH_CALLSTACKS() LLError::LLCallStacks::push(__FUNCTION__, __LINE__)  #define llcallstacks                                                    \ -	{                                                                   \ -		std::ostringstream _out;                                        \ -		LLError::LLCallStacks::insert(_out, __FUNCTION__, __LINE__) ;   \ -		_out +    {                                                                   \ +        std::ostringstream _out;                                        \ +        LLError::LLCallStacks::insert(_out, __FUNCTION__, __LINE__) ;   \ +        _out  #define llcallstacksendl                   \ -		LLError::End();                    \ -		LLError::LLCallStacks::end(_out) ; \ -	} +        LLError::End();                    \ +        LLError::LLCallStacks::end(_out) ; \ +    }  #define LL_CLEAR_CALLSTACKS() LLError::LLCallStacks::clear()  #define LL_PRINT_CALLSTACKS() LLError::LLCallStacks::print()  /* -	Class type information for logging +    Class type information for logging   */ -#define LOG_CLASS(s)	typedef s _LL_CLASS_TO_LOG -	// Declares class to tag logged messages with. -	// See top of file for example of how to use this +#define LOG_CLASS(s)    typedef s _LL_CLASS_TO_LOG +    // Declares class to tag logged messages with. +    // See top of file for example of how to use this  typedef LLError::NoClassInfo _LL_CLASS_TO_LOG; -	// Outside a class declaration, or in class without LOG_CLASS(), this -	// typedef causes the messages to not be associated with any class. +    // Outside a class declaration, or in class without LOG_CLASS(), this +    // typedef causes the messages to not be associated with any class.  /////////////////////////////////  // Error Logging Macros @@ -381,34 +381,34 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG;  #define lllog(level, once, ...)                                         \      do {                                                                \          LL_PROFILE_ZONE_NAMED("lllog");                                 \ -		const char* tags[] = {"", ##__VA_ARGS__};                       \ -		static LLError::CallSite _site(lllog_site_args_(level, once, tags)); \ -		lllog_test_() +        const char* tags[] = {"", ##__VA_ARGS__};                       \ +        static LLError::CallSite _site(lllog_site_args_(level, once, tags)); \ +        lllog_test_()  #define lllog_test_()                           \ -		if (LL_UNLIKELY(_site.shouldLog()))     \ -		{                                       \ -			std::ostringstream _out;            \ -			_out +        if (LL_UNLIKELY(_site.shouldLog()))     \ +        {                                       \ +            std::ostringstream _out;            \ +            _out  #define lllog_site_args_(level, once, tags)                 \ -	level, __FILE__, __LINE__, typeid(_LL_CLASS_TO_LOG),    \ -	__FUNCTION__, once, &tags[1], LL_ARRAY_SIZE(tags)-1 +    level, __FILE__, __LINE__, typeid(_LL_CLASS_TO_LOG),    \ +    __FUNCTION__, once, &tags[1], LL_ARRAY_SIZE(tags)-1  //Use this construct if you need to do computation in the middle of a  //message:  // -//	LL_INFOS("AgentGesture") << "the agent " << agend_id; -//	switch (f) -//	{ -//		case FOP_SHRUGS:	LL_CONT << "shrugs";				break; -//		case FOP_TAPS:		LL_CONT << "points at " << who;	break; -//		case FOP_SAYS:		LL_CONT << "says " << message;	break; -//	} -//	LL_CONT << " for " << t << " seconds" << LL_ENDL; +//  LL_INFOS("AgentGesture") << "the agent " << agend_id; +//  switch (f) +//  { +//      case FOP_SHRUGS:    LL_CONT << "shrugs";                break; +//      case FOP_TAPS:      LL_CONT << "points at " << who; break; +//      case FOP_SAYS:      LL_CONT << "says " << message;  break; +//  } +//  LL_CONT << " for " << t << " seconds" << LL_ENDL;  //  //Such computation is done iff the message will be logged. -#define LL_CONT	_out +#define LL_CONT _out  #define LL_NEWLINE '\n' @@ -437,24 +437,24 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG;  // NEW Macros for debugging, allow the passing of a string tag  // Pass comma separated list of tags (currently only supports up to 0, 1, or 2) -#define LL_DEBUGS(...)	lllog(LLError::LEVEL_DEBUG, false, ##__VA_ARGS__) -#define LL_INFOS(...)	lllog(LLError::LEVEL_INFO, false, ##__VA_ARGS__) -#define LL_WARNS(...)	lllog(LLError::LEVEL_WARN, false, ##__VA_ARGS__) -#define LL_ERRS(...)	lllog(LLError::LEVEL_ERROR, false, ##__VA_ARGS__) +#define LL_DEBUGS(...)  lllog(LLError::LEVEL_DEBUG, false, ##__VA_ARGS__) +#define LL_INFOS(...)   lllog(LLError::LEVEL_INFO, false, ##__VA_ARGS__) +#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  // 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 ")" +#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). -#define LL_DEBUGS_ONCE(...)	lllog(LLError::LEVEL_DEBUG, true, ##__VA_ARGS__) -#define LL_INFOS_ONCE(...)	lllog(LLError::LEVEL_INFO, true, ##__VA_ARGS__) -#define LL_WARNS_ONCE(...)	lllog(LLError::LEVEL_WARN, true, ##__VA_ARGS__) +#define LL_DEBUGS_ONCE(...) lllog(LLError::LEVEL_DEBUG, true, ##__VA_ARGS__) +#define LL_INFOS_ONCE(...)  lllog(LLError::LEVEL_INFO, true, ##__VA_ARGS__) +#define LL_WARNS_ONCE(...)  lllog(LLError::LEVEL_WARN, true, ##__VA_ARGS__)  // Use this if you need to pass LLError::ELevel as a variable.  #define LL_VLOGS(level, ...)      llvlog(level, false, ##__VA_ARGS__) @@ -470,33 +470,33 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG;  // instance for the passed level value.  // Compare implementation to lllog() above.  #define llvlog(level, once, ...)                                        \ -	do {                                                                \ -		const char* tags[] = {"", ##__VA_ARGS__};                       \ -		/* Need a static CallSite instance per expected ELevel value. */ \ -		/* Since we intend to index this array with the ELevel, */      \ -		/* _sites[0] should be ELevel(0), and so on -- avoid using */   \ -		/* ELevel symbolic names when initializing -- except for */     \ -		/* the last entry, which handles anything beyond the end. */    \ -		/* (Commented ELevel value names are from 2016-09-01.) */       \ -		/* Passing an ELevel past the end of this array is itself */    \ -		/* a fatal error, so ensure the last is LEVEL_ERROR. */         \ -		static LLError::CallSite _sites[] =                             \ -		{                                                               \ -			/* LEVEL_DEBUG */                                           \ -			LLError::CallSite(lllog_site_args_(LLError::ELevel(0), once, tags)), \ -			/* LEVEL_INFO */                                            \ -			LLError::CallSite(lllog_site_args_(LLError::ELevel(1), once, tags)), \ -			/* LEVEL_WARN */                                            \ -			LLError::CallSite(lllog_site_args_(LLError::ELevel(2), once, tags)), \ -			/* LEVEL_ERROR */                                           \ -			LLError::CallSite(lllog_site_args_(LLError::LEVEL_ERROR, once, tags)) \ -		};                                                              \ -		/* Clamp the passed 'level' to at most last entry */            \ -		std::size_t which((std::size_t(level) >= LL_ARRAY_SIZE(_sites)) ? \ -						  (LL_ARRAY_SIZE(_sites) - 1) : std::size_t(level)); \ -		/* selected CallSite *must* be named _site for LL_ENDL */       \ -		LLError::CallSite& _site(_sites[which]);                        \ -		lllog_test_() +    do {                                                                \ +        const char* tags[] = {"", ##__VA_ARGS__};                       \ +        /* Need a static CallSite instance per expected ELevel value. */ \ +        /* Since we intend to index this array with the ELevel, */      \ +        /* _sites[0] should be ELevel(0), and so on -- avoid using */   \ +        /* ELevel symbolic names when initializing -- except for */     \ +        /* the last entry, which handles anything beyond the end. */    \ +        /* (Commented ELevel value names are from 2016-09-01.) */       \ +        /* Passing an ELevel past the end of this array is itself */    \ +        /* a fatal error, so ensure the last is LEVEL_ERROR. */         \ +        static LLError::CallSite _sites[] =                             \ +        {                                                               \ +            /* LEVEL_DEBUG */                                           \ +            LLError::CallSite(lllog_site_args_(LLError::ELevel(0), once, tags)), \ +            /* LEVEL_INFO */                                            \ +            LLError::CallSite(lllog_site_args_(LLError::ELevel(1), once, tags)), \ +            /* LEVEL_WARN */                                            \ +            LLError::CallSite(lllog_site_args_(LLError::ELevel(2), once, tags)), \ +            /* LEVEL_ERROR */                                           \ +            LLError::CallSite(lllog_site_args_(LLError::LEVEL_ERROR, once, tags)) \ +        };                                                              \ +        /* Clamp the passed 'level' to at most last entry */            \ +        std::size_t which((std::size_t(level) >= LL_ARRAY_SIZE(_sites)) ? \ +                          (LL_ARRAY_SIZE(_sites) - 1) : std::size_t(level)); \ +        /* selected CallSite *must* be named _site for LL_ENDL */       \ +        LLError::CallSite& _site(_sites[which]);                        \ +        lllog_test_()  /*  // Check at run-time whether logging is enabled, without generating output.  | 
