/** @class GATS_Exception @brief Embodies the GATS_Exception base class. @note The constructor of this class is protected meaning you can not create instances of this class directly but rather you must derive your exception objects from this class. @date $Date: 2007-01-10 11:06:55 -0500 (Wed, 10 Jan 2007) $ @version $Rev$ @author - Lance Deaver @copyright (©) Copyright 2006 by GATS Inc. 11864 Canon Blvd., Suite 101, Newport News, VA 23606 All Rights Reserved. No part of this software or publication may be reproduced, stored in a retrieval system, or transmitted, in any form or by any means, electronic, mechanical, photocopying, recording, or otherwise without the prior written permission of GATS Inc. @see GATS_Exception.h @todo Add an EXPORT macro so windows users can preface functions with the decspl when constructing DLL files. @bug None known $Id$ $Id$ */ #include "GATS_Exception.h" #include #include #ifdef __linux__ //Provides stack tracing options on linux platforms #include #endif /** * The GATS_Exception copy constructor. */ GATS_Exception::GATS_Exception(const GATS_Exception& e) throw() : std::exception(e), what_(e.what_ ), filename_(e.filename_), linenumber_(e.linenumber_) #ifdef __linux__ ,stack_(e.stack_) #endif { } /** * Destroy a GATS_Exception object. */ GATS_Exception::~GATS_Exception() throw() { } /** * This is the GATS_Exception class constructor. On a linux system this constructor * will store a stack trace that may be useful when debugging programs. Also this * constructor receives the source filename and line number and that also can be * useful when chasing a problem * * @parm[in] w A useful error message explaining the reason an exception was thrown. * @param[in] filename The source filename throwing the exception. Usually retrieved from the __FILE__ compiler macro. * @param[in] linenumber The line number in the source file that the exception was thrown. Usually retrieved from the __LINE__ macro. */ GATS_Exception::GATS_Exception(const char* w, const char* filename, const unsigned int linenumber) throw() : what_(w), filename_(filename), linenumber_(linenumber) { #ifdef __linux__ // Acquire the stack trace... void * array[25]; size_t entries = backtrace( array, sizeof( array ) / sizeof( void* ) ); char ** symbols = backtrace_symbols( array, entries ); if ( symbols == 0 ) { // Probable out of memory condition; we'll skip // over the full stack. entries = 0; } // Store it into our Vector. We are skipping the // top-most element, since this will be this // constructor, which is not particularly interesting. // We are also skipping the next line, because the // __FILE__ and __LINE__ have that location already. stack_.reserve( entries > 2 ? entries - 2 : 0 ); for ( size_t i = 2; i < entries; ++i ) { stack_.push_back( symbols[i] ); } // Free up the allocated memory. free( symbols ); #endif } /** * The GATS_Exception assignment operator */ GATS_Exception& GATS_Exception::operator=(const GATS_Exception& rhs) throw() { std::exception::operator=(rhs); what_ = rhs.what_; filename_ = rhs.filename_; linenumber_=rhs.linenumber_; #ifdef __linux__ stack_=rhs.stack_; #endif return *this; } /** * This class will return a string containing the exception message along with the * souce filename and linenumber where the exception occurred. On linux systems, a stack * trace will also be appended. */ std::string GATS_Exception::StackTrace() const throw() { std::stringstream st; st << what_ << std::endl; st << " at " << filename_ << ": " << linenumber_ << std::endl; #ifdef __linux__ for ( unsigned int i = 0, size = stack_.size(); i < size; ++i ) { st << " at " << stack_[i] << std::endl; } #endif return st.str(); } /** * This is a protected function that is declared virtual meaning it can be overloaded * in derived classes. It defines the format of the print message when * using the << operator for a class. * * @param[in] o A reference to std::ostream such as cout or a fstream. */ void GATS_Exception::PrintOn(std::ostream& o) const { o << what_ << '\n' << " at " << filename_ << ": " << linenumber_ << std::endl; } /** * A overloaded << std::stream operator that provides printing of the data elements * in the GATS_Exception class. */ std::ostream& operator<<( std::ostream& o, const GATS_Exception& e ) { e.PrintOn(o); return o; }