From 3f00eb29183b6d40a886fab56dbc66bc88afdef2 Mon Sep 17 00:00:00 2001 From: Federico Montesino Pouzols Date: Thu, 22 Jan 2015 16:44:26 +0000 Subject: [PATCH] more verbose excepts, handle sigsegv (happens on windows), re #5805 --- .../Framework/DataHandling/src/Load.cpp | 13 +++++++- .../Framework/Kernel/src/NexusDescriptor.cpp | 31 ++++++++++++++++++- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/Code/Mantid/Framework/DataHandling/src/Load.cpp b/Code/Mantid/Framework/DataHandling/src/Load.cpp index 44032ee061b4..5fb9ec28447f 100644 --- a/Code/Mantid/Framework/DataHandling/src/Load.cpp +++ b/Code/Mantid/Framework/DataHandling/src/Load.cpp @@ -127,7 +127,18 @@ void Load::setPropertyValue(const std::string &name, const std::string &value) { flattenVecOfVec(getProperty("Filename")); // If it's a single file load, then it's fine to change loader. if (fileNames.size() == 1) { - IAlgorithm_sptr loader = getFileLoader(getPropertyValue(name)); + IAlgorithm_sptr loader; + try { + loader = getFileLoader(getPropertyValue(name)); + } catch(std::exception& e) { + g_log.error() << std::string("It seems that this file contains errors " + "or is not well supported. Severe issue " + "found when trying to find an algorithm " + "that is able to load: '" + name +"'.\n " + "Please check that the file is a supported" + "type and is not corrupted: ") + e.what(); + throw e; + } assert(loader); // (getFileLoader should throw if no loader is found.) declareLoaderProperties(loader); } diff --git a/Code/Mantid/Framework/Kernel/src/NexusDescriptor.cpp b/Code/Mantid/Framework/Kernel/src/NexusDescriptor.cpp index 7f020c9e1aa0..55435660aa1e 100644 --- a/Code/Mantid/Framework/Kernel/src/NexusDescriptor.cpp +++ b/Code/Mantid/Framework/Kernel/src/NexusDescriptor.cpp @@ -8,6 +8,7 @@ #include #include +#include namespace Mantid { namespace Kernel { @@ -26,6 +27,13 @@ size_t NexusDescriptor::HDF5SignatureSize = 8; const unsigned char NexusDescriptor::HDF5Signature[8] = { 137, 'H', 'D', 'F', '\r', '\n', '\032', '\n'}; +/// a signal handler for potential libNeXus SIGSEGVs +static void segvSignalHandler(int signal) +{ + if (SIGSEGV == signal) + throw std::runtime_error("SIGSEGV - severe issue: memory access violation!"); +} + namespace { //--------------------------------------------------------------------------------------------------------------------------- // Anonymous helper methods to use isHDF methods to use an open file handle @@ -119,11 +127,22 @@ NexusDescriptor::NexusDescriptor(const std::string &filename) throw std::invalid_argument("NexusDescriptor() - File '" + filename + "' does not exist"); } + + // be ready for potential SIGSEGV in libNeXus + void (*prevHandler)(int) = signal(SIGSEGV, segvSignalHandler); try { initialize(filename); + signal(SIGSEGV, prevHandler); } catch (::NeXus::Exception &) { throw std::invalid_argument("NexusDescriptor::initialize - File '" + filename + "' does not look like a HDF file."); + signal(SIGSEGV, prevHandler); + } catch (...) { + // this probably comes with a memory violation + throw std::runtime_error("NexusDescriptor::initialize - File '" + + filename + "' in principle looks like a HDF " + "file but an unexpected issue was found and " + "it cannot be loaded as such."); } } @@ -237,7 +256,17 @@ void NexusDescriptor::walkFile(::NeXus::File &file, const std::string &rootPath, } } - auto dirents = file.getEntries(); + // getEntries from libNeXus can segfault on bad files, see example + // in ticket #5805 + std::map dirents; + try { + dirents = file.getEntries(); + } catch(std::exception& e) { + throw std::runtime_error(std::string(e.what()) + + "Severe failure while trying to get NeXus entries " + "from file. Cannot continue."); + } + auto itend = dirents.end(); for (auto it = dirents.begin(); it != itend; ++it) { const std::string &entryName = it->first;