User Manual, Developers Guide and API Documentation

Backtrace.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002  * This file is part of openWNS (open Wireless Network Simulator)
00003  * _____________________________________________________________________________
00004  *
00005  * Copyright (C) 2004-2007
00006  * Chair of Communication Networks (ComNets)
00007  * Kopernikusstr. 16, D-52074 Aachen, Germany
00008  * phone: ++49-241-80-27910,
00009  * fax: ++49-241-80-22242
00010  * email: info@openwns.org
00011  * www: http://www.openwns.org
00012  * _____________________________________________________________________________
00013  *
00014  * openWNS is free software; you can redistribute it and/or modify it under the
00015  * terms of the GNU Lesser General Public License version 2 as published by the
00016  * Free Software Foundation;
00017  *
00018  * openWNS is distributed in the hope that it will be useful, but WITHOUT ANY
00019  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
00020  * A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00021  * details.
00022  *
00023  * You should have received a copy of the GNU Lesser General Public License
00024  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00025  *
00026  ******************************************************************************/
00027 
00028 #include <WNS/Backtrace.hpp>
00029 #include <WNS/demangle.hpp>
00030 #include <iomanip>
00031 #include <cmath>
00032 
00033 // to get the __GLIBC__ macro set (if glibc available)
00034 #include <features.h>
00035 
00036 #ifdef __GLIBC__
00037 #include <execinfo.h>
00038 #include <cstdlib>
00039 #endif // __GLIBC__
00040 
00041 #include <sstream>
00042 
00043 using namespace wns;
00044 
00045 Backtrace::Backtrace() :
00046     backtrace_()
00047 {
00048 }
00049 
00050 Backtrace::~Backtrace()
00051 {
00052     clear();
00053 }
00054 
00055 void
00056 Backtrace::snapshot()
00057 {
00058     clear();
00059 #ifdef __GLIBC__
00060     const int arraySize = 1000;
00061     void* array[arraySize];
00062     size_t size;
00063     char** strings;
00064 
00065     size = backtrace (array, arraySize);
00066     strings = backtrace_symbols (array, size);
00067 
00068     for (size_t ii = 0; ii < size; ++ii)
00069     {
00070         backtrace_.push_back(strings[ii]);
00071     }
00072 
00073     free (strings);
00074 #endif // __GLIBC__
00075 }
00076 
00077 void
00078 Backtrace::clear()
00079 {
00080     backtrace_.clear();
00081 }
00082 
00083 wns::Backtrace::FunctionCalls
00084 Backtrace::getFunctionCalls() const
00085 {
00086     FunctionCalls functionCalls;
00087 
00088     for(Lines::const_iterator itr = backtrace_.begin();
00089         itr != backtrace_.end();
00090         ++itr)
00091     {
00092         functionCalls.push_back(FunctionCall(*itr));
00093     }
00094 
00095     return functionCalls;
00096 }
00097 
00098 std::string
00099 Backtrace::doToString() const
00100 {
00101     // get function calls and stream reverse
00102     FunctionCalls functionCalls = getFunctionCalls();
00103     size_t stackSize = functionCalls.size();
00104     size_t frame = stackSize;
00105     int width = static_cast<int>(std::ceil(std::log10(stackSize)));
00106     std::stringstream tmp;
00107     tmp << "Backtrace (most recent call last, stack size: " << stackSize << "):\n";
00108     if (stackSize == 0)
00109     {
00110         tmp << "  No backtrace available.\n"
00111         << "  Backtrace is currently only available on systems with glibc, sorry.\n";
00112         return tmp.str();
00113     }
00114     // Marc Schinnenburg <marc@schinnenburg.com> 10.12.2007
00115     // The itr should be const_reverse_iterator, but gcc 3.4.4 cannot find the
00116     // operator==() or operator!=() for that :}
00117     for(FunctionCalls::reverse_iterator itr = functionCalls.rbegin();
00118         itr != functionCalls.rend();
00119         ++itr)
00120     {
00121         tmp << " " << std::setw(width) << frame << ")  " << itr->getName() << "\n";
00122         --frame;
00123     }
00124     return tmp.str();
00125 }
00126 
00127 
00128 
00129 Backtrace::FunctionCall::FunctionCall(std::string line) :
00130     origin_("unknown"),
00131     name_("unknown"),
00132     offset_("unknown"),
00133     returnAddress_("unknown")
00134 {
00135 
00136     // the line typically looks like this:
00137     // ./openwns(_ZN3wns3WNS13SignalHandler11catchSignalEi+0xfc) [0x8068870]
00138     size_t openBrace = line.find("(");
00139     size_t plus = line.find("+");
00140     size_t closeBrace = line.find(")");
00141     size_t openSquareBrace = line.find("[");
00142     size_t closeSquareBrace = line.find("]");
00143 
00144     if (openBrace != std::string::npos)
00145     {
00146         // the stuff in front of "(" is the origin
00147         origin_ = line.substr(0, openBrace);
00148 
00149         if (closeBrace != std::string::npos && plus != std::string::npos)
00150         {
00151             // the stuff from "(" to "+" is the function name
00152             {
00153                 std::string symbol = line.substr(openBrace+1, plus-openBrace-1);
00154                 name_ = wns::demangle(symbol);
00155             }
00156             // the stuff from "+" to ")" is the offset
00157             offset_ = line.substr(plus+1, closeBrace-plus-1);
00158         }
00159     }
00160 
00161     if (openSquareBrace != std::string::npos && closeSquareBrace != std::string::npos)
00162     {
00163         // between "[" and "]" we find the return address
00164         returnAddress_ = line.substr(openSquareBrace+1, closeSquareBrace-plus-1);
00165     }
00166 }
00167 
00168 std::string
00169 Backtrace::FunctionCall::getOrigin() const
00170 {
00171     return origin_;
00172 }
00173 
00174 std::string
00175 Backtrace::FunctionCall::getName() const
00176 {
00177     return name_;
00178 }
00179 
00180 std::string
00181 Backtrace::FunctionCall::getOffset() const
00182 {
00183     return offset_;
00184 }
00185 
00186 std::string
00187 Backtrace::FunctionCall::getReturnAddress() const
00188 {
00189     return returnAddress_;
00190 }

Generated on Wed Feb 8 03:31:38 2012 for openWNS by  doxygen 1.5.5