Files
pvData/src/misc/epicsException.cpp
2014-03-28 10:20:24 -05:00

92 lines
2.0 KiB
C++

/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mes
*/
#include <sstream>
#include <cstdio>
#include <cstring>
#define epicsExportSharedSymbols
#include <pv/epicsException.h>
namespace epics{ namespace pvData {
void
ExceptionMixin::print(FILE *fp) const
{
fprintf(fp, "On line %d of %s\n",m_line,m_file);
#if defined(EXCEPT_USE_BACKTRACE)
if(m_depth>0) {
fflush(fp); // must flush before using raw handle
backtrace_symbols_fd(m_stack, m_depth, fileno(fp));
fprintf(fp, "To translate run 'addr2line -e execname 0xXXXXXXX ...'\n"
" Note: Must be compiled with debug symbols\n");
}
#endif
}
std::string
ExceptionMixin::show() const
{
std::ostringstream out;
out<<"On line "<<m_line<<" of "<<m_file<<"\n";
#if defined(EXCEPT_USE_BACKTRACE)
if (m_depth>0) {
char **symbols=backtrace_symbols(m_stack, m_depth);
for(int i=0; i<m_depth; i++) {
out<<symbols[i]<<"\n";
}
free(symbols);
}
#endif
return out.str();
}
const char*
BaseException::what() const throw()
{
try{
if (base_msg.size()==0) {
const char *base=std::logic_error::what();
std::string out, stack;
const ExceptionMixin *info=dynamic_cast<const ExceptionMixin*>(this);
if(info) {
stack=info->show();
}
out.reserve(strlen(base)+1+stack.size()+1);
out+=base;
out+="\n";
if(info) {
out+=stack;
out+="\n";
}
base_msg.swap(out);
}
return base_msg.c_str();
} catch(std::bad_alloc&) {
return "BaseException::what - Insufficient memory to construct message";
} catch(...) {
return "BaseException::what - Unknown error when constructing message";
}
}
}}