00001 #include <cstdio>
00002 #include <cstring>
00003 #include <cstdlib>
00004 #include <cstdio>
00005
00006 #include "AlcapExcept.h"
00007
00008
00009 #ifdef _GNU_SOURCE
00010 #include <execinfo.h>
00011 #endif
00012
00013 unsigned int Except::Base::gBacktraceSymbols = 5;
00014
00015 Except::Base::Base() {
00016 fTrace[0] = 0;
00017 fWhat[0] = 0;
00018 #ifdef _GNU_SOURCE
00019 if (gBacktraceSymbols>0) {
00020 const unsigned int bufferSize=100;
00021 if (gBacktraceSymbols>bufferSize) gBacktraceSymbols = bufferSize;
00022 void *buffer[bufferSize];
00023 unsigned int frames = bufferSize;
00024 if (gBacktraceSymbols<frames) frames = gBacktraceSymbols;
00025 int nFrames = backtrace(buffer,frames);
00026 char **symbols = backtrace_symbols(buffer,nFrames);
00027 if (symbols != NULL) {
00028 unsigned int len = 0;
00029 std::strcat(fTrace,"Backtrace:\n");
00030 for (int i = 0; i<nFrames; ++i) {
00031 std::string sym(symbols[i]);
00032 std::string lib;
00033 std::string::size_type s = sym.find_last_of('/');
00034 if (s != std::string::npos) sym = sym.substr(s+1);
00035 s = sym.find_first_of('(');
00036 if (s != std::string::npos) lib = sym.substr(0,s);
00037 sym = sym.substr(s+1);
00038 std::string::size_type t = sym.find_first_of(')');
00039 if (s != std::string::npos
00040 && t != std::string::npos) sym = sym.substr(0,t);
00041 else sym="";
00042 if (lib.empty() && sym.empty()) continue;
00043 len += lib.length();
00044 len += sym.length() + 6;
00045 if (2*len>sizeof(fTrace)) break;
00046 std::strcat(fTrace," --> ");
00047 if (!lib.empty()) std::strcat(fTrace,lib.c_str());
00048 if (!sym.empty()) {
00049 std::strcat(fTrace,": ");
00050 std::strcat(fTrace,sym.c_str());
00051 }
00052 std::strcat(fTrace,"\n");
00053 }
00054 std::free(symbols);
00055 }
00056 }
00057 #endif
00058 std::strcat(fWhat,"Except::Base");
00059 }
00060
00061 void Except::Base::AppendWhat(const char* child) {
00062 unsigned int wLen = std::strlen(fWhat);
00063 unsigned int cLen = std::strlen(child);
00064 if (wLen+cLen < sizeof(fWhat)-5) {
00065 std::strcat(fWhat,"::");
00066 std::strcat(fWhat,child);
00067 }
00068 }
00069
00070 void Except::Base::AppendWhat(const char* child, const char* message) {
00071 AppendWhat(child);
00072 unsigned int wLen = std::strlen(fWhat);
00073 unsigned int mLen = std::strlen(message);
00074 if (wLen+mLen < sizeof(fWhat)-9) {
00075 std::strcat(fWhat," \"");
00076 std::strcat(fWhat,message);
00077 std::strcat(fWhat,"\"");
00078 }
00079 }
00080
00081 void Except::Base::AppendWhat(const char* child, const char* file, int line) {
00082 AppendWhat (child);
00083 unsigned int wLen = std::strlen(fWhat);
00084 unsigned int fLen = std::strlen(file);
00085 if (fLen+wLen < sizeof(fWhat)-16) {
00086 char buf[16];
00087 buf[0]=0;
00088 snprintf(buf,16,":%d)", line);
00089 std::strcat(fWhat," (");
00090 std::strcat(fWhat,file);
00091 std::strcat(fWhat,buf);
00092 }
00093 }
00094