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