|
Rcpp Version 0.9.10
|
00001 // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*- 00002 // 00003 // debugging.cpp: R/C++ interface class library -- debugging helpers 00004 // 00005 // Copyright (C) 2010 - 2011 Dirk Eddelbuettel and Romain Francois 00006 // 00007 // This file is part of Rcpp. 00008 // 00009 // Rcpp is free software: you can redistribute it and/or modify it 00010 // under the terms of the GNU General Public License as published by 00011 // the Free Software Foundation, either version 2 of the License, or 00012 // (at your option) any later version. 00013 // 00014 // Rcpp is distributed in the hope that it will be useful, but 00015 // WITHOUT ANY WARRANTY; without even the implied warranty of 00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 // GNU General Public License for more details. 00018 // 00019 // You should have received a copy of the GNU General Public License 00020 // along with Rcpp. If not, see <http://www.gnu.org/licenses/>. 00021 00022 #include <Rcpp.h> 00023 00024 #if defined(__GNUC__) 00025 #if defined(WIN32) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) 00026 // Simpler version for Windows and *BSD 00027 SEXP stack_trace( const char* file, int line ){ 00028 Rcpp::List trace = Rcpp::List::create( 00029 Rcpp::Named( "file" ) = file, 00030 Rcpp::Named( "line" ) = line, 00031 Rcpp::Named( "stack" ) = "C++ stack not available on this system" ) ; 00032 trace.attr("class") = "Rcpp_stack_trace" ; 00033 return trace ; 00034 } 00035 #else // ! (defined(WIN32) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) 00036 #include <execinfo.h> 00037 #include <cxxabi.h> 00038 00039 static std::string demangler_one( const char* input){ 00040 static std::string buffer ; 00041 buffer = input ; 00042 buffer.resize( buffer.find_last_of( '+' ) - 1 ) ; 00043 buffer.erase( 00044 buffer.begin(), 00045 buffer.begin() + buffer.find_last_of( ' ' ) + 1) ; 00046 return demangle( buffer) ; 00047 } 00048 00049 /* inspired from http://tombarta.wordpress.com/2008/08/01/c-stack-traces-with-gcc/ */ 00050 SEXP stack_trace( const char *file, int line) { 00051 const size_t max_depth = 100; 00052 size_t stack_depth; 00053 void *stack_addrs[max_depth]; 00054 char **stack_strings; 00055 00056 stack_depth = backtrace(stack_addrs, max_depth); 00057 stack_strings = backtrace_symbols(stack_addrs, stack_depth); 00058 00059 std::string current_line ; 00060 00061 Rcpp::CharacterVector res( stack_depth - 1) ; 00062 std::transform( 00063 stack_strings + 1, stack_strings + stack_depth, 00064 res.begin(), 00065 demangler_one 00066 ) ; 00067 free(stack_strings); // malloc()ed by backtrace_symbols 00068 00069 Rcpp::List trace = Rcpp::List::create( 00070 Rcpp::Named( "file" ) = file, 00071 Rcpp::Named( "line" ) = line, 00072 Rcpp::Named( "stack" ) = res ) ; 00073 trace.attr("class") = "Rcpp_stack_trace" ; 00074 return trace ; 00075 } 00076 #endif 00077 #else /* !defined( __GNUC__ ) */ 00078 SEXP stack_trace( const char *file, int line) { 00079 return R_NilValue ; 00080 } 00081 #endif