Exceptions: optional callback for exception throws.

This is to allow recording an error+stacktrace whenever an exception
is thrown, since that’s the point when the stack is interesting.
This commit is contained in:
Automatic Release Builder 2020-09-22 15:26:33 +01:00
parent 3753c62783
commit 733efd08dd
2 changed files with 64 additions and 74 deletions

View File

@ -13,6 +13,8 @@
#include <simgear/misc/sg_path.hxx> #include <simgear/misc/sg_path.hxx>
static ThrowCallback static_callback;
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// Implementation of sg_location class. // Implementation of sg_location class.
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
@ -49,19 +51,7 @@ sg_location::sg_location (const char* path, int line, int column)
setPath(path); setPath(path);
} }
sg_location::~sg_location () void sg_location::setPath(const char *path) {
{
}
const char*
sg_location::getPath () const
{
return _path;
}
void
sg_location::setPath (const char* path)
{
if (path) { if (path) {
strncpy(_path, path, max_path); strncpy(_path, path, max_path);
_path[max_path -1] = '\0'; _path[max_path -1] = '\0';
@ -70,17 +60,9 @@ sg_location::setPath (const char* path)
} }
} }
int const char *sg_location::getPath() const { return _path; }
sg_location::getLine () const
{
return _line;
}
void int sg_location::getLine() const { return _line; }
sg_location::setLine (int line)
{
_line = line;
}
int int
sg_location::getColumn () const sg_location::getColumn () const
@ -88,11 +70,6 @@ sg_location::getColumn () const
return _column; return _column;
} }
void
sg_location::setColumn (int column)
{
_column = column;
}
int int
sg_location::getByte () const sg_location::getByte () const
@ -100,12 +77,6 @@ sg_location::getByte () const
return _byte; return _byte;
} }
void
sg_location::setByte (int byte)
{
_byte = byte;
}
std::string std::string
sg_location::asString () const sg_location::asString () const
{ {
@ -126,8 +97,8 @@ sg_location::asString () const
return out.str(); return out.str();
} }
bool sg_location::isValid() const { return strlen(_path) > 0; }
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// Implementation of sg_throwable class. // Implementation of sg_throwable class.
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
@ -138,10 +109,14 @@ sg_throwable::sg_throwable ()
_origin[0] = '\0'; _origin[0] = '\0';
} }
sg_throwable::sg_throwable (const char* message, const char* origin) sg_throwable::sg_throwable(const char *message, const char *origin,
{ const sg_location &loc) {
setMessage(message); setMessage(message);
setOrigin(origin); setOrigin(origin);
if (static_callback) {
static_callback(_message, _origin, loc);
}
} }
sg_throwable::~sg_throwable () sg_throwable::~sg_throwable ()
@ -228,16 +203,13 @@ sg_exception::sg_exception ()
{ {
} }
sg_exception::sg_exception (const char* message, const char* origin) sg_exception::sg_exception(const char *message, const char *origin,
: sg_throwable(message, origin) const sg_location &loc)
{ : sg_throwable(message, origin, loc) {}
}
sg_exception::sg_exception(const std::string &message, sg_exception::sg_exception(const std::string &message,
const std::string& origin ) const std::string &origin, const sg_location &loc)
: sg_throwable(message.c_str(), origin.c_str()) : sg_throwable(message.c_str(), origin.c_str(), loc) {}
{
}
sg_exception::~sg_exception () sg_exception::~sg_exception ()
{ {
@ -260,10 +232,7 @@ sg_io_exception::sg_io_exception (const char* message, const char* origin)
sg_io_exception::sg_io_exception(const char *message, sg_io_exception::sg_io_exception(const char *message,
const sg_location &location, const sg_location &location,
const char *origin) const char *origin)
: sg_exception(message, origin), : sg_exception(message, origin, location), _location(location) {}
_location(location)
{
}
sg_io_exception::sg_io_exception( const std::string& message, sg_io_exception::sg_io_exception( const std::string& message,
const std::string& origin ) const std::string& origin )
@ -274,10 +243,7 @@ sg_io_exception::sg_io_exception( const std::string& message,
sg_io_exception::sg_io_exception(const std::string &message, sg_io_exception::sg_io_exception(const std::string &message,
const sg_location &location, const sg_location &location,
const std::string &origin) const std::string &origin)
: sg_exception(message, origin), : sg_exception(message, origin, location), _location(location) {}
_location(location)
{
}
sg_io_exception::~sg_io_exception () sg_io_exception::~sg_io_exception ()
{ {
@ -382,4 +348,9 @@ sg_range_exception::sg_range_exception(const std::string& message,
sg_range_exception::~sg_range_exception () sg_range_exception::~sg_range_exception ()
{ {
} }
////////////////////////////////////////////////////////////////////////
void setThrowCallback(ThrowCallback cb) { static_callback = cb; }
// end of exception.cxx // end of exception.cxx

View File

@ -11,6 +11,7 @@
#define __SIMGEAR_MISC_EXCEPTION_HXX 1 #define __SIMGEAR_MISC_EXCEPTION_HXX 1
#include <exception> #include <exception>
#include <functional>
#include <simgear/compiler.h> #include <simgear/compiler.h>
#include <string> #include <string>
@ -31,17 +32,20 @@ public:
sg_location(const std::string& path, int line = -1, int column = -1); sg_location(const std::string& path, int line = -1, int column = -1);
sg_location(const SGPath& path, int line = -1, int column = -1); sg_location(const SGPath& path, int line = -1, int column = -1);
explicit sg_location(const char* path, int line = -1, int column = -1); explicit sg_location(const char* path, int line = -1, int column = -1);
virtual ~sg_location();
virtual const char* getPath() const; ~sg_location() = default;
virtual void setPath (const char* path);
virtual int getLine () const; const char *getPath() const;
virtual void setLine (int line); int getLine() const;
virtual int getColumn () const; int getColumn() const;
virtual void setColumn (int column); int getByte() const;
virtual int getByte () const;
virtual void setByte (int byte); std::string asString() const;
virtual std::string asString () const; bool isValid() const;
private: private:
void setPath(const char *p);
char _path[max_path]; char _path[max_path];
int _line; int _line;
int _column; int _column;
@ -57,7 +61,9 @@ class sg_throwable : public std::exception
public: public:
enum {MAX_TEXT_LEN = 1024}; enum {MAX_TEXT_LEN = 1024};
sg_throwable (); sg_throwable ();
sg_throwable (const char* message, const char* origin = 0); sg_throwable(const char *message, const char *origin = 0,
const sg_location &loc = {});
virtual ~sg_throwable (); virtual ~sg_throwable ();
virtual const char* getMessage () const; virtual const char* getMessage () const;
virtual const std::string getFormattedMessage () const; virtual const std::string getFormattedMessage () const;
@ -86,7 +92,7 @@ class sg_error : public sg_throwable
public: public:
sg_error (); sg_error ();
sg_error (const char* message, const char* origin = 0); sg_error (const char* message, const char* origin = 0);
sg_error (const std::string& message, const std::string& origin = ""); sg_error(const std::string &message, const std::string &origin = {});
virtual ~sg_error (); virtual ~sg_error ();
}; };
@ -109,8 +115,10 @@ class sg_exception : public sg_throwable
{ {
public: public:
sg_exception (); sg_exception ();
sg_exception (const char* message, const char* origin = 0); sg_exception(const char *message, const char *origin = 0,
sg_exception (const std::string& message, const std::string& = ""); const sg_location &loc = {});
sg_exception(const std::string &message, const std::string & = {},
const sg_location &loc = {});
virtual ~sg_exception (); virtual ~sg_exception ();
}; };
@ -193,6 +201,17 @@ public:
virtual ~sg_range_exception (); virtual ~sg_range_exception ();
}; };
using ThrowCallback = std::function<void(
const char *message, const char *origin, const sg_location &loc)>;
/**
* @brief Specify a callback to be invoked when an exception is created.
*
* This is used to capture a stack-trace for our crash/error reporting system,
* if a callback is defined
*/
void setThrowCallback(ThrowCallback cb);
#endif #endif
// end of exception.hxx // end of exception.hxx