summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp')
-rw-r--r--cpp/include/IceUtil/Exception.h5
-rw-r--r--cpp/src/IceUtil/Exception.cpp646
-rw-r--r--cpp/test/IceUtil/stacktrace/Client.cpp222
-rw-r--r--cpp/test/IceUtil/stacktrace/StackTrace.debug-release.OSX14
-rw-r--r--cpp/test/IceUtil/stacktrace/StackTrace.debug.Linux18
-rw-r--r--cpp/test/IceUtil/stacktrace/StackTrace.debug.OSX14
-rw-r--r--cpp/test/IceUtil/stacktrace/StackTrace.release.Linux2
-rw-r--r--cpp/test/IceUtil/stacktrace/StackTrace.release.OSX4
8 files changed, 525 insertions, 400 deletions
diff --git a/cpp/include/IceUtil/Exception.h b/cpp/include/IceUtil/Exception.h
index 663e4471673..ba82e81cc38 100644
--- a/cpp/include/IceUtil/Exception.h
+++ b/cpp/include/IceUtil/Exception.h
@@ -188,4 +188,9 @@ private:
}
+namespace IceUtilInternal
+{
+ ICE_UTIL_API bool canCaptureStackTrace();
+}
+
#endif
diff --git a/cpp/src/IceUtil/Exception.cpp b/cpp/src/IceUtil/Exception.cpp
index 3a57e1ba797..27af47fdba7 100644
--- a/cpp/src/IceUtil/Exception.cpp
+++ b/cpp/src/IceUtil/Exception.cpp
@@ -28,25 +28,44 @@
#include <iomanip>
#include <cstdlib>
-
-#if defined(__GNUC__) && !defined(__sun) && !defined(__FreeBSD__) && !defined(__MINGW32__) && \
- !defined(ICE_STATIC_LIBS)
-# include <execinfo.h>
-# include <cxxabi.h>
-# define ICE_GCC_STACK_TRACES
+#ifdef __GNUC__
+# define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
+
+# if defined(__linux) && ((GCC_VERSION >= 5003) || ((GCC_VERSION >= 4008) && (!defined(NDEBUG))))
+ // On Linux with GCC, we use libbacktrace:
+ // - all the time with GCC >= 5.3
+ // - only for release builds with GCC >= 4.8 and < 5.3
+ // in practice, for GCC 4.8, libbacktrace does not seem to work when the final
+ // executable is built without debug information
+
+# include <backtrace.h>
+# include <backtrace-supported.h>
+# if BACKTRACE_SUPPORTED && BACKTRACE_SUPPORTS_THREADS
+# include <algorithm>
+# include <cxxabi.h>
+# define ICE_LIBBACKTRACE
+# endif
+# endif
+
+# if !defined(__sun) && !defined(__FreeBSD__) && !defined(__MINGW32__) && !defined(ICE_STATIC_LIBS)
+# include <execinfo.h>
+# include <cxxabi.h>
+# include <stdint.h>
+# define ICE_BACKTRACE
+# endif
#endif
#if defined(_WIN32) && !defined(ICE_OS_WINRT) && !defined(__MINGW32__)
-# define ICE_WIN32_STACK_TRACES
-# if defined(_MSC_VER) && _MSC_VER >= 1700
-# define DBGHELP_TRANSLATE_TCHAR
-# include <IceUtil/StringConverter.h>
-# if _MSC_VER >= 1900
-# pragma warning(disable:4091) // VS 2015 RC issues this warning for code in DbgHelp.h
-# endif
-# endif
-# include <DbgHelp.h>
-# include <tchar.h>
+# define ICE_DBGHELP
+# if defined(_MSC_VER) && (_MSC_VER >= 1700)
+# define DBGHELP_TRANSLATE_TCHAR
+# include <IceUtil/StringConverter.h>
+# if _MSC_VER >= 1900
+# pragma warning(disable:4091) // VS 2015 RC issues this warning for code in DbgHelp.h
+# endif
+# endif
+# include <DbgHelp.h>
+# include <tchar.h>
#endif
using namespace std;
@@ -57,6 +76,14 @@ namespace IceUtilInternal
bool ICE_UTIL_API printStackTraces = false;
bool ICE_UTIL_API nullHandleAbort = false;
+bool canCaptureStackTrace()
+{
+#if defined(ICE_DBGHELP) || defined(ICE_LIBBACKTRACE) || defined(ICE_BACKTRACE)
+ return true;
+#else
+ return false;
+#endif
+}
}
namespace
@@ -64,35 +91,190 @@ namespace
IceUtil::Mutex* globalMutex = 0;
-#ifdef ICE_WIN32_STACK_TRACES
+#ifdef ICE_DBGHELP
HANDLE process = 0;
#endif
+#ifdef ICE_LIBBACKTRACE
+backtrace_state* bstate = 0;
+#endif
+
class Init
{
public:
Init()
{
- globalMutex = new IceUtil::Mutex;
+ globalMutex = new IceUtil::Mutex;
+#ifdef ICE_LIBBACKTRACE
+ // Leaked, as libbacktrace does not provide an API to free
+ // this state
+ bstate = backtrace_create_state(0, 1, 0, 0);
+#endif
}
~Init()
{
- delete globalMutex;
- globalMutex = 0;
-#ifdef ICE_WIN32_STACK_TRACES
- if(process != 0)
- {
- SymCleanup(process);
- process = 0;
- }
+ delete globalMutex;
+ globalMutex = 0;
+#ifdef ICE_DBGHELP
+ if(process != 0)
+ {
+ SymCleanup(process);
+ process = 0;
+ }
#endif
}
};
Init init;
+#if defined(ICE_LIBBACKTRACE) || defined (ICE_BACKTRACE)
+
+struct FrameInfo
+{
+ explicit FrameInfo(int i) :
+ index(i),
+ fallback(0)
+ {
+ }
+
+ int index;
+ const char* fallback;
+ string output;
+};
+
+void
+decode(const string& line, string& function, string& filename)
+{
+ 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)
+ {
+ function = tmp.substr(0 , plus);
+ filename = 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)
+ {
+ function = tmp;
+ filename = line.substr(start, finish - start);
+ }
+ }
+ }
+ }
+ }
+}
+
+int
+printFrame(void* data, uintptr_t pc, const char* filename, int lineno, const char* function)
+{
+ FrameInfo& frameInfo = *reinterpret_cast<FrameInfo*>(data);
+
+ ostringstream os;
+ os << setw(3) << frameInfo.index << " ";
+
+ string functionHolder, filenameHolder;
+
+ if(!function && frameInfo.fallback)
+ {
+ // Extract function and filename from fallback
+ decode(frameInfo.fallback, functionHolder, filenameHolder);
+ if(!functionHolder.empty())
+ {
+ function = functionHolder.c_str();
+ }
+ if(!filename && !filenameHolder.empty())
+ {
+ filename = filenameHolder.c_str();
+ }
+ }
+
+ int ret = 0;
+
+ if(function)
+ {
+ char* demangledFunction = abi::__cxa_demangle(function, 0, 0, 0);
+ if(demangledFunction)
+ {
+ os << demangledFunction;
+ free(demangledFunction);
+ }
+ else
+ {
+ os << function;
+ }
+
+ if(filename && lineno > 0)
+ {
+ os << " at " << filename << ":" << lineno;
+ }
+ else if(filename)
+ {
+ os << " in " << filename;
+ }
+ }
+ else if(frameInfo.fallback)
+ {
+ // decode was not able to parse this string
+ os << frameInfo.fallback;
+ ret = 1;
+ }
+ else
+ {
+ os << hex << setw(sizeof(uintptr_t) * 2) << setfill('0') << pc;
+ ret = 2;
+ }
+ os << "\n";
+ frameInfo.output = os.str();
+ return ret;
+}
+#endif
+
+#ifdef ICE_LIBBACKTRACE
+int
+addFrame(void* sf, uintptr_t pc)
+{
+ if(pc != UINTPTR_MAX)
+ {
+ vector<void*>* stackFrames = reinterpret_cast<vector<void*>*>(sf);
+ stackFrames->push_back(reinterpret_cast<void*>(pc));
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
+}
+#endif
vector<void*>
getStackFrames()
@@ -101,10 +283,10 @@ getStackFrames()
if(!IceUtilInternal::printStackTraces)
{
- return stackFrames;
+ return stackFrames;
}
-# if defined(ICE_WIN32_STACK_TRACES)
+#if defined(ICE_DBGHELP)
stackFrames.resize(61);
//
@@ -114,14 +296,20 @@ getStackFrames()
USHORT frameCount = CaptureStackBackTrace(1, static_cast<DWORD>(stackFrames.size()), &stackFrames.front(), 0);
stackFrames.resize(frameCount);
+#elif defined(ICE_LIBBACKTRACE)
+
+ backtrace_simple(bstate, 1, addFrame, 0, &stackFrames);
+
+#elif defined(ICE_BACKTRACE)
-# elif defined(ICE_GCC_STACK_TRACES)
-
stackFrames.resize(100);
size_t stackDepth = backtrace(&stackFrames.front(), stackFrames.size());
stackFrames.resize(stackDepth);
-
-# endif
+ if(!stackFrames.empty())
+ {
+ stackFrames.erase(stackFrames.begin()); // drop the first frame
+ }
+#endif
return stackFrames;
}
@@ -132,12 +320,12 @@ getStackTrace(const vector<void*>& stackFrames)
{
if(stackFrames.empty())
{
- return "";
+ return "";
}
string stackTrace;
-# if defined(ICE_WIN32_STACK_TRACES)
+#if defined(ICE_DBGHELP)
//
// Note: the Sym functions are not thread-safe
@@ -145,68 +333,68 @@ getStackTrace(const vector<void*>& stackFrames)
IceUtilInternal::MutexPtrLock<IceUtil::Mutex> lock(globalMutex);
if(process == 0)
{
- //
- // Compute Search path (best effort)
- // consists of the current working directory, this DLL (or exe) directory and %_NT_SYMBOL_PATH%
- //
- basic_string<TCHAR> searchPath;
- const TCHAR pathSeparator = _T('\\');
- const TCHAR searchPathSeparator = _T(';');
-
- TCHAR cwd[MAX_PATH];
- if(GetCurrentDirectory(MAX_PATH, cwd) != 0)
- {
- searchPath = cwd;
- }
-
- HMODULE myModule = 0;
- GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
- "startHook",
- &myModule);
- //
- // If GetModuleHandleEx fails, myModule is NULL, i.e. we'll locate the current exe's directory.
- //
-
- TCHAR myFilename[MAX_PATH];
- DWORD len = GetModuleFileName(myModule, myFilename, MAX_PATH);
- if(len != 0 && len < MAX_PATH)
- {
- assert(myFilename[len] == 0);
-
- basic_string<TCHAR> myPath = myFilename;
- size_t pos = myPath.find_last_of(pathSeparator);
- if(pos != basic_string<TCHAR>::npos)
- {
- myPath = myPath.substr(0, pos);
-
- if(!searchPath.empty())
- {
- searchPath += searchPathSeparator;
- }
- searchPath += myPath;
- }
- }
-
- const DWORD size = 1024;
- TCHAR symbolPath[size];
- len = GetEnvironmentVariable(_T("_NT_SYMBOL_PATH"), symbolPath, size);
- if(len > 0 && len < size)
- {
- if(!searchPath.empty())
- {
- searchPath += searchPathSeparator;
- }
- searchPath += symbolPath;
- }
-
- process = GetCurrentProcess();
-
- SymSetOptions(SYMOPT_LOAD_LINES | SYMOPT_DEFERRED_LOADS | SYMOPT_EXACT_SYMBOLS | SYMOPT_UNDNAME);
- if(SymInitialize(process, searchPath.c_str(), TRUE) == 0)
- {
- process = 0;
- return "No stack trace: SymInitialize failed with " + IceUtilInternal::errorToString(GetLastError());
- }
+ //
+ // Compute Search path (best effort)
+ // consists of the current working directory, this DLL (or exe) directory and %_NT_SYMBOL_PATH%
+ //
+ basic_string<TCHAR> searchPath;
+ const TCHAR pathSeparator = _T('\\');
+ const TCHAR searchPathSeparator = _T(';');
+
+ TCHAR cwd[MAX_PATH];
+ if(GetCurrentDirectory(MAX_PATH, cwd) != 0)
+ {
+ searchPath = cwd;
+ }
+
+ HMODULE myModule = 0;
+ GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
+ "startHook",
+ &myModule);
+ //
+ // If GetModuleHandleEx fails, myModule is NULL, i.e. we'll locate the current exe's directory.
+ //
+
+ TCHAR myFilename[MAX_PATH];
+ DWORD len = GetModuleFileName(myModule, myFilename, MAX_PATH);
+ if(len != 0 && len < MAX_PATH)
+ {
+ assert(myFilename[len] == 0);
+
+ basic_string<TCHAR> myPath = myFilename;
+ size_t pos = myPath.find_last_of(pathSeparator);
+ if(pos != basic_string<TCHAR>::npos)
+ {
+ myPath = myPath.substr(0, pos);
+
+ if(!searchPath.empty())
+ {
+ searchPath += searchPathSeparator;
+ }
+ searchPath += myPath;
+ }
+ }
+
+ const DWORD size = 1024;
+ TCHAR symbolPath[size];
+ len = GetEnvironmentVariable(_T("_NT_SYMBOL_PATH"), symbolPath, size);
+ if(len > 0 && len < size)
+ {
+ if(!searchPath.empty())
+ {
+ searchPath += searchPathSeparator;
+ }
+ searchPath += symbolPath;
+ }
+
+ process = GetCurrentProcess();
+
+ SymSetOptions(SYMOPT_LOAD_LINES | SYMOPT_DEFERRED_LOADS | SYMOPT_EXACT_SYMBOLS | SYMOPT_UNDNAME);
+ if(SymInitialize(process, searchPath.c_str(), TRUE) == 0)
+ {
+ process = 0;
+ return "No stack trace: SymInitialize failed with " + IceUtilInternal::errorToString(GetLastError());
+ }
}
lock.release();
@@ -215,193 +403,135 @@ getStackTrace(const vector<void*>& stackFrames)
static_assert(sizeof(TCHAR) == sizeof(wchar_t), "Bad TCHAR - should be wchar_t");
# else
static_assert(sizeof(TCHAR) == sizeof(char), "Bad TCHAR - should be char");
-# endif
+# endif
#endif
char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
-
+
SYMBOL_INFO* symbol = reinterpret_cast<SYMBOL_INFO*>(buffer);
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
symbol->MaxNameLen = MAX_SYM_NAME;
-
+
IMAGEHLP_LINE64 line = {};
line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
DWORD displacement = 0;
-
+
lock.acquire();
-
+
// TODO: call SymRefreshModuleList here? (not available on XP)
-
+
#ifdef DBGHELP_TRANSLATE_TCHAR
const IceUtil::StringConverterPtr converter = IceUtil::getProcessStringConverter();
#endif
for(size_t i = 0; i < stackFrames.size(); i++)
{
- if(!stackTrace.empty())
- {
- stackTrace += "\n";
- }
-
- stringstream s;
- s << setw(3) << i << " ";
-
- DWORD64 address = reinterpret_cast<DWORD64>(stackFrames[i]);
-
- BOOL ok = SymFromAddr(process, address, 0, symbol);
- if(ok)
- {
+ ostringstream s;
+ s << setw(3) << i << " ";
+
+ DWORD64 address = reinterpret_cast<DWORD64>(stackFrames[i]);
+
+ BOOL ok = SymFromAddr(process, address, 0, symbol);
+ if(ok)
+ {
#ifdef DBGHELP_TRANSLATE_TCHAR
- s << IceUtil::wstringToString(symbol->Name, converter);
+ s << IceUtil::wstringToString(symbol->Name, converter);
#else
- s << symbol->Name;
+ s << symbol->Name;
#endif
- ok = SymGetLineFromAddr64(process, address, &displacement, &line);
- if(ok)
- {
- s << " at line " << line.LineNumber << " in "
+ ok = SymGetLineFromAddr64(process, address, &displacement, &line);
+ if(ok)
+ {
+ s << " at "
#ifdef DBGHELP_TRANSLATE_TCHAR
- << IceUtil::wstringToString(line.FileName, converter);
+ << IceUtil::wstringToString(line.FileName, converter)
#else
- << line.FileName;
+ << line.FileName
#endif
- }
- }
- else
- {
- s << hex << "0x" << address;
- }
- stackTrace += s.str();
+ << ":" << line.LineNumber;
+ }
+ }
+ else
+ {
+ s << hex << setw(sizeof(DWORD64) * 2) << setfill('0') << address;
+ }
+ s << "\n";
+ stackTrace += s.str();
}
lock.release();
-# elif defined(ICE_GCC_STACK_TRACES)
+#elif defined(ICE_LIBBACKTRACE) || defined (ICE_BACKTRACE)
+
+ vector<void*>::const_iterator p = stackFrames.begin();
+ int frameIndex = 0;
+ int offset = 0;
+ char** backtraceStrings = 0;
- // With some compilers/toolchains this can fail so we must check that
- // stackStrings is not null.
-
- char** stackStrings = backtrace_symbols(&stackFrames.front(), stackFrames.size());
- if(stackStrings != 0)
+# if defined(ICE_LIBBACKTRACE) && defined(ICE_BACKTRACE)
+ bool backtraceStringsInitialized = false;
+# endif
+# if !defined(ICE_LIBBACKTRACE)
+ // Initialize backtraceStrings immediately
+ if(p != stackFrames.end())
{
- //
- // Start at 1 to skip the top frame (== call to this function)
- //
- for(size_t i = 1; i < stackFrames.size(); i++)
- {
- string line(stackStrings[i]);
-
- if(i > 1)
- {
- stackTrace += "\n";
- }
-
- stringstream s;
- s << setw(3) << i - 1 << " ";
-
- //
- // For each line attempt to parse the mangled function name as well
- // as the source library/executable.
- //
- string mangled;
- string source;
- 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);
-
- source = 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;
-
- source = line.substr(start, finish - start);
- }
- }
- }
- }
- }
- if(mangled.size() != 0)
- {
- //
- // Unmangle the function name
- //
- int status;
- char* unmangled = abi::__cxa_demangle(mangled.c_str(), 0, 0, &status);
- if(unmangled)
- {
- s << unmangled;
- free(unmangled);
- }
- else
- {
- s << mangled << "()";
- }
-
- if(!source.empty())
- {
- s << " in " << source;
- }
- }
- else
- {
- s << line;
- }
-
- stackTrace += s.str();
- }
- free(stackStrings);
+ backtraceStrings = backtrace_symbols(&*p, stackFrames.size());
}
- else
+# endif
+
+ do
{
- stackTrace = "<stack trace unavailable>";
+ FrameInfo frameInfo(frameIndex);
+ bool retry = false;
+
+ if(backtraceStrings)
+ {
+ frameInfo.fallback = backtraceStrings[frameIndex - offset];
+ }
+
+# if defined(ICE_LIBBACKTRACE)
+ if(backtrace_pcinfo(bstate, reinterpret_cast<uintptr_t>(*p), printFrame, 0, &frameInfo) != 0)
+ {
+# if defined(ICE_BACKTRACE)
+ if(!backtraceStringsInitialized)
+ {
+ offset = frameIndex;
+ // Initialize backtraceStrings as fallback
+ backtraceStrings = backtrace_symbols(&*p, stackFrames.size() - offset);
+ backtraceStringsInitialized = true;
+ retry = true;
+ }
+# endif
+ }
+# else // not using libbacktrace:
+ printFrame(&frameInfo, reinterpret_cast<uintptr_t>(*p), 0, 0, 0);
+# endif
+ if(!retry)
+ {
+ stackTrace += frameInfo.output;
+ ++p;
+ ++frameIndex;
+ }
+ } while(p != stackFrames.end());
+
+ if(backtraceStrings)
+ {
+ free(backtraceStrings);
}
-# endif
-
+#endif
return stackTrace;
}
}
IceUtil::Exception::Exception() :
_file(0),
- _line(0),
+ _line(0),
_stackFrames(getStackFrames())
{
}
IceUtil::Exception::Exception(const char* file, int line) :
_file(file),
- _line(line),
+ _line(line),
_stackFrames(getStackFrames())
{
}
@@ -415,7 +545,7 @@ IceUtil::Exception::ice_print(ostream& out) const
{
if(_file && _line > 0)
{
- out << _file << ':' << _line << ": ";
+ out << _file << ':' << _line << ": ";
}
out << ice_id();
}
@@ -425,16 +555,16 @@ IceUtil::Exception::what() const ICE_NOEXCEPT
{
try
{
- IceUtilInternal::MutexPtrLock<IceUtil::Mutex> lock(globalMutex);
- {
- if(_str.empty())
- {
- stringstream s;
- ice_print(s);
- _str = s.str(); // Lazy initialization.
- }
- }
- return _str.c_str();
+ IceUtilInternal::MutexPtrLock<IceUtil::Mutex> lock(globalMutex);
+ {
+ if(_str.empty())
+ {
+ stringstream s;
+ ice_print(s);
+ _str = s.str(); // Lazy initialization.
+ }
+ }
+ return _str.c_str();
}
catch(...)
{
@@ -454,11 +584,11 @@ IceUtil::Exception::ice_clone() const
{
try
{
- ice_throw();
+ ice_throw();
}
catch(...)
{
- return current_exception();
+ return current_exception();
}
assert(false);
return nullptr; // Make compilers happy
@@ -514,7 +644,7 @@ IceUtil::NullHandleException::NullHandleException(const char* file, int line) :
{
if(IceUtilInternal::nullHandleAbort)
{
- abort();
+ abort();
}
}
@@ -598,7 +728,7 @@ IceUtil::IllegalConversionException::IllegalConversionException(const char* file
{}
IceUtil::IllegalConversionException::IllegalConversionException(const char* file, int line,
- const string& reason):
+ const string& reason):
Exception(file, line),
_reason(reason)
{}
@@ -654,7 +784,7 @@ IceUtil::SyscallException::ice_print(ostream& os) const
Exception::ice_print(os);
if(_error != 0)
{
- os << ":\nsyscall exception: " << IceUtilInternal::errorToString(_error);
+ os << ":\nsyscall exception: " << IceUtilInternal::errorToString(_error);
}
}
@@ -703,7 +833,7 @@ IceUtil::FileLockException::ice_print(ostream& os) const
os << ":\ncould not lock file: `" << _path << "'";
if(_error != 0)
{
- os << "\nsyscall exception: " << IceUtilInternal::errorToString(_error);
+ os << "\nsyscall exception: " << IceUtilInternal::errorToString(_error);
}
}
@@ -738,7 +868,7 @@ IceUtil::OptionalNotSetException::OptionalNotSetException(const char* file, int
{
if(IceUtilInternal::nullHandleAbort)
{
- abort();
+ abort();
}
}
diff --git a/cpp/test/IceUtil/stacktrace/Client.cpp b/cpp/test/IceUtil/stacktrace/Client.cpp
index ff71e1866cc..9e47d7cbf73 100644
--- a/cpp/test/IceUtil/stacktrace/Client.cpp
+++ b/cpp/test/IceUtil/stacktrace/Client.cpp
@@ -15,14 +15,6 @@
using namespace IceUtil;
using namespace std;
-#if defined(__GNUC__) && !defined(__sun) && !defined(__FreeBSD__) && !defined(__MINGW32__) && \
- !defined(ICE_STATIC_LIBS)
-# define HAS_STACK_TRACES
-#endif
-
-#if defined(_WIN32) && !defined(ICE_OS_WINRT) && !defined(__MINGW32__)
-# define HAS_STACK_TRACES
-#endif
namespace IceUtilInternal
{
@@ -41,32 +33,32 @@ public:
void first()
{
- _idx++;
- second();
+ _idx++;
+ second();
}
void second()
{
- _idx++;
- third();
+ _idx++;
+ third();
}
void third()
{
- _idx++;
- forth();
+ _idx++;
+ forth();
}
void forth()
{
- _idx++;
- fifth();
+ _idx++;
+ fifth();
}
void fifth()
{
- _idx++;
- throw IceUtil::NullHandleException(__FILE__, __LINE__);
+ _idx++;
+ throw IceUtil::NullHandleException(__FILE__, __LINE__);
}
private:
@@ -84,27 +76,27 @@ getIceHome()
string iceHome = (ret > 0 && ret < buf.size()) ? IceUtil::wstringToString(&buf[0]) : string("");
if(!iceHome.empty())
{
- return iceHome;
+ return iceHome;
}
else
{
- HKEY hKey;
-
- string key = string("SOFTWARE\\ZeroC\\Ice ") + ICE_STRING_VERSION;
- const wstring keyName = IceUtil::stringToWstring(key);
-
- if(RegOpenKeyExW(HKEY_LOCAL_MACHINE, keyName.c_str(), 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS)
- {
- return "";
- }
-
- WCHAR buf[512];
- DWORD bufSize = sizeof(buf);
- if(RegQueryValueExW(hKey, L"InstallDir", 0, NULL, (LPBYTE)buf, &bufSize) != ERROR_SUCCESS)
- {
- return "";
- }
- return IceUtil::wstringToString(wstring(buf));
+ HKEY hKey;
+
+ string key = string("SOFTWARE\\ZeroC\\Ice ") + ICE_STRING_VERSION;
+ const wstring keyName = IceUtil::stringToWstring(key);
+
+ if(RegOpenKeyExW(HKEY_LOCAL_MACHINE, keyName.c_str(), 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS)
+ {
+ return "";
+ }
+
+ WCHAR buf[512];
+ DWORD bufSize = sizeof(buf);
+ if(RegQueryValueExW(hKey, L"InstallDir", 0, NULL, (LPBYTE)buf, &bufSize) != ERROR_SUCCESS)
+ {
+ return "";
+ }
+ return IceUtil::wstringToString(wstring(buf));
}
}
#endif
@@ -122,8 +114,8 @@ standardizeVersion(string& str)
size_t pos = 0;
while((pos = str.find(v1, pos)) != string::npos)
{
- str.replace(pos, v1.length(), v2);
- pos += v2.length();
+ str.replace(pos, v1.length(), v2);
+ pos += v2.length();
}
}
#else
@@ -135,7 +127,7 @@ splitLines(const string& str)
string line;
while(std::getline(is, line))
{
- result.push_back(line);
+ result.push_back(line);
};
return result;
}
@@ -144,8 +136,6 @@ splitLines(const string& str)
int main(int argc, char* argv[])
{
-#ifdef HAS_STACK_TRACES
-
bool optimized = false;
#ifdef NDEBUG
optimized = true;
@@ -160,22 +150,22 @@ int main(int argc, char* argv[])
if(binDist)
{
- //
- // For Windows we only run the test against bindist if PDBs were installed
- //
- string pdb = getIceHome() + "\\bin\\icebox.pdb";
- if(!ifstream(pdb))
- {
- cout << "Test requires PDBs to be installed" << endl;
- return EXIT_SUCCESS;
- }
+ //
+ // For Windows we only run the test against bindist if PDBs were installed
+ //
+ string pdb = getIceHome() + "\\bin\\icebox.pdb";
+ if(!ifstream(pdb))
+ {
+ cout << "Test requires PDBs to be installed" << endl;
+ return EXIT_SUCCESS;
+ }
}
else if(optimized)
{
- //
- // Only support debug srcdist Windows builds
- //
- return EXIT_SUCCESS;
+ //
+ // Only support debug srcdist Windows builds
+ //
+ return EXIT_SUCCESS;
}
#endif
@@ -195,25 +185,25 @@ int main(int argc, char* argv[])
if(binDist && !optimized)
{
- filename += "debug-release";
+ filename += "debug-release";
}
else if(optimized)
#else
if(optimized)
#endif
{
- filename += "release";
+ filename += "release";
#if defined(_MSC_VER)
# if(_MSC_VER == 1800)
- filename += "-vc120";
+ filename += "-vc120";
# elif(_MSC_VER == 1900)
- filename += "-vc140";
+ filename += "-vc140";
# endif
#endif
}
else
{
- filename += "debug";
+ filename += "debug";
}
#if defined(_WIN32)
@@ -227,79 +217,79 @@ int main(int argc, char* argv[])
while(true)
{
#if defined(_WIN32) && defined(NDEBUG)
- bool match = true;
+ bool match = true;
#endif
- ifstream ifs(filename.c_str());
- stringstream sstr;
- sstr << ifs.rdbuf();
+ ifstream ifs(filename.c_str());
+ stringstream sstr;
+ sstr << ifs.rdbuf();
#if defined(__APPLE__)
- string expected = sstr.str();
- standardizeVersion(expected);
+ string expected = sstr.str();
+ standardizeVersion(expected);
#else
- vector<string> expected = splitLines(sstr.str());
+ vector<string> expected = splitLines(sstr.str());
#endif
- ThrowerPtr thrower = new Thrower();
- try
- {
- thrower->first();
- }
- catch(const IceUtil::Exception& ex)
- {
- string stack = ex.ice_stackTrace();
+ ThrowerPtr thrower = new Thrower();
+ try
+ {
+ thrower->first();
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ string stack = ex.ice_stackTrace();
+ // cerr << "\n full stack trace is \n" << stack << endl;
+
#ifdef __APPLE__
- standardizeVersion(stack);
- if(expected.size() < stack.size())
- {
- test(stack.compare(0, expected.size(), expected) == 0);
- }
- else
- {
- test(stack == expected);
- }
- break;
+ standardizeVersion(stack);
+ if(expected.size() < stack.size())
+ {
+ test(stack.compare(0, expected.size(), expected) == 0);
+ }
+ else
+ {
+ test(stack == expected);
+ }
+ break;
#else
- vector<string> actual = splitLines(stack);
- test(expected.size() <= actual.size());
- for(size_t i = 0; i < expected.size(); ++i)
- {
- if(actual[i].find(expected[i]) == string::npos)
- {
+ vector<string> actual = splitLines(stack);
+ test(expected.size() <= actual.size());
+ for(size_t i = 0; i < expected.size(); ++i)
+ {
+ if(actual[i].find(expected[i]) == string::npos)
+ {
#if defined(_WIN32) && defined(NDEBUG)
- match = false;
- //
- // With windows optimized builds retry with the alternate
- // expect file.
- //
- if(filename != "StackTrace.release.Win32")
- {
- break;
- }
- else
- {
- test(false);
- }
+ match = false;
+ //
+ // With windows optimized builds retry with the alternate
+ // expect file.
+ //
+ if(filename != "StackTrace.release.Win32")
+ {
+ break;
+ }
+ else
+ {
+ test(false);
+ }
#else
- test(false);
+ cerr << "could not find `" << expected[i] << "` in " << actual[i] << endl;
+ test(false);
#endif
- }
- }
+ }
+ }
#if defined(_WIN32) && defined(NDEBUG)
- if(!match && filename != "StackTrace.release.Win32")
- {
- filename = "StackTrace.release.Win32";
- continue;
- }
+ if(!match && filename != "StackTrace.release.Win32")
+ {
+ filename = "StackTrace.release.Win32";
+ continue;
+ }
#endif
- break;
+ break;
#endif
- }
+ }
}
cout << "ok" << endl;
-#else
- cout << "Test not supported on this platform" << endl;
-#endif
return EXIT_SUCCESS;
}
diff --git a/cpp/test/IceUtil/stacktrace/StackTrace.debug-release.OSX b/cpp/test/IceUtil/stacktrace/StackTrace.debug-release.OSX
index 334072652ae..8f02f6229d8 100644
--- a/cpp/test/IceUtil/stacktrace/StackTrace.debug-release.OSX
+++ b/cpp/test/IceUtil/stacktrace/StackTrace.debug-release.OSX
@@ -1,8 +1,8 @@
0 IceUtil::NullHandleException::NullHandleException(char const*, int) in libIceUtil.3.7a0.dylib
- 1 (anonymous namespace)::Thrower::fifth() in client
- 2 (anonymous namespace)::Thrower::forth() in client
- 3 (anonymous namespace)::Thrower::third() in client
- 4 (anonymous namespace)::Thrower::second() in client
- 5 (anonymous namespace)::Thrower::first() in client
- 6 main() in client
- 7 start() in libdyld.dylib \ No newline at end of file
+ 1 (anonymous namespace)::Thrower::fifth in client
+ 2 (anonymous namespace)::Thrower::forth in client
+ 3 (anonymous namespace)::Thrower::third in client
+ 4 (anonymous namespace)::Thrower::second in client
+ 5 (anonymous namespace)::Thrower::first in client
+ 6 main in client
+ 7 start in libdyld.dylib \ No newline at end of file
diff --git a/cpp/test/IceUtil/stacktrace/StackTrace.debug.Linux b/cpp/test/IceUtil/stacktrace/StackTrace.debug.Linux
index 5f6c0f19732..50a457a9437 100644
--- a/cpp/test/IceUtil/stacktrace/StackTrace.debug.Linux
+++ b/cpp/test/IceUtil/stacktrace/StackTrace.debug.Linux
@@ -1,9 +1,9 @@
- 0 IceUtil::Exception::Exception(char const*, int)
- 1 IceUtil::NullHandleException::NullHandleException(char const*, int)
-client
-client
-client
-client
-client
-client
- 8 __libc_start_main()
+ 0 IceUtil::Exception::Exception(char const*, int) at
+ 1 IceUtil::NullHandleException::NullHandleException(char const*, int) at
+ 2 fifth at
+ 3 forth at
+ 4 third at
+ 5 second at
+ 6 first at
+ 7 main at
+ 8
diff --git a/cpp/test/IceUtil/stacktrace/StackTrace.debug.OSX b/cpp/test/IceUtil/stacktrace/StackTrace.debug.OSX
index 5eeb56428ab..777bc5d8bf9 100644
--- a/cpp/test/IceUtil/stacktrace/StackTrace.debug.OSX
+++ b/cpp/test/IceUtil/stacktrace/StackTrace.debug.OSX
@@ -1,10 +1,10 @@
0 IceUtil::Exception::Exception(char const*, int) in libIceUtil.3.7a0.dylib
1 IceUtil::NullHandleException::NullHandleException(char const*, int) in libIceUtil.3.7a0.dylib
2 IceUtil::NullHandleException::NullHandleException(char const*, int) in libIceUtil.3.7a0.dylib
- 3 (anonymous namespace)::Thrower::fifth() in client
- 4 (anonymous namespace)::Thrower::forth() in client
- 5 (anonymous namespace)::Thrower::third() in client
- 6 (anonymous namespace)::Thrower::second() in client
- 7 (anonymous namespace)::Thrower::first() in client
- 8 main() in client
- 9 start() in libdyld.dylib \ No newline at end of file
+ 3 (anonymous namespace)::Thrower::fifth in client
+ 4 (anonymous namespace)::Thrower::forth in client
+ 5 (anonymous namespace)::Thrower::third in client
+ 6 (anonymous namespace)::Thrower::second in client
+ 7 (anonymous namespace)::Thrower::first in client
+ 8 main in client
+ 9 start in libdyld.dylib \ No newline at end of file
diff --git a/cpp/test/IceUtil/stacktrace/StackTrace.release.Linux b/cpp/test/IceUtil/stacktrace/StackTrace.release.Linux
index 3da3cc083ce..bb009c56c85 100644
--- a/cpp/test/IceUtil/stacktrace/StackTrace.release.Linux
+++ b/cpp/test/IceUtil/stacktrace/StackTrace.release.Linux
@@ -1,4 +1,4 @@
0 IceUtil::Exception::Exception(char const*, int)
1 IceUtil::NullHandleException::NullHandleException(char const*, int)
client
- 3 __libc_start_main()
+ 3 __libc_start_main
diff --git a/cpp/test/IceUtil/stacktrace/StackTrace.release.OSX b/cpp/test/IceUtil/stacktrace/StackTrace.release.OSX
index 4782f2d15e9..3bb0ce97ea5 100644
--- a/cpp/test/IceUtil/stacktrace/StackTrace.release.OSX
+++ b/cpp/test/IceUtil/stacktrace/StackTrace.release.OSX
@@ -1,3 +1,3 @@
0 IceUtil::NullHandleException::NullHandleException(char const*, int) in libIceUtil.3.7a0.dylib
- 1 main() in client
- 2 start() in libdyld.dylib \ No newline at end of file
+ 1 main in client
+ 2 start in libdyld.dylib \ No newline at end of file