diff --git a/cpp/src/Ice/Exception.cpp b/cpp/src/Ice/Exception.cpp index 5ec544cb4bc..df23a5f4e73 100644 --- a/cpp/src/Ice/Exception.cpp +++ b/cpp/src/Ice/Exception.cpp @@ -477,6 +477,7 @@ Ice::Exception::ice_enableStackTraceCollection() if (!SymRefreshModuleList(process)) { // TODO: SymRefreshModuleList occasionally fails with error code 3221225476; we retry once in this case. + // Note that calling GetLastError() does not reset the last error. if (GetLastError() != 3221225476 || !SymRefreshModuleList(process)) { throw std::runtime_error{ diff --git a/cpp/src/Ice/Instance.cpp b/cpp/src/Ice/Instance.cpp index 49153fa7963..caa23a5cb72 100644 --- a/cpp/src/Ice/Instance.cpp +++ b/cpp/src/Ice/Instance.cpp @@ -103,15 +103,27 @@ namespace } } - inline bool printStackTraces(const PropertiesPtr& properties) + void checkPrintStackTraces(const InitializationData& initData) { #ifdef NDEBUG // Release build - return properties->getIcePropertyAsInt("Ice.PrintStackTraces") > 0; + if (initData.properties->getIcePropertyAsInt("Ice.PrintStackTraces") > 0) #else // Debug build - return properties->getPropertyAsIntWithDefault("Ice.PrintStackTraces", 1); + if (initData.properties->getPropertyAsIntWithDefault("Ice.PrintStackTraces", 1)) #endif + { + try + { + Exception::ice_enableStackTraceCollection(); + } + catch (const std::exception& ex) + { + Warning out(initData.logger); + out << "Cannot enable stack trace collection:\n" << ex; + out << "\nYou can turn off this warning by setting Ice.PrintStackTraces=0"; + } + } } class Init @@ -1060,10 +1072,7 @@ IceInternal::Instance::initialize(const Ice::CommunicatorPtr& communicator) assert(_initData.logger); // This affects the entire process. - if (printStackTraces(_initData.properties)) - { - Exception::ice_enableStackTraceCollection(); - } + checkPrintStackTraces(_initData); const_cast(_traceLevels) = make_shared(_initData.properties); @@ -1344,9 +1353,9 @@ IceInternal::Instance::finishSetup(int& argc, const char* argv[], const Ice::Com // On Windows, if we loaded any plugin and stack trace collection is enabled, we need to call // ice_enableStackTraceCollection() again to refresh the module list. This refresh is fairly slow so we make it only // when necessary. Extra calls to ice_enableStackTraceCollection() are no-op on other platforms. - if (libraryLoaded && printStackTraces(_initData.properties)) + if (libraryLoaded) { - Exception::ice_enableStackTraceCollection(); + checkPrintStackTraces(_initData); } // diff --git a/cpp/src/IceBox/ServiceManagerI.cpp b/cpp/src/IceBox/ServiceManagerI.cpp index cdb52a3ffa6..5cfbfa717ce 100644 --- a/cpp/src/IceBox/ServiceManagerI.cpp +++ b/cpp/src/IceBox/ServiceManagerI.cpp @@ -440,7 +440,16 @@ IceBox::ServiceManagerI::start() // Refresh module list after loading dynamic libraries if stack trace collection is enabled. if (printStackTraces(_communicator->getProperties())) { - Exception::ice_enableStackTraceCollection(); + try + { + Exception::ice_enableStackTraceCollection(); + } + catch (const std::exception& ex) + { + Warning out(_communicator->getLogger()); + out << "Cannot enable/refresh stack trace collection:\n" << ex; + out << "\nYou can turn off this warning by setting Ice.PrintStackTraces=0"; + } } //