Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Helpers/Assert.cpp

    r506d2f r112b09  
    55 *      Author: crueger
    66 */
     7
     8#include "Helpers/MemDebug.hpp"
    79
    810#include "Helpers/Assert.hpp"
     
    4446}
    4547
     48using namespace Assert;
     49
    4650#ifndef NDEBUG
    4751
    48 #ifdef __GNUC__
    49 #include <cstdlib>
    50 #include <execinfo.h>
    51 #include <cxxabi.h>
    52 #endif
     52Action _my_assert::defaultAction = Ask;
     53std::vector<Assert::hook_t> _my_assert::hooks;
    5354
    54 Assert::Action Assert::_my_assert::defaultAction = Ask;
    55 std::vector<Assert::hook_t> Assert::_my_assert::hooks;
     55std::map<std::string,bool> _wrapper::ignores;
     56const char* _wrapper::message_ptr = "source pointer did not point to object of desired type";
     57const char* _wrapper::message_ref = "source reference did not contain object of desired type";
    5658
    57 std::map<std::string,bool> Assert::_wrapper::ignores;
    58 const char* Assert::_wrapper::message_ptr = "source pointer did not point to object of desired type";
    59 const char* Assert::_wrapper::message_ref = "source reference did not contain object of desired type";
    6059
    61 bool Assert::_my_assert::check(const char* condition,
    62                                const char* message,
    63                                const char* filename,
    64                                const int line,
    65                                bool& ignore)
     60bool _my_assert::check(const bool res,
     61                       const char* condition,
     62                       const char* message,
     63                       const char* filename,
     64                       const int line,
     65                       bool& ignore)
    6666{
    67   cout << "Assertion \"" << condition << "\" failed in file " << filename << " at line " << line << endl;
    68   cout << "Assertion Message: " << message << std::endl;
    69   while(true){
    70     char choice;
    71     if(defaultAction==Assert::Ask) {
    72 #ifdef __GNUC__
    73       cout << "Please choose: (a)bort, (t)hrow execption, show (b)actrace, (i)gnore, al(w)ays ignore" << endl;
    74 #else
    75       cout << "Please choose: (a)bort, (t)hrow execption, (i)gnore, al(w)ays ignore" << endl;
    76 #endif /* __GNUC__ */
    77       cin >> choice;
    78     }
    79     else{
    80       choice = ActionKeys[defaultAction];
    81     }
    82     switch(choice){
    83       case 'a':
    84         return true;
    85         break;
    86       case 't':
    87         throw AssertionFailure(condition,filename,line,message);
    88         break;
    89 #ifdef __GNUC__
    90       case 'b':
    91         Assert::_my_assert::backtrace(filename,line);
    92        break;
    93 #endif /* __GNUC__ */
    94       case 'w':
    95         ignore = true;
    96         // fallthrough
    97       case 'i':
    98         return false;
    99         break;
     67  if(!res){
     68    cout << "Assertion \"" << condition << "\" failed in file " << filename << " at line " << line << endl;
     69    cout << "Assertion Message: " << message << std::endl;
     70    while(true){
     71      char choice;
     72      if(defaultAction==Ask) {
     73        cout << "Please choose: (a)bort, (t)hrow execption, (i)gnore, al(w)ays ignore" << endl;
     74        cin >> choice;
     75      }
     76      else{
     77        choice = ActionKeys[defaultAction];
     78      }
     79      switch(choice){
     80        case 'a':
     81          return true;
     82          break;
     83        case 't':
     84          throw AssertionFailure(condition,filename,line,message);
     85          break;
     86        case 'w':
     87          ignore = true;
     88          // fallthrough
     89        case 'i':
     90          return false;
     91          break;
     92      }
    10093    }
    10194  }
     
    10396}
    10497
    105 #ifdef __GNUC__
    106 void Assert::_my_assert::backtrace(const char *file, int line){
    107   const size_t max_depth = 100;
    108   void* stack_addrs[max_depth];
    109   size_t stack_depth;
    110   char **stack_strings=0;
    111   const char *func_name=0;
    112   size_t sz = 64;
    113 
    114   // get the backtrace
    115   stack_depth   = ::backtrace(stack_addrs,max_depth);
    116   stack_strings = backtrace_symbols(stack_addrs, stack_depth);
    117   // used later for demangling
    118   // reserved here, so we can free it unconditionally
    119   char *dm_function = static_cast<char*>(malloc(sz));
    120   if(!dm_function){
    121     // malloc failed... we are out of luck
    122     cout << "cannot provide stack trace due to exhausted memory" << endl;
    123     return;
    124   }
    125 
    126   cout << "Backtrace from  " << file << "@" << line << ":" << endl;
    127 
    128   // i=2 because we don't want this function, nor the assertion handler
    129   for(unsigned int i=2;i<stack_depth-2;++i){
    130     // find the mangled function name
    131     char *begin = stack_strings[i];
    132     // function name starts with a (
    133     while(*begin && *begin!='(') ++begin;
    134     char *end=begin;
    135     while(*end && *end!='+') ++end;
    136 
    137     // see if we found our function name
    138     if(*begin && *end){
    139       *begin++ = 0;
    140       *end = 0;
    141       // use the C++ demangler
    142 
    143       int status;
    144       char *func_ret = abi::__cxa_demangle(begin, dm_function, &sz, &status);
    145       if(func_ret){
    146         // abi might have realloced...
    147         dm_function = func_ret;
    148         func_name = dm_function;
    149       }
    150       else{
    151         // demangling failed... get the function name without demangling
    152         func_name = begin;
    153       }
    154     }
    155     else{
    156       // function name not found... get the whole line
    157       func_name = stack_strings[i];
    158     }
    159     cout << func_name << endl;
    160   }
    161   free(dm_function);
    162   free(stack_strings); // malloc()ed by backtrace_symbols
    163 }
    164 #endif /* __GNUC__ */
    165 
    166 void Assert::_my_assert::doHooks(){
     98void _my_assert::doHooks(){
    16799  for(vector<hook_t>::reverse_iterator iter = hooks.rbegin(); iter!=hooks.rend(); ++iter ){
    168100    (*iter)();
     
    170102}
    171103
    172 void Assert::_my_assert::addHook(hook_t hook){
     104void _my_assert::addHook(hook_t hook){
    173105  hooks.push_back(hook);
    174106}
    175107
    176 void Assert::_my_assert::removeHook(Assert::hook_t hook){
     108void _my_assert::removeHook(Assert::hook_t hook){
    177109  for(vector<hook_t>::iterator iter = hooks.begin(); iter!=hooks.end();){
    178110    if((*iter)==hook){
     
    185117}
    186118
    187 void Assert::_my_assert::setDefault(Assert::Action action){
     119void _my_assert::setDefault(Assert::Action action){
    188120  defaultAction = action;
    189121}
    190 Assert::Action Assert::_my_assert::getDefault(){
     122Assert::Action _my_assert::getDefault(){
    191123  return defaultAction;
    192124}
    193 std::string Assert::_my_assert::printDefault(){
     125std::string _my_assert::printDefault(){
    194126  return ActionNames[defaultAction];
    195127}
Note: See TracChangeset for help on using the changeset viewer.