00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00035 #include "OW_config.h"
00036 #include "OW_StackTrace.hpp"
00037 
00038 #ifdef OW_WIN32
00039 #include <iostream>  
00040 namespace OW_NAMESPACE
00041 {
00042 using std::cerr;
00043 using std::endl;
00044 void StackTrace::printStackTrace()
00045 {
00046    cerr << "StackTrace::printStackTrace not implemented yet" << endl;
00047 }
00048 }
00049 #else
00050 
00051 #include "OW_Exec.hpp"
00052 #include "OW_UnnamedPipe.hpp"
00053 #include "OW_Format.hpp"
00054 #include "OW_Array.hpp"
00055 #include <fstream>
00056 #include <iostream>  
00057 
00058 #if defined(OW_HAVE_BACKTRACE)
00059 #include <execinfo.h>
00060 #endif
00061 
00062 #if defined(OW_HAVE_CXXABI_H)
00063 #include <cxxabi.h>
00064 #endif
00065 
00066 #ifdef OW_HAVE_UNISTD_H
00067 extern "C"
00068 {
00069 #include <unistd.h> 
00070 }
00071 #endif
00072 
00073 namespace OW_NAMESPACE
00074 {
00075 
00076 using std::ifstream;
00077 using std::ofstream;
00078 using std::flush;
00079 
00080 #ifndef OW_DEFAULT_GDB_PATH
00081 #define OW_DEFAULT_GDB_PATH "/usr/bin/gdb"
00082 #endif
00083 
00084 
00085 void StackTrace::printStackTrace()
00086 {
00087    if (getenv("OW_STACKTRACE"))
00088    {
00089       
00090       
00091       
00092 #ifdef OW_HAVE_BACKTRACE
00093       void *array[200];
00094       
00095       size_t size = backtrace (array, 200);
00096       char **strings = backtrace_symbols (array, size);
00097       
00098       String bt;
00099       
00100       size_t i;
00101       for (i = 0; i < size; i++)
00102       {
00103 #if defined(OW_HAVE_CXXABI_H)
00104          bt += strings[i];
00105          int status;
00106          
00107          char* firstparen = ::strchr(strings[i], '(');
00108          char* lastparen = ::strchr(strings[i], '+');
00109          if (firstparen != 0 && lastparen != 0 && firstparen < lastparen)
00110          {
00111             bt += ": ";
00112             *lastparen = '\0';
00113             char* realname = abi::__cxa_demangle(firstparen+1, 0, 0, &status);
00114             bt += realname;
00115             free(realname);
00116          }
00117 #else
00118          bt += strings[i];
00119 #endif
00120          bt += "\n";
00121       }
00122       
00123       free (strings);
00124       
00125       std::cerr << bt << std::endl;
00126 #else
00127       ifstream file(OW_DEFAULT_GDB_PATH);
00128       if (file)
00129       {
00130          file.close();
00131          String scriptName("/tmp/owgdb-");
00132          String outputName("/tmp/owgdbout-");
00133          
00134          outputName += String(UInt32(::getpid()));
00135          scriptName += String(UInt32(::getpid())) + ".sh";
00136          String exeName("/proc/");
00137          exeName += String(UInt32(::getpid())) + "/exe";
00138          
00139          ofstream scriptFile(scriptName.c_str(), std::ios::out);
00140          scriptFile << "#!/bin/sh\n"
00141             << "gdb " << exeName << " " << ::getpid() << " << EOS > " << outputName << " 2>&1\n"
00142 
00143             << "bt\n"
00144             << "detach\n"
00145             << "q\n"
00146             << "EOS\n" << flush;
00147          scriptFile.close();
00148          Array<String> command;
00149          command.push_back( "/bin/sh" );
00150          command.push_back( scriptName );
00151          Exec::safeSystem(command);
00152          ifstream outputFile(outputName.c_str(), std::ios::in);
00153          String output;
00154          while (outputFile)
00155          {
00156             output += String::getLine(outputFile) + "\n";
00157          }
00158          outputFile.close();
00159          unlink(outputName.c_str());
00160          unlink(scriptName.c_str());
00161          std::cerr << output << std::endl;
00162       }
00163 #endif
00164    }
00165 }
00166 
00167 } 
00168 
00169 #endif   // ifdef OW_WIN32