Changeset 2727 for box


Ignore:
Timestamp:
31/08/2010 14:59:29 (18 months ago)
Author:
chris
Message:

Fix demangled logging of backtraces on OSX by using dladdr to get function
names rather than trying to parse the results of backtrace_strings().

Location:
box/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • box/trunk/configure.ac

    r2719 r2727  
    153153 
    154154AC_SEARCH_LIBS([dlsym], ["dl"]) 
     155AC_CHECK_FUNCS([dlsym dladdr]) 
    155156 
    156157### Checks for typedefs, structures, and compiler characteristics. 
     
    264265 
    265266## Find out how to do file locking 
    266 AC_CHECK_FUNCS([flock]) 
     267AC_CHECK_FUNCS([flock fcntl]) 
    267268AC_CHECK_DECLS([O_EXLOCK],,, [[#include <fcntl.h>]]) 
    268269AC_CHECK_DECLS([F_SETLK],,, [[#include <fcntl.h>]]) 
     
    400401 
    401402# Write summary of important info 
    402 cat <<EOC 
     403cat | tee config.log.features <<EOC 
    403404A summary of the build configuration is below. Box Backup will function 
    404405without these features, but will work better where they are present. Refer 
     
    410411Readline:            $have_libreadline 
    411412Extended attributes: $ac_cv_header_sys_xattr_h 
    412 EOC | tee config.log.features 
     413EOC 
    413414 
    414415 
  • box/trunk/lib/common/Utils.cpp

    r2551 r2727  
    2525#endif 
    2626 
     27#ifdef HAVE_DLFCN_H 
     28        #include <dlfcn.h> 
     29#endif 
     30 
    2731#include "Utils.h" 
    2832#include "CommonException.h" 
     
    7478 
    7579#ifdef SHOW_BACKTRACE_ON_EXCEPTION 
     80static std::string demangle(const std::string& mangled_name) 
     81{ 
     82        #ifdef HAVE_CXXABI_H 
     83        int status; 
     84         
     85#include "MemLeakFindOff.h" 
     86        char* result = abi::__cxa_demangle(mangled_name.c_str(), 
     87                NULL, NULL, &status); 
     88#include "MemLeakFindOn.h" 
     89 
     90        if (result == NULL) 
     91        { 
     92                if (status == 0) 
     93                { 
     94                        BOX_WARNING("Demangle failed but no error: " << 
     95                                mangled_name); 
     96                } 
     97                else if (status == -1) 
     98                { 
     99                        BOX_WARNING("Demangle failed with " 
     100                                "memory allocation error: " << 
     101                                mangled_name); 
     102                } 
     103                else if (status == -2) 
     104                { 
     105                        // Probably non-C++ name, don't demangle 
     106                        /* 
     107                        BOX_WARNING("Demangle failed with " 
     108                                "with invalid name: " << 
     109                                mangled_name); 
     110                        */ 
     111                } 
     112                else if (status == -3) 
     113                { 
     114                        BOX_WARNING("Demangle failed with " 
     115                                "with invalid argument: " << 
     116                                mangled_name); 
     117                } 
     118                else 
     119                { 
     120                        BOX_WARNING("Demangle failed with " 
     121                                "with unknown error " << status << 
     122                                ": " << mangled_name); 
     123                } 
     124 
     125                return std::string(mangled_name); 
     126        } 
     127        else 
     128        { 
     129                std::string output = result; 
     130#include "MemLeakFindOff.h" 
     131                std::free(result); 
     132#include "MemLeakFindOn.h" 
     133                return output; 
     134        } 
     135        #else // !HAVE_CXXABI_H 
     136        return mangled_name; 
     137        #endif // HAVE_CXXABI_H 
     138} 
     139 
    76140void DumpStackBacktrace() 
    77141{ 
    78142        void  *array[10]; 
    79         size_t size = backtrace (array, 10); 
    80         char **strings = backtrace_symbols (array, size); 
    81  
     143        size_t size = backtrace(array, 10); 
    82144        BOX_TRACE("Obtained " << size << " stack frames."); 
    83145 
    84146        for(size_t i = 0; i < size; i++) 
    85147        { 
    86                 // Demangling code copied from  
    87                 // cctbx_sources/boost_adaptbx/meta_ext.cpp, BSD license 
    88                  
    89                 std::string mangled_frame = strings[i]; 
    90                 std::string output_frame  = strings[i]; // default 
    91  
    92                 #ifdef HAVE_CXXABI_H 
    93                 int start = mangled_frame.find('('); 
    94                 int end   = mangled_frame.find('+', start); 
    95                 std::string mangled_func = mangled_frame.substr(start + 1, 
    96                         end - start - 1); 
    97  
    98                 int status; 
    99                  
    100 #include "MemLeakFindOff.h" 
    101                 char* result = abi::__cxa_demangle(mangled_func.c_str(), 
    102                         NULL, NULL, &status); 
    103 #include "MemLeakFindOn.h" 
    104  
    105                 if (result == NULL) 
    106                 { 
    107                         if (status == 0) 
     148                std::ostringstream output; 
     149                output << "Stack frame " << i << ": "; 
     150 
     151                #ifdef HAVE_DLADDR 
     152                        Dl_info info; 
     153                        int result = dladdr(array[i], &info); 
     154 
     155                        if(result == 0) 
    108156                        { 
    109                                 BOX_WARNING("Demangle failed but no error: " << 
    110                                         mangled_func); 
     157                                BOX_LOG_SYS_WARNING("Failed to resolve " 
     158                                        "backtrace address " << array[i]); 
     159                                output << "unresolved address " << array[i]; 
    111160                        } 
    112                         else if (status == -1) 
     161                        else if(info.dli_sname == NULL) 
    113162                        { 
    114                                 BOX_WARNING("Demangle failed with " 
    115                                         "memory allocation error: " << 
    116                                         mangled_func); 
    117                         } 
    118                         else if (status == -2) 
    119                         { 
    120                                 // Probably non-C++ name, don't demangle 
    121                                 /* 
    122                                 BOX_WARNING("Demangle failed with " 
    123                                         "with invalid name: " << 
    124                                         mangled_func); 
    125                                 */ 
    126                         } 
    127                         else if (status == -3) 
    128                         { 
    129                                 BOX_WARNING("Demangle failed with " 
    130                                         "with invalid argument: " << 
    131                                         mangled_func); 
     163                                output << "unknown address " << array[i]; 
    132164                        } 
    133165                        else 
    134166                        { 
    135                                 BOX_WARNING("Demangle failed with " 
    136                                         "with unknown error " << status << 
    137                                         ": " << mangled_func); 
     167                                uint64_t diff = (uint64_t) array[i]; 
     168                                diff -= (uint64_t) info.dli_saddr; 
     169                                output << demangle(info.dli_sname) << "+" << 
     170                                        (void *)diff; 
    138171                        } 
    139                 } 
    140                 else 
    141                 { 
    142                         output_frame = mangled_frame.substr(0, start + 1) + 
    143                                 result + mangled_frame.substr(end); 
    144 #include "MemLeakFindOff.h" 
    145                         std::free(result); 
    146 #include "MemLeakFindOn.h" 
    147                 } 
    148                 #endif // HAVE_CXXABI_H 
    149  
    150                 BOX_TRACE("Stack frame " << i << ": " << output_frame); 
    151         } 
    152  
    153 #include "MemLeakFindOff.h" 
    154         std::free (strings); 
    155 #include "MemLeakFindOn.h" 
    156 } 
    157 #endif 
     172                #else 
     173                        output << "address " << array[i]; 
     174                #endif // HAVE_DLADDR 
     175 
     176                BOX_TRACE(output.str()); 
     177        } 
     178} 
     179#endif // SHOW_BACKTRACE_ON_EXCEPTION 
    158180 
    159181 
Note: See TracChangeset for help on using the changeset viewer.