Skip to content

@wmanley /econtext.cpp
Last active

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Code sketch of a mechanism for attaching additional context to exceptions
#include "econtext.h"
__thread std::vector<ExceptionContextItem> currentContext;
typedef void (*cxa_throw_type)(void *, void *, void (*) (void *));
static cxa_throw_type orig_cxa_throw = 0;
static void load_orig_throw_code()
{
orig_cxa_throw = (cxa_throw_type) dlsym(RTLD_NEXT, "__cxa_throw");
}
extern "C"
void __cxa_throw (void *thrown_exception, void *pvtinfo, void (*dest)(void *)) {
if (!orig_cxa_throw)
load_orig_throw_code();
currentContext.clear();
orig_cxa_throw(thrown_exception, pvtinfo, dest);
}
#ifndef _ECONTEXT_HPP
#define _ECONTEXT_HPP
#define EXCEPTION_CONTEXT("row", x) \
scoped_exception_context<typeof(x)> ("row", &x);
template<typename T>
struct scoped_exception_context
{
public:
scoped_exception_context(const char* name, T* val) {
}
~scoped_exception_context() {
if (std::uncaught_exception()) {
currentContext.push_back(name, boost::lexical_cast<std::string>(val));
}
}
private:
const char* name;
T* val;
};
struct ExceptionContextItem {
const char * name;
std::string value;
};
__thread std::vector<ExceptionContextItem> currentContext;
#endif // _ECONTEXT_HPP
try {
size_t row = 0, col = 0;
EXCEPTION_CONTEXT("row", row);
EXCEPTION_CONTEXT("col", col);
for (row = 0; row < row_count; row++)
for (col = 0; col < col_count; col++) {
EXCEPTION_CONTEXT("contents", data[row][col])
if (!validate(data[row][col]))
throw validation_failed();
}
}
catch (validation_failed&)
{
dialog("Loading simulation failed because cell " + context["row"] + ", " + context["col"]
+ " of " + context["filename"] + " contains '" + context["contents"] + "' when it"
"should contain a number");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.