Merge pull request #755 from vesis84/error_logs

base/kaldi_error : the error messages are no longer printed 2x
This commit is contained in:
Daniel Povey 2016-05-18 14:58:30 -04:00
Родитель 26ef88fed9 1449a9d021
Коммит ea7f04b244
5 изменённых файлов: 224 добавлений и 172 удалений

Просмотреть файл

@ -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 <execinfo.h> // 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 <cxxabi.h> // 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

Просмотреть файл

@ -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"

Просмотреть файл

@ -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.
}
}

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -52,8 +52,7 @@ template<class KaldiType> 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 KaldiType> 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 BasicType> 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 BasicType> 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 BasicType> 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 BasicType> 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 BasicType> 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 BasicType> 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 BasicType> 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 BasicType> 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.