summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
authorDwayne Boone <dwayne@zeroc.com>2009-05-07 09:44:25 -0230
committerDwayne Boone <dwayne@zeroc.com>2009-05-07 09:44:25 -0230
commit2d0d9ef78501a0d3c9b6ab77bd31afa845db7cd3 (patch)
treeda8bb8159c737559c48989869a23e280e7cb38bd /cpp
parentBug 3624 - desupport HP (diff)
downloadice-2d0d9ef78501a0d3c9b6ab77bd31afa845db7cd3.tar.bz2
ice-2d0d9ef78501a0d3c9b6ab77bd31afa845db7cd3.tar.xz
ice-2d0d9ef78501a0d3c9b6ab77bd31afa845db7cd3.zip
Bug 2664 - show stack traces with C++
Diffstat (limited to 'cpp')
-rw-r--r--cpp/include/IceUtil/Exception.h3
-rw-r--r--cpp/src/Freeze/BackgroundSaveEvictorI.cpp10
-rw-r--r--cpp/src/Ice/Application.cpp57
-rw-r--r--cpp/src/Ice/BasicStream.cpp6
-rw-r--r--cpp/src/Ice/ConnectionFactory.cpp10
-rw-r--r--cpp/src/Ice/ConnectionI.cpp3
-rw-r--r--cpp/src/Ice/ConnectionMonitor.cpp3
-rw-r--r--cpp/src/Ice/Incoming.cpp3
-rw-r--r--cpp/src/Ice/Instance.cpp6
-rw-r--r--cpp/src/Ice/Outgoing.cpp3
-rw-r--r--cpp/src/Ice/OutgoingAsync.cpp3
-rw-r--r--cpp/src/Ice/SelectorThread.cpp15
-rw-r--r--cpp/src/Ice/ServantManager.cpp3
-rw-r--r--cpp/src/Ice/ThreadPool.cpp27
-rw-r--r--cpp/src/IceBox/ServiceManagerI.cpp38
-rw-r--r--cpp/src/IceUtil/Exception.cpp143
-rw-r--r--cpp/src/IceUtil/Timer.cpp8
-rw-r--r--cpp/test/Ice/exceptions/AllTests.cpp6
18 files changed, 347 insertions, 0 deletions
diff --git a/cpp/include/IceUtil/Exception.h b/cpp/include/IceUtil/Exception.h
index 907d7046c57..e545594c608 100644
--- a/cpp/include/IceUtil/Exception.h
+++ b/cpp/include/IceUtil/Exception.h
@@ -29,14 +29,17 @@ public:
virtual const char* what() const throw();
virtual Exception* ice_clone() const;
virtual void ice_throw() const;
+
const char* ice_file() const;
int ice_line() const;
+ const std::string& ice_stackTrace() const;
private:
const char* _file;
int _line;
static const char* _name;
+ const std::string _stackTrace;
mutable ::std::string _str; // Initialized lazily in what().
};
diff --git a/cpp/src/Freeze/BackgroundSaveEvictorI.cpp b/cpp/src/Freeze/BackgroundSaveEvictorI.cpp
index 755d22beced..83d4e4e0960 100644
--- a/cpp/src/Freeze/BackgroundSaveEvictorI.cpp
+++ b/cpp/src/Freeze/BackgroundSaveEvictorI.cpp
@@ -1215,6 +1215,16 @@ Freeze::BackgroundSaveEvictorI::run()
}
}
}
+ catch(const Ice::Exception& ex)
+ {
+ Error out(_communicator->getLogger());
+ out << "Saving thread killed by exception: " << ex.what();
+#ifdef __GNUC__
+ out << "\n" << ex.ice_stackTrace();
+#endif
+ out.flush();
+ handleFatalError(this, _communicator);
+ }
catch(const std::exception& ex)
{
Error out(_communicator->getLogger());
diff --git a/cpp/src/Ice/Application.cpp b/cpp/src/Ice/Application.cpp
index be6639227de..219f571810b 100644
--- a/cpp/src/Ice/Application.cpp
+++ b/cpp/src/Ice/Application.cpp
@@ -123,6 +123,14 @@ destroyOnInterruptCallback(int signal)
assert(_communicator != 0);
_communicator->destroy();
}
+ catch(const Ice::Exception& ex)
+ {
+ Error out(getProcessLogger());
+ out << _appName << " (while destroying in response to signal " << signal << "): " << ex.what();
+#ifdef __GNUC__
+ out << "\n" << ex.ice_stackTrace();
+#endif
+ }
catch(const std::exception& ex)
{
Error out(getProcessLogger());
@@ -178,6 +186,15 @@ shutdownOnInterruptCallback(int signal)
assert(_communicator != 0);
_communicator->shutdown();
}
+ catch(const Ice::Exception& ex)
+ {
+ Error out(getProcessLogger());
+ out << _appName << " (while shutting down in response to signal " << signal << "): std::exception: "
+ << ex.what();
+#ifdef __GNUC__
+ out << "\n" << ex.ice_stackTrace();
+#endif
+ }
catch(const std::exception& ex)
{
Error out(getProcessLogger());
@@ -231,6 +248,15 @@ callbackOnInterruptCallback(int signal)
assert(_application != 0);
_application->interruptCallback(signal);
}
+ catch(const Ice::Exception& ex)
+ {
+ Error out(getProcessLogger());
+ out << _appName << " (while interrupting in response to signal " << signal << "): std::exception: "
+ << ex.what();
+#ifdef __GNUC__
+ out << "\n" << ex.ice_stackTrace();
+#endif
+ }
catch(const std::exception& ex)
{
Error out(getProcessLogger());
@@ -290,6 +316,19 @@ Ice::Application::main(int argc, char* argv[], const char* configFile)
initData.properties = createProperties();
initData.properties->load(configFile);
}
+ catch(const Ice::Exception& ex)
+ {
+ Error out(getProcessLogger());
+ if(argv[0])
+ {
+ out << argv[0] << ": ";
+ }
+ out << ex.what();
+#ifdef __GNUC__
+ out << "\n" << ex.ice_stackTrace();
+#endif
+ return EXIT_FAILURE;
+ }
catch(const std::exception& ex)
{
Error out(getProcessLogger());
@@ -607,6 +646,15 @@ Ice::Application::mainInternal(int argc, char* argv[], const InitializationData&
status = run(argc, argv);
}
+ catch(const Ice::Exception& ex)
+ {
+ Error out(getProcessLogger());
+ out << ": " << ex.what();
+#ifdef __GNUC__
+ out << "\n" << ex.ice_stackTrace();
+#endif
+ status = EXIT_FAILURE;
+ }
catch(const std::exception& ex)
{
Error out(getProcessLogger());
@@ -670,6 +718,15 @@ Ice::Application::mainInternal(int argc, char* argv[], const InitializationData&
{
_communicator->destroy();
}
+ catch(const Ice::Exception& ex)
+ {
+ Error out(getProcessLogger());
+ out << _appName << ": " << ex.what();
+#ifdef __GNUC__
+ out << "\n" << ex.ice_stackTrace();
+#endif
+ status = EXIT_FAILURE;
+ }
catch(const std::exception& ex)
{
Error out(getProcessLogger());
diff --git a/cpp/src/Ice/BasicStream.cpp b/cpp/src/Ice/BasicStream.cpp
index 0841bb297f5..9b0f6c560f6 100644
--- a/cpp/src/Ice/BasicStream.cpp
+++ b/cpp/src/Ice/BasicStream.cpp
@@ -2093,6 +2093,9 @@ IceInternal::BasicStream::readPendingObjects()
{
Ice::Warning out(_instance->initializationData().logger);
out << "Ice::Exception raised by ice_postUnmarshal:\n" << ex;
+#ifdef __GNUC__
+ out << "\n" << ex.ice_stackTrace();
+#endif
}
catch(const std::exception& ex)
{
@@ -2155,6 +2158,9 @@ IceInternal::BasicStream::writeInstance(const ObjectPtr& v, Int index)
{
Ice::Warning out(_instance->initializationData().logger);
out << "Ice::Exception raised by ice_preMarshal:\n" << ex;
+#ifdef __GNUC__
+ out << "\n" << ex.ice_stackTrace();
+#endif
}
catch(const std::exception& ex)
{
diff --git a/cpp/src/Ice/ConnectionFactory.cpp b/cpp/src/Ice/ConnectionFactory.cpp
index 107887e6501..649abf514aa 100644
--- a/cpp/src/Ice/ConnectionFactory.cpp
+++ b/cpp/src/Ice/ConnectionFactory.cpp
@@ -1429,6 +1429,10 @@ IceInternal::IncomingConnectionFactory::message(BasicStream&, const ThreadPoolPt
{
Warning out(_instance->initializationData().logger);
out << "connection exception:\n" << ex << '\n' << _acceptor->toString();
+#ifdef __GNUC__
+ out << "\n" << ex.ice_stackTrace();
+#endif
+
}
return;
}
@@ -1454,6 +1458,9 @@ IceInternal::IncomingConnectionFactory::message(BasicStream&, const ThreadPoolPt
{
Warning out(_instance->initializationData().logger);
out << "connection exception:\n" << ex << '\n' << _acceptor->toString();
+#ifdef __GNUC__
+ out << "\n" << ex.ice_stackTrace();
+#endif
}
return;
}
@@ -1531,6 +1538,9 @@ IceInternal::IncomingConnectionFactory::connectionStartFailed(const Ice::Connect
{
Warning out(_instance->initializationData().logger);
out << "connection exception:\n" << ex << '\n' << _acceptor->toString();
+#ifdef __GNUC__
+ out << "\n" << ex.ice_stackTrace();
+#endif
}
//
diff --git a/cpp/src/Ice/ConnectionI.cpp b/cpp/src/Ice/ConnectionI.cpp
index 399351f2b0f..d5b92374617 100644
--- a/cpp/src/Ice/ConnectionI.cpp
+++ b/cpp/src/Ice/ConnectionI.cpp
@@ -1469,6 +1469,9 @@ Ice::ConnectionI::setState(State state, const LocalException& ex)
{
Warning out(_logger);
out << "connection exception:\n" << *_exception.get() << '\n' << _desc;
+#ifdef __GNUC__
+ out << "\n" << ex.ice_stackTrace();
+#endif
}
}
}
diff --git a/cpp/src/Ice/ConnectionMonitor.cpp b/cpp/src/Ice/ConnectionMonitor.cpp
index 6933ab3d401..935e38f785e 100644
--- a/cpp/src/Ice/ConnectionMonitor.cpp
+++ b/cpp/src/Ice/ConnectionMonitor.cpp
@@ -105,6 +105,9 @@ IceInternal::ConnectionMonitor::runTimerTask()
Error out(_instance->initializationData().logger);
out << "exception in connection monitor:\n" << ex;
+#ifdef __GNUC__
+ out << "\n" << ex.ice_stackTrace();
+#endif
}
catch(...)
{
diff --git a/cpp/src/Ice/Incoming.cpp b/cpp/src/Ice/Incoming.cpp
index ee574377515..d907f0da0ac 100644
--- a/cpp/src/Ice/Incoming.cpp
+++ b/cpp/src/Ice/Incoming.cpp
@@ -77,6 +77,9 @@ IceInternal::IncomingBase::__warning(const Exception& ex) const
{
ostringstream str;
str << ex;
+#ifdef __GNUC__
+ str << "\n" << ex.ice_stackTrace();
+#endif
__warning(str.str());
}
diff --git a/cpp/src/Ice/Instance.cpp b/cpp/src/Ice/Instance.cpp
index b95ca596911..a8adcd393bc 100644
--- a/cpp/src/Ice/Instance.cpp
+++ b/cpp/src/Ice/Instance.cpp
@@ -1032,6 +1032,9 @@ IceInternal::Instance::Instance(const CommunicatorPtr& communicator, const Initi
{
Error out(_initData.logger);
out << "cannot create thread for timer:\n" << ex;
+#ifdef __GNUC__
+ out << "\n" << ex.ice_stackTrace();
+#endif
throw;
}
@@ -1043,6 +1046,9 @@ IceInternal::Instance::Instance(const CommunicatorPtr& communicator, const Initi
{
Error out(_initData.logger);
out << "cannot create thread for endpoint host resolver:\n" << ex;
+#ifdef __GNUC__
+ out << "\n" << ex.ice_stackTrace();
+#endif
throw;
}
diff --git a/cpp/src/Ice/Outgoing.cpp b/cpp/src/Ice/Outgoing.cpp
index 893b105cd3f..165255d8a7d 100644
--- a/cpp/src/Ice/Outgoing.cpp
+++ b/cpp/src/Ice/Outgoing.cpp
@@ -58,6 +58,9 @@ IceInternal::LocalExceptionWrapper::throwWrapper(const std::exception& ex)
}
stringstream s;
s << *le;
+#ifdef __GNUC__
+ s << "\n" << le->ice_stackTrace();
+#endif
throw LocalExceptionWrapper(UnknownLocalException(__FILE__, __LINE__, s.str()), false);
}
string msg = "std::exception: ";
diff --git a/cpp/src/Ice/OutgoingAsync.cpp b/cpp/src/Ice/OutgoingAsync.cpp
index d1947092002..ae70612be37 100644
--- a/cpp/src/Ice/OutgoingAsync.cpp
+++ b/cpp/src/Ice/OutgoingAsync.cpp
@@ -194,6 +194,9 @@ IceInternal::OutgoingAsyncMessageCallback::__warning(const InstancePtr& instance
if(ex)
{
out << "Ice::Exception raised by AMI callback:\n" << *ex;
+#ifdef __GNUC__
+ out << "\n" << ex->ice_stackTrace();
+#endif
}
else
{
diff --git a/cpp/src/Ice/SelectorThread.cpp b/cpp/src/Ice/SelectorThread.cpp
index 8b1c815f7af..c5f53aa6620 100644
--- a/cpp/src/Ice/SelectorThread.cpp
+++ b/cpp/src/Ice/SelectorThread.cpp
@@ -36,6 +36,9 @@ IceInternal::SelectorThread::SelectorThread(const InstancePtr& instance) :
{
Error out(_instance->initializationData().logger);
out << "cannot create thread for selector thread:\n" << ex;
+#ifdef __GNUC__
+ out << "\n" << ex.ice_stackTrace();
+#endif
}
_thread = 0;
__setNoDelete(false);
@@ -156,6 +159,9 @@ IceInternal::SelectorThread::run()
{
Error out(_instance->initializationData().logger);
out << "exception in selector thread:\n" << ex;
+#ifdef __GNUC__
+ out << "\n" << ex.ice_stackTrace();
+#endif
continue;
}
@@ -230,6 +236,15 @@ IceInternal::SelectorThread::run()
status = cb->socketReady();
}
}
+ catch(const Ice::Exception& ex)
+ {
+ Error out(_instance->initializationData().logger);
+ out << "exception in selector thread while calling socketReady():\n" << ex.what();
+#ifdef __GNUC__
+ out << "\n" << ex.ice_stackTrace();
+#endif
+ status = Finished;
+ }
catch(const std::exception& ex)
{
Error out(_instance->initializationData().logger);
diff --git a/cpp/src/Ice/ServantManager.cpp b/cpp/src/Ice/ServantManager.cpp
index 6562896ae0a..1f6b5622231 100644
--- a/cpp/src/Ice/ServantManager.cpp
+++ b/cpp/src/Ice/ServantManager.cpp
@@ -426,6 +426,9 @@ IceInternal::ServantManager::destroy()
<< "object adapter: `" << _adapterName << "'\n"
<< "locator category: `" << p->first << "'\n"
<< ex;
+#ifdef __GNUC__
+ out << "\n" << ex.ice_stackTrace();
+#endif
}
catch(...)
{
diff --git a/cpp/src/Ice/ThreadPool.cpp b/cpp/src/Ice/ThreadPool.cpp
index 70bc4513bd4..834cbb27695 100644
--- a/cpp/src/Ice/ThreadPool.cpp
+++ b/cpp/src/Ice/ThreadPool.cpp
@@ -113,6 +113,9 @@ IceInternal::ThreadPool::ThreadPool(const InstancePtr& instance, const string& p
{
Error out(_instance->initializationData().logger);
out << "cannot create thread for `" << _prefix << "':\n" << ex;
+#ifdef __GNUC__
+ out << "\n" << ex.ice_stackTrace();
+#endif
}
destroy();
@@ -271,6 +274,9 @@ IceInternal::ThreadPool::promoteFollower(EventHandler* handler)
{
Error out(_instance->initializationData().logger);
out << "cannot create thread for `" << _prefix << "':\n" << ex;
+#ifdef __GNUC__
+ out << "\n" << ex.ice_stackTrace();
+#endif
}
}
}
@@ -327,6 +333,9 @@ IceInternal::ThreadPool::run()
{
Error out(_instance->initializationData().logger);
out << "exception in `" << _prefix << "':\n" << ex;
+#ifdef __GNUC__
+ out << "\n" << ex.ice_stackTrace();
+#endif
continue;
}
@@ -437,6 +446,9 @@ IceInternal::ThreadPool::run()
{
Error out(_instance->initializationData().logger);
out << "exception in `" << _prefix << "' while calling execute():\n" << ex;
+#ifdef __GNUC__
+ out << "\n" << ex.ice_stackTrace();
+#endif
}
//
@@ -467,6 +479,9 @@ IceInternal::ThreadPool::run()
Error out(_instance->initializationData().logger);
out << "exception in `" << _prefix << "' while calling finished():\n"
<< ex << '\n' << handler->toString();
+#ifdef __GNUC__
+ out << "\n" << ex.ice_stackTrace();
+#endif
}
//
@@ -545,6 +560,9 @@ IceInternal::ThreadPool::run()
Error out(_instance->initializationData().logger);
out << "exception in `" << _prefix << "' while calling message():\n"
<< ex << '\n' << handler->toString();
+#ifdef __GNUC__
+ out << "\n" << ex.ice_stackTrace();
+#endif
}
//
@@ -807,6 +825,15 @@ IceInternal::ThreadPool::EventHandlerThread::run()
{
promote = _pool->run();
}
+ catch(const Ice::Exception& ex)
+ {
+ Error out(_pool->_instance->initializationData().logger);
+ out << "exception in `" << _pool->_prefix << "':\n" << ex.what();
+#ifdef __GNUC__
+ out << "\n" << ex.ice_stackTrace();
+#endif
+ promote = true;
+ }
catch(const std::exception& ex)
{
Error out(_pool->_instance->initializationData().logger);
diff --git a/cpp/src/IceBox/ServiceManagerI.cpp b/cpp/src/IceBox/ServiceManagerI.cpp
index e80a49474e6..c5b59c43b7f 100644
--- a/cpp/src/IceBox/ServiceManagerI.cpp
+++ b/cpp/src/IceBox/ServiceManagerI.cpp
@@ -190,6 +190,9 @@ IceBox::ServiceManagerI::startService(const string& name, const Current&)
Warning out(_logger);
out << "ServiceManager: exception in start for service " << info.name << ":\n";
out << ex;
+#ifdef __GNUC__
+ out << "\n" << ex.ice_stackTrace();
+#endif
}
catch(...)
{
@@ -268,6 +271,9 @@ IceBox::ServiceManagerI::stopService(const string& name, const Current&)
Warning out(_logger);
out << "ServiceManager: exception in stop for service " << info.name << ":\n";
out << ex;
+#ifdef __GNUC__
+ out << "\n" << ex.ice_stackTrace();
+#endif
}
catch(...)
{
@@ -545,6 +551,9 @@ IceBox::ServiceManagerI::start()
{
Error out(_logger);
out << ex.reason;
+#ifdef __GNUC__
+ out << "\n" << ex.ice_stackTrace();
+#endif
stopAll();
return false;
}
@@ -552,6 +561,9 @@ IceBox::ServiceManagerI::start()
{
Error out(_logger);
out << "ServiceManager: " << ex;
+#ifdef __GNUC__
+ out << "\n" << ex.ice_stackTrace();
+#endif
stopAll();
return false;
}
@@ -701,6 +713,9 @@ IceBox::ServiceManagerI::start(const string& service, const string& entryPoint,
Warning out(_logger);
out << "ServiceManager: exception in shutting down communicator for service " << service << ":\n";
out << ex;
+#ifdef __GNUC__
+ out << "\n" << ex.ice_stackTrace();
+#endif
}
try
@@ -713,6 +728,9 @@ IceBox::ServiceManagerI::start(const string& service, const string& entryPoint,
Warning out(_logger);
out << "ServiceManager: exception in shutting down communicator for service " << service << ":\n";
out << ex;
+#ifdef __GNUC__
+ out << "\n" << ex.ice_stackTrace();
+#endif
}
}
throw;
@@ -778,6 +796,9 @@ IceBox::ServiceManagerI::stopAll()
Warning out(_logger);
out << "ServiceManager: exception in stop for service " << info.name << ":\n";
out << ex;
+#ifdef __GNUC__
+ out << "\n" << ex.ice_stackTrace();
+#endif
}
catch(...)
{
@@ -819,6 +840,9 @@ IceBox::ServiceManagerI::stopAll()
Warning out(_logger);
out << "ServiceManager: exception in stop for service " << info.name << ":\n";
out << ex;
+#ifdef __GNUC__
+ out << "\n" << ex.ice_stackTrace();
+#endif
}
}
@@ -856,6 +880,9 @@ IceBox::ServiceManagerI::stopAll()
Warning out(_logger);
out << "ServiceManager: exception in stop for service " << info.name << ":\n";
out << ex;
+#ifdef __GNUC__
+ out << "\n" << ex.ice_stackTrace();
+#endif
}
}
@@ -868,6 +895,9 @@ IceBox::ServiceManagerI::stopAll()
Warning out(_logger);
out << "ServiceManager: exception in stop for service " << info.name << ":\n";
out << ex;
+#ifdef __GNUC__
+ out << "\n" << ex.ice_stackTrace();
+#endif
}
catch(...)
{
@@ -882,6 +912,14 @@ IceBox::ServiceManagerI::stopAll()
{
_sharedCommunicator->destroy();
}
+ catch(const Ice::Exception& ex)
+ {
+ Warning out(_logger);
+ out << "ServiceManager: unknown exception while destroying shared communicator:\n" << ex.what();
+#ifdef __GNUC__
+ out << "\n" << ex.ice_stackTrace();
+#endif
+ }
catch(const std::exception& ex)
{
Warning out(_logger);
diff --git a/cpp/src/IceUtil/Exception.cpp b/cpp/src/IceUtil/Exception.cpp
index 55a32df57c2..6c4cb6624ce 100644
--- a/cpp/src/IceUtil/Exception.cpp
+++ b/cpp/src/IceUtil/Exception.cpp
@@ -13,6 +13,11 @@
#include <ostream>
#include <cstdlib>
+#ifdef __GNUC__
+# include <execinfo.h>
+# include <cxxabi.h>
+#endif
+
using namespace std;
namespace IceUtil
@@ -22,15 +27,147 @@ bool ICE_DECLSPEC_EXPORT nullHandleAbort = false;
};
+#ifdef __GNUC__
+namespace
+{
+
+string
+getStackTrace()
+{
+ string stackTrace;
+
+ const size_t maxDepth = 100;
+ void *stackAddrs[maxDepth];
+
+ size_t stackDepth = backtrace(stackAddrs, maxDepth);
+ char **stackStrings = backtrace_symbols(stackAddrs, stackDepth);
+
+ bool checkException = true;
+ for (size_t i = 1; i < stackDepth; i++)
+ {
+ string line(stackStrings[i]);
+
+ //
+ // Don't add the traces for the Exception constructors.
+ //
+ if(checkException)
+ {
+ if(line.find("ExceptionC") != string::npos)
+ {
+ continue;
+ }
+ else
+ {
+ checkException = false;
+ }
+ }
+ else
+ {
+ stackTrace += "\n";
+ }
+
+ stackTrace += " ";
+
+ //
+ // For each line attempt to parse the mangled function name as well
+ // as the source library/executable.
+ //
+ string mangled;
+ string::size_type openParen = line.find_first_of('(');
+ if(openParen != string::npos)
+ {
+ //
+ // Format: "/opt/Ice/lib/libIceUtil.so.33(_ZN7IceUtil9ExceptionC2EPKci+0x51) [0x73b267]"
+ //
+ string::size_type closeParen = line.find_first_of(')', openParen);
+ if(closeParen != string::npos)
+ {
+ string tmp = line.substr(openParen + 1, closeParen - openParen - 1);
+ string::size_type plus = tmp.find_last_of('+');
+ if(plus != string::npos)
+ {
+ mangled = tmp.substr(0 , plus);
+
+ stackTrace += line.substr(0, openParen);
+ }
+ }
+ }
+ else
+ {
+ //
+ // Format: "1 libIce.3.3.1.dylib 0x000933a1 _ZN7IceUtil9ExceptionC2EPKci + 71"
+ //
+ string::size_type plus = line.find_last_of('+');
+ if(plus != string::npos)
+ {
+ string tmp = line.substr(0, plus - 1);
+ string::size_type space = tmp.find_last_of(" \t");
+ if(space != string::npos)
+ {
+ tmp = tmp.substr(space + 1, tmp.size() - space);
+
+ string::size_type start = line.find_first_not_of(" \t", 3);
+ if(start != string::npos)
+ {
+ string::size_type finish = line.find_first_of(" \t", start);
+ if(finish != string::npos)
+ {
+ mangled = tmp;
+
+ stackTrace += line.substr(start, finish - start);
+ }
+ }
+ }
+ }
+ }
+ if(mangled.size() != 0)
+ {
+ stackTrace += ": ";
+
+ //
+ // Unmangle the function name
+ //
+ int status;
+ char* unmangled = abi::__cxa_demangle(mangled.c_str(), 0, 0, &status);
+ if(unmangled)
+ {
+ stackTrace += unmangled;
+ free(unmangled);
+ }
+ else
+ {
+ stackTrace += mangled;
+ stackTrace += "()";
+ }
+ }
+ else
+ {
+ stackTrace += line;
+ }
+ }
+ free(stackStrings);
+
+ return stackTrace;
+}
+
+};
+#endif
+
IceUtil::Exception::Exception() :
_file(0),
_line(0)
+#ifdef __GNUC__
+ , _stackTrace(getStackTrace())
+#endif
{
}
IceUtil::Exception::Exception(const char* file, int line) :
_file(file),
_line(line)
+#ifdef __GNUC__
+ , _stackTrace(getStackTrace())
+#endif
{
}
@@ -102,6 +239,12 @@ IceUtil::Exception::ice_line() const
return _line;
}
+const string&
+IceUtil::Exception::ice_stackTrace() const
+{
+ return _stackTrace;
+}
+
ostream&
IceUtil::operator<<(ostream& out, const IceUtil::Exception& ex)
{
diff --git a/cpp/src/IceUtil/Timer.cpp b/cpp/src/IceUtil/Timer.cpp
index 41200f5648b..8d19580e099 100644
--- a/cpp/src/IceUtil/Timer.cpp
+++ b/cpp/src/IceUtil/Timer.cpp
@@ -184,6 +184,14 @@ Timer::run()
{
token.task->runTimerTask();
}
+ catch(const IceUtil::Exception& e)
+ {
+ cerr << "IceUtil::Timer::run(): uncaught exception:\n" << e.what();
+#ifdef __GNUC__
+ cerr << "\n" << e.ice_stackTrace();
+#endif
+ cerr << endl;
+ }
catch(const std::exception& e)
{
cerr << "IceUtil::Timer::run(): uncaught exception:\n" << e.what() << endl;
diff --git a/cpp/test/Ice/exceptions/AllTests.cpp b/cpp/test/Ice/exceptions/AllTests.cpp
index 289e0ae1161..a65fa4b1a34 100644
--- a/cpp/test/Ice/exceptions/AllTests.cpp
+++ b/cpp/test/Ice/exceptions/AllTests.cpp
@@ -965,6 +965,12 @@ allTests(const Ice::CommunicatorPtr& communicator, bool collocated)
catch(const Ice::UnknownUserException&)
{
}
+ catch(const Ice::Exception& ex)
+ {
+ cout << ex << endl;
+ cout << ex.ice_stackTrace() << endl;
+ test(false);
+ }
catch(...)
{
test(false);