diff --git a/src/base/kaldi-error.cc b/src/base/kaldi-error.cc index f5e83ad55..5ca884e99 100644 --- a/src/base/kaldi-error.cc +++ b/src/base/kaldi-error.cc @@ -1,5 +1,6 @@ // base/kaldi-error.cc +// Copyright 2016 Brno University of Technology (author: Karel Vesely) // Copyright 2009-2011 Microsoft Corporation; Lukas Burget; Ondrej Glembek // See ../../COPYING for clarification regarding multiple authors @@ -20,8 +21,8 @@ #ifdef HAVE_EXECINFO_H #include // To get stack trace in error messages. // If this #include fails there is an error in the Makefile, it does not -// support your platform well. Make sure HAVE_EXECINFO_H is undefined, and the -// code will compile. +// support your platform well. Make sure HAVE_EXECINFO_H is undefined, +// and the code will compile. #ifdef HAVE_CXXABI_H #include // For name demangling. // Useful to decode the stack trace, but only used if we have execinfo.h @@ -32,11 +33,13 @@ #include "base/kaldi-error.h" namespace kaldi { + +/***** GLOBAL VARIABLES FOR LOGGING *****/ + int32 g_kaldi_verbose_level = 0; const char *g_program_name = NULL; static LogHandler g_log_handler = NULL; - // If the program name was set (g_program_name != ""), the function // GetProgramName returns the program name (without the path) followed by a // colon, e.g. "gmm-align:". Otherwise it returns the empty string "". @@ -44,10 +47,13 @@ const char *GetProgramName() { return g_program_name == NULL ? "" : g_program_name; } + +/***** HELPER FUNCTIONS *****/ + // Given a filename like "/a/b/c/d/e/f.cc", GetShortFileName // returns "e/f.cc". Does not currently work if backslash is // the filename separator. -const char *GetShortFileName(const char *filename) { +static const char *GetShortFileName(const char *filename) { const char *last_slash = strrchr(filename, '/'); if (!last_slash) { return filename; @@ -58,115 +64,78 @@ const char *GetShortFileName(const char *filename) { } } + +/***** STACKTRACE *****/ + +static std::string Demangle(std::string trace_name) { #if defined(HAVE_CXXABI_H) && defined(HAVE_EXECINFO_H) -// The function name looks like a macro: it's a macro if we don't have ccxxabi.h -inline void KALDI_APPEND_POSSIBLY_DEMANGLED_STRING(const char *to_append, - std::string *ans) { - // at input the string "to_append" looks like: + // at input the string looks like: // ./kaldi-error-test(_ZN5kaldi13UnitTestErrorEv+0xb) [0x804965d] // We want to extract the name e.g. '_ZN5kaldi13UnitTestErrorEv", // demangle it and return it. - int32 status; - const char *paren = strchr(to_append, '('); - const char *plus = (paren ? strchr(paren, '+') : NULL); - if (!plus) { // did not find the '(' or did not find the '+' - // This is a soft failure in case we did not get what we expected. - ans->append(to_append); - return; + + // try to locate '(' and '+', take the string in between, + size_t begin(trace_name.find("(")), + end(trace_name.rfind("+")); + if (begin != std::string::npos && end != std::string::npos && begin < end) { + trace_name = trace_name.substr(begin+1,end-(begin+1)); } - std::string stripped(paren+1, plus-(paren+1)); // the bit between ( and +. - - char *demangled_name = abi::__cxa_demangle(stripped.c_str(), 0, 0, &status); - - // if status != 0 it is an error (demangling failure), but not all names seem - // to demangle, so we don't check it. - - if (demangled_name != NULL) { - ans->append(demangled_name); + // demangle, + int status; + char *demangled_name = abi::__cxa_demangle(trace_name.c_str(), 0, 0, &status); + std::string ans; + if (status == 0) { + ans = demangled_name; free(demangled_name); } else { - ans->append(to_append); // add the original string. + ans = trace_name; } + // return, + return ans; +#else + return trace_name; +#endif } -#else // defined(HAVE_CXXABI_H) && defined(HAVE_EXECINFO_H) -#define KALDI_APPEND_POSSIBLY_DEMANGLED_STRING(to_append, ans) \ - ans->append(to_append) -#endif // defined(HAVE_CXXABI_H) && defined(HAVE_EXECINFO_H) + +static std::string KaldiGetStackTrace() { + std::string ans; #ifdef HAVE_EXECINFO_H -std::string KaldiGetStackTrace() { #define KALDI_MAX_TRACE_SIZE 50 #define KALDI_MAX_TRACE_PRINT 20 // must be even. - std::string ans; - void *array[KALDI_MAX_TRACE_SIZE]; - size_t size = backtrace(array, KALDI_MAX_TRACE_SIZE); - char **strings = backtrace_symbols(array, size); + // buffer for the trace, + void *trace[KALDI_MAX_TRACE_SIZE]; + // get the trace, + size_t size = backtrace(trace, KALDI_MAX_TRACE_SIZE); + // get the trace symbols, + char **trace_symbol = backtrace_symbols(trace, size); + + // Compose the 'string', + ans += "[ Stack-Trace: ]\n"; if (size <= KALDI_MAX_TRACE_PRINT) { for (size_t i = 0; i < size; i++) { - KALDI_APPEND_POSSIBLY_DEMANGLED_STRING(strings[i], &ans); - ans += "\n"; + ans += Demangle(trace_symbol[i]) + "\n"; } } else { // print out first+last (e.g.) 5. for (size_t i = 0; i < KALDI_MAX_TRACE_PRINT/2; i++) { - KALDI_APPEND_POSSIBLY_DEMANGLED_STRING(strings[i], &ans); - ans += "\n"; + ans += Demangle(trace_symbol[i]) + "\n"; } ans += ".\n.\n.\n"; for (size_t i = size - KALDI_MAX_TRACE_PRINT/2; i < size; i++) { - KALDI_APPEND_POSSIBLY_DEMANGLED_STRING(strings[i], &ans); - ans += "\n"; + ans += Demangle(trace_symbol[i]) + "\n"; } if (size == KALDI_MAX_TRACE_SIZE) ans += ".\n.\n.\n"; // stack was too long, probably a bug. } - free(strings); // it's all in one big malloc()ed block. - -#ifdef HAVE_CXXABI_H // demangle the name, if possible. -#endif // HAVE_CXXABI_H + // cleanup, + free(trace_symbol); // it's okay, just the pointers, not the strings. +#endif // HAVE_EXECINFO_H return ans; } -#endif -void KaldiAssertFailure_(const char *func, const char *file, - int32 line, const char *cond_str) { - MessageLogger ml(LogMessageEnvelope::Error, func, file, line); - ml.stream() << "Assertion failed: " << cond_str; -#ifdef HAVE_EXECINFO_H - ml.stream() << "\nStack trace is:\n" << KaldiGetStackTrace(); -#endif -} -LogHandler SetLogHandler(LogHandler new_handler) { - LogHandler old_handler = g_log_handler; - g_log_handler = new_handler; - return old_handler; -} - -static void SendToLog(const LogMessageEnvelope &envelope, - const char *message) { - // Send to a logging handler if provided. - if (g_log_handler != NULL) { - g_log_handler(envelope, message); - return; - } - - // Otherwise, use Kaldi default logging. - std::stringstream header; - if (envelope.severity > LogMessageEnvelope::Info) - header << "VLOG[" << envelope.severity << "] ("; - else if (envelope.severity == LogMessageEnvelope::Info) - header << "LOG ("; - else if (envelope.severity == LogMessageEnvelope::Warning) - header << "WARNING ("; - else - header << "ERROR ("; - header << GetProgramName() << envelope.func << "():" - << envelope.file << ':' << envelope.line << ")"; - - std::string header_str = header.str(); - fprintf(stderr, "%s %s\n", header_str.c_str(), message); -} +/***** KALDI LOGIGNG *****/ MessageLogger::MessageLogger(LogMessageEnvelope::Severity severity, const char *func, const char *file, int32 line) { @@ -177,27 +146,99 @@ MessageLogger::MessageLogger(LogMessageEnvelope::Severity severity, envelope_.line = line; } + MessageLogger::~MessageLogger() KALDI_NOEXCEPT(false) { + // remove trailing '\n', std::string str = ss_.str(); while (!str.empty() && str[str.length() - 1] == '\n') str.resize(str.length() - 1); - SendToLog(envelope_, str.c_str()); - if (envelope_.severity > LogMessageEnvelope::Error) - return; + // print the mesage (or send to logging handler), + MessageLogger::HandleMessage(envelope_, str.c_str()); +} - // On error, throw an exception with the message, plus traceback info if - // available. - if (!std::uncaught_exception()) { -#ifdef HAVE_EXECINFO_H - throw std::runtime_error(str + "\n\n[stack trace: ]\n" + - KaldiGetStackTrace() + "\n"); -#else - throw std::runtime_error(str); -#endif + +void MessageLogger::HandleMessage(const LogMessageEnvelope &envelope, + const char *message) { + // Send to a logging handler if provided. + if (g_log_handler != NULL) { + g_log_handler(envelope, message); } else { - abort(); + // Otherwise, we use the default Kaldi logging. + // Build the log-message 'header', + std::stringstream header; + if (envelope.severity > LogMessageEnvelope::kInfo) { + header << "VLOG[" << envelope.severity << "] ("; + } else { + switch (envelope.severity) { + case LogMessageEnvelope::kInfo : + header << "LOG ("; + break; + case LogMessageEnvelope::kWarning : + header << "WARNING ("; + break; + case LogMessageEnvelope::kError : + header << "ERROR ("; + break; + case LogMessageEnvelope::kAssertFailed : + header << "ASSERTION_FAILED ("; + break; + default: + abort(); // coding errror (unknown 'severity'), + } + } + // fill the other info from the envelope, + header << GetProgramName() << envelope.func << "():" + << envelope.file << ':' << envelope.line << ")"; + + // Printing the message, + if (envelope.severity >= LogMessageEnvelope::kWarning) { + // VLOG, LOG, WARNING: + fprintf(stderr, "%s %s\n", header.str().c_str(), message); + } else { + // ERROR, ASSERT_FAILED (print with stack-trace): + fprintf(stderr, "%s %s\n\n%s\n", header.str().c_str(), message, + KaldiGetStackTrace().c_str()); + } + } + + // Should we throw exception, or abort? + switch (envelope.severity) { + case LogMessageEnvelope::kAssertFailed: + abort(); // ASSERT_FAILED, + break; + case LogMessageEnvelope::kError: + if (!std::uncaught_exception()) { + // throw exception with empty message, + throw std::runtime_error(""); // KALDI_ERR, + } else { + // If we got here, this thread has already thrown exception, + // and this exception has not yet arrived to its 'catch' clause... + // Throwing a new exception would be unsafe! + // (can happen during 'stack unwinding', if we have 'KALDI_ERR << msg' + // in a destructor of some local object). + abort(); + } + break; } } + +/***** KALDI ASSERTS *****/ + +void KaldiAssertFailure_(const char *func, const char *file, + int32 line, const char *cond_str) { + MessageLogger ml(LogMessageEnvelope::kAssertFailed, func, file, line); + ml.stream() << ": '" << cond_str << "' "; +} + + +/***** THIRD-PARTY LOG-HANDLER *****/ + +LogHandler SetLogHandler(LogHandler new_handler) { + LogHandler old_handler = g_log_handler; + g_log_handler = new_handler; + return old_handler; +} + } // end namespace kaldi diff --git a/src/base/kaldi-error.h b/src/base/kaldi-error.h index b76b69cc5..2911036d1 100644 --- a/src/base/kaldi-error.h +++ b/src/base/kaldi-error.h @@ -1,5 +1,6 @@ // base/kaldi-error.h +// Copyright 2016 Brno University of Technology (author: Karel Vesely) // Copyright 2009-2011 Microsoft Corporation; Ondrej Glembek; Lukas Burget; // Saarland University @@ -29,13 +30,15 @@ #include "base/kaldi-types.h" #include "base/kaldi-utils.h" - /* Important that this file does not depend on any other kaldi headers. */ +// By adding 'KALDI_NOEXCEPT(bool)' immediately after function declaration, +// we can tell the compiler that the function must-not produce +// exceptions (true), or may produce exceptions (false): #if _MSC_VER >= 1900 || (!defined(_MSC_VER) && __cplusplus >= 201103L) #define KALDI_NOEXCEPT(Predicate) noexcept((Predicate)) #elif defined(__GXX_EXPERIMENTAL_CXX0X__) && \ - (__GNUC__ >= 4 && __GNUC_MINOR__ >= 6) + (__GNUC__ >= 4 && __GNUC_MINOR__ >= 6) #define KALDI_NOEXCEPT(Predicate) noexcept((Predicate)) #else #define KALDI_NOEXCEPT(Predicate) @@ -50,7 +53,9 @@ namespace kaldi { /// \addtogroup error_group /// @{ -/// This is set by util/parse-options.{h, cc} if you set --verbose = ? option. +/***** VERBOSITY LEVEL *****/ + +/// This is set by util/parse-options.{h, cc} if you set --verbose=? option. extern int32 g_kaldi_verbose_level; /// This is set by util/parse-options.{h, cc} (from argv[0]) and used (if set) @@ -66,12 +71,16 @@ inline int32 GetVerboseLevel() { return g_kaldi_verbose_level; } /// automatically from ParseOptions. inline void SetVerboseLevel(int32 i) { g_kaldi_verbose_level = i; } + +/***** KALDI LOGGING *****/ + /// Log message severity and source location info. struct LogMessageEnvelope { enum Severity { - Error = -2, - Warning = -1, - Info = 0, + kAssertFailed = -3, + kError = -2, + kWarning = -1, + kInfo = 0, }; // An 'enum Severity' value, or a positive number indicating verbosity level. int severity; @@ -80,36 +89,59 @@ struct LogMessageEnvelope { int32 line; }; -/// Type of user-provided logging function. -typedef void (*LogHandler)(const LogMessageEnvelope &envelope, - const char *message); - -/// Set logging handler. If called with a non-NULL function pointer, the -/// function pointed by it is called to send messages to a caller-provided -/// log. If called with NULL pointer, restores default Kaldi error logging to -/// stderr. SetLogHandler is obviously not thread safe. -LogHandler SetLogHandler(LogHandler); - -// Class MessageLogger is invoked from the KALDI_ERR, KALDI_WARN, KALDI_LOG and +// Class MessageLogger is invoked from the KALDI_ASSERT, KALDI_ERR, KALDI_WARN and // KALDI_LOG macros. It formats the message, then either prints it to stderr or // passes to the log custom handler if provided, then, in case of the error, -// throws an std::runtime_exception. +// throws an std::runtime_exception, in case of failed KALDI_ASSERT calls abort(). // -// Note: we avoid using std::cerr, since it does not guarantee thread safety -// in general, until C++11; even then, in "cerr << a << b", other thread's -// output is allowed to intrude between a and b. fprintf(stderr,...) is -// guaranteed thread-safe, and outputs its formatted string atomically. +// Note: we avoid using std::cerr for thread safety issues. +// fprintf(stderr,...) is guaranteed thread-safe, and outputs +// its formatted string atomically. class MessageLogger { public: - MessageLogger(LogMessageEnvelope::Severity severity, const char *func, - const char *file, int32 line); + /// Constructor stores the info, + MessageLogger(LogMessageEnvelope::Severity severity, + const char *func, + const char *file, + int32 line); + + /// Destructor, calls 'HandleMessage' which prints the message, + /// (since C++11 a 'throwing' destructor must be declared 'noexcept(false)') ~MessageLogger() KALDI_NOEXCEPT(false); + + /// The hook for the 'insertion operator', e.g. + /// 'KALDI_LOG << "Message,"', inline std::ostream &stream() { return ss_; } + +private: + /// The logging function, + static void HandleMessage(const LogMessageEnvelope &env, const char *msg); + private: LogMessageEnvelope envelope_; std::ostringstream ss_; }; +// The definition of the logging macros, +#define KALDI_ERR \ + ::kaldi::MessageLogger(::kaldi::LogMessageEnvelope::kError, \ + __func__, __FILE__, __LINE__).stream() +#define KALDI_WARN \ + ::kaldi::MessageLogger(::kaldi::LogMessageEnvelope::kWarning, \ + __func__, __FILE__, __LINE__).stream() +#define KALDI_LOG \ + ::kaldi::MessageLogger(::kaldi::LogMessageEnvelope::kInfo, \ + __func__, __FILE__, __LINE__).stream() +#define KALDI_VLOG(v) if ((v) <= ::kaldi::g_kaldi_verbose_level) \ + ::kaldi::MessageLogger((::kaldi::LogMessageEnvelope::Severity)(v), \ + __func__, __FILE__, __LINE__).stream() + + +/***** KALDI ASSERTS *****/ + +void KaldiAssertFailure_(const char *func, const char *file, + int32 line, const char *cond_str); + // Note on KALDI_ASSERT and KALDI_PARANOID_ASSERT // The original (simple) version of the code was this // @@ -138,7 +170,7 @@ private: #else #define KALDI_ASSERT(cond) (void)0 #endif -// also see KALDI_COMPILE_TIME_ASSERT, defined in base/kaldi-utils.h, +// Also see KALDI_COMPILE_TIME_ASSERT, defined in base/kaldi-utils.h, // and KALDI_ASSERT_IS_INTEGER_TYPE and KALDI_ASSERT_IS_FLOATING_TYPE, // also defined there. // some more expensive asserts only checked if this defined @@ -150,25 +182,17 @@ private: #endif -#define KALDI_ERR \ - ::kaldi::MessageLogger(::kaldi::LogMessageEnvelope::Error, \ - __func__, __FILE__, __LINE__).stream() -#define KALDI_WARN \ - ::kaldi::MessageLogger(::kaldi::LogMessageEnvelope::Warning, \ - __func__, __FILE__, __LINE__).stream() -#define KALDI_LOG \ - ::kaldi::MessageLogger(::kaldi::LogMessageEnvelope::Info, \ - __func__, __FILE__, __LINE__).stream() -#define KALDI_VLOG(v) if ((v) <= ::kaldi::g_kaldi_verbose_level) \ - ::kaldi::MessageLogger((::kaldi::LogMessageEnvelope::Severity)(v), \ - __func__, __FILE__, __LINE__).stream() +/***** THIRD-PARTY LOG-HANDLER *****/ -inline bool IsKaldiError(const std::string &str) { - return(!strncmp(str.c_str(), "ERROR ", 6)); -} +/// Type of third-party logging function, +typedef void (*LogHandler)(const LogMessageEnvelope &envelope, + const char *message); -void KaldiAssertFailure_(const char *func, const char *file, - int32 line, const char *cond_str); +/// Set logging handler. If called with a non-NULL function pointer, the +/// function pointed by it is called to send messages to a caller-provided +/// log. If called with NULL pointer, restores default Kaldi error logging to +/// stderr. SetLogHandler is obviously not thread safe. +LogHandler SetLogHandler(LogHandler); /// @} end "addtogroup error_group" diff --git a/src/feat/wave-reader.h b/src/feat/wave-reader.h index 963e0e5e0..0749022f7 100644 --- a/src/feat/wave-reader.h +++ b/src/feat/wave-reader.h @@ -135,8 +135,8 @@ class WaveHolder { t.Write(os); // throws exception on failure. return true; } catch (const std::exception &e) { - KALDI_WARN << "Exception caught in WaveHolder object (writing)."; - if (!IsKaldiError(e.what())) { std::cerr << e.what(); } + KALDI_WARN << "Exception caught in WaveHolder object (writing). " + << e.what(); return false; // write failure. } } @@ -162,8 +162,8 @@ class WaveHolder { t_.Read(is); // throws exception on failure. return true; } catch (const std::exception &e) { - KALDI_WARN << "Exception caught in WaveHolder object (reading)."; - if (!IsKaldiError(e.what())) { std::cerr << e.what(); } + KALDI_WARN << "Exception caught in WaveHolder object (reading). " + << e.what(); return false; // write failure. } } @@ -213,8 +213,8 @@ class WaveInfoHolder { t_.Read(is, WaveData::kLeaveDataUndefined); // throws exception on failure. return true; } catch (const std::exception &e) { - KALDI_WARN << "Exception caught in WaveHolder object (reading)."; - if (!IsKaldiError(e.what())) { std::cerr << e.what(); } + KALDI_WARN << "Exception caught in WaveHolder object (reading). " + << e.what(); return false; // write failure. } } diff --git a/src/hmm/posterior.cc b/src/hmm/posterior.cc index 4e5cbd452..66965ad8d 100644 --- a/src/hmm/posterior.cc +++ b/src/hmm/posterior.cc @@ -129,8 +129,7 @@ bool PosteriorHolder::Write(std::ostream &os, bool binary, const T &t) { WritePosterior(os, binary, t); return true; } catch(const std::exception &e) { - KALDI_WARN << "Exception caught writing table of posteriors"; - if (!IsKaldiError(e.what())) { std::cerr << e.what(); } + KALDI_WARN << "Exception caught writing table of posteriors. " << e.what(); return false; // Write failure. } } @@ -147,8 +146,7 @@ bool PosteriorHolder::Read(std::istream &is) { ReadPosterior(is, is_binary, &t_); return true; } catch (std::exception &e) { - KALDI_WARN << "Exception caught reading table of posteriors"; - if (!IsKaldiError(e.what())) { std::cerr << e.what(); } + KALDI_WARN << "Exception caught reading table of posteriors. " << e.what(); t_.clear(); return false; } @@ -174,8 +172,7 @@ bool GaussPostHolder::Write(std::ostream &os, bool binary, const T &t) { if(!binary) os << '\n'; return os.good(); } catch (const std::exception &e) { - KALDI_WARN << "Exception caught writing table of posteriors"; - if (!IsKaldiError(e.what())) { std::cerr << e.what(); } + KALDI_WARN << "Exception caught writing table of posteriors. " << e.what(); return false; // Write failure. } } @@ -210,8 +207,7 @@ bool GaussPostHolder::Read(std::istream &is) { } return true; } catch (std::exception &e) { - KALDI_WARN << "Exception caught reading table of posteriors"; - if (!IsKaldiError(e.what())) { std::cerr << e.what(); } + KALDI_WARN << "Exception caught reading table of posteriors. " << e.what(); t_.clear(); return false; } diff --git a/src/util/kaldi-holder-inl.h b/src/util/kaldi-holder-inl.h index 2fc89409c..4297af9a2 100644 --- a/src/util/kaldi-holder-inl.h +++ b/src/util/kaldi-holder-inl.h @@ -52,8 +52,7 @@ template class KaldiObjectHolder { t.Write(os, binary); return os.good(); } catch(const std::exception &e) { - KALDI_WARN << "Exception caught writing Table object: " << e.what(); - if (!IsKaldiError(e.what())) { std::cerr << e.what(); } + KALDI_WARN << "Exception caught writing Table object. " << e.what(); return false; // Write failure. } } @@ -80,8 +79,7 @@ template class KaldiObjectHolder { t_->Read(is, is_binary); return true; } catch(const std::exception &e) { - KALDI_WARN << "Exception caught reading Table object "; - if (!IsKaldiError(e.what())) { std::cerr << e.what(); } + KALDI_WARN << "Exception caught reading Table object. " << e.what(); delete t_; t_ = NULL; return false; @@ -137,8 +135,7 @@ template class BasicHolder { // easier to manipulate. return os.good(); } catch(const std::exception &e) { - KALDI_WARN << "Exception caught writing Table object: " << e.what(); - if (!IsKaldiError(e.what())) { std::cerr << e.what(); } + KALDI_WARN << "Exception caught writing Table object. " << e.what(); return false; // Write failure. } } @@ -186,8 +183,7 @@ template class BasicHolder { } return true; } catch(const std::exception &e) { - KALDI_WARN << "Exception caught reading Table object"; - if (!IsKaldiError(e.what())) { std::cerr << e.what(); } + KALDI_WARN << "Exception caught reading Table object. " << e.what(); return false; } } @@ -252,8 +248,8 @@ template class BasicVectorHolder { } return os.good(); } catch(const std::exception &e) { - KALDI_WARN << "Exception caught writing Table object (BasicVector). "; - if (!IsKaldiError(e.what())) { std::cerr << e.what(); } + KALDI_WARN << "Exception caught writing Table object (BasicVector). " + << e.what(); return false; // Write failure. } } @@ -290,8 +286,7 @@ template class BasicVectorHolder { return true; } catch(const std::exception &e) { KALDI_WARN << "BasicVectorHolder::Read, could not interpret line: " - << line; - if (!IsKaldiError(e.what())) { std::cerr << e.what(); } + << "'" << line << "'" << "\n" << e.what(); return false; } } else { // binary mode. @@ -390,8 +385,7 @@ template class BasicVectorVectorHolder { } return os.good(); } catch(const std::exception &e) { - KALDI_WARN << "Exception caught writing Table object. "; - if (!IsKaldiError(e.what())) { std::cerr << e.what(); } + KALDI_WARN << "Exception caught writing Table object. " << e.what(); return false; // Write failure. } } @@ -436,8 +430,7 @@ template class BasicVectorVectorHolder { } } } catch(const std::exception &e) { - KALDI_WARN << "BasicVectorVectorHolder::Read, read error"; - if (!IsKaldiError(e.what())) { std::cerr << e.what(); } + KALDI_WARN << "BasicVectorVectorHolder::Read, read error. " << e.what(); return false; } } else { // binary mode. @@ -532,8 +525,7 @@ template class BasicPairVectorHolder { } return os.good(); } catch(const std::exception &e) { - KALDI_WARN << "Exception caught writing Table object. "; - if (!IsKaldiError(e.what())) { std::cerr << e.what(); } + KALDI_WARN << "Exception caught writing Table object. " << e.what(); return false; // Write failure. } } @@ -589,8 +581,7 @@ template class BasicPairVectorHolder { } } } catch(const std::exception &e) { - KALDI_WARN << "BasicPairVectorHolder::Read, read error"; - if (!IsKaldiError(e.what())) { std::cerr << e.what(); } + KALDI_WARN << "BasicPairVectorHolder::Read, read error. " << e.what(); return false; } } else { // binary mode.