-
Notifications
You must be signed in to change notification settings - Fork 5.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base/kaldi_error : the error messages are no longer printed 2x #755
Conversation
- e.what() contains stackttrace or is empty string - we should also consider changing: 'std::cerr << e.what();' -> 'fprintf(stderr, e.what().c_str());' - fprintf is thread-safe and it is better not to mix 'std::cerr' and 'stderr', and 'stderr' is already used for logging...
I guess this makes sense. I'll wait for Kirill or others to comment though- I'm in no hurry to commit this, like, today, as it would be a big change. Regarding substituting std::cerr -> fprintf, I'd rather not do this as it might lead to git merging hassles for others, and it just seems to me that it's more of a theoretical than a practical problem at this point [especially since at exit there will be only 1 thread.] |
There's one more thing which is not logical. If a binary crashes on KALDI_ASSERT, the stacktrace is printed 2x, while both traces are little different. I propose to remove the 'stacktrace' print from the KALDI_ASSERT macro. KALDI_ASSERT generates a call of KALDI_ERR, and KALDI_ERR should be the only place where 'stacktrace' is generated. Thanks! |
Oh. I see now that a failed KALDI_ASSERT does have the same effect as calling It's possible in principle to add another macro KALDI_FATAL, that would It would be good if you can show us an example of how the stack traces are Dan On Fri, May 6, 2016 at 8:44 AM, Karel Vesely notifications@github.com
|
It probably would be better to have the stack traces printed at the point where the error happens, rather than when it's caught. |
OK, I just noticed something. There are quite a few parts of the code that attempt to do something with the error string in the exception. The following are just a small subset: grep 'e.what()' /.{h,cc} | grep -v '//' | grep -v 'bin/' However, most of this code seems intended to print the error if it wasn't already printed, e.g. like
so if it was e.g. std::bad_alloc it would get printed. Other instances of this are just redundant, e.g.: so it will be printed twice if it wasn't a Kaldi error. Anyway, I'm just pointing out that if we stop including the string in the exception, that code may need to be changed (and possibly simplified). |
Hi, The difference of the stacktraces is small, i.e. only the last level is different, once context comes from the KALDI_ASSERT and second time from the KALDI_ERR. But there is no real reason to show the stack-trace 2x (I already deleted the log). Concerning the cases like 'Cholesky' failure, it might be interesting to define some custom exception, say 'CholeskyNumericException' derived from std::runtime_error and pass it to KALDI_ERR macro as an argument. I can make a toy example to prove that can be done. The final code would look like this: As it is now, the macro without an argument would simply produce the std::runtime_error : What do you think of it? |
Hi, in the end, the specific exceptions to be passed through KALDI_ERR are not easily doable. The macros cannot be redefined, 2nd with 'Variadic macros' we could do: But this is not what we really need. We could define KALDI_EXCEPT(...) but this would be similar story to 'KALDI_FATAL', the new extension would confuse people who are used to the old version. |
Okay, Kirill probably needs to get the ASSERT_FAILED message to the Logger handler. So we can define a new severity 'AssertFailed' with ordinal value -3, let the log-print happen and call abort(). For the KALDI_ERR the whole message will go through the e.what(), while it will also be forwarded to the Kirills Logger. Btw, Are there many people using that Logger thing? Is it something like a standard interface? |
Hm, that's not really what I was saying.. The exceptions do not need to contain the message-- I was just pointing out In fact, it is better to have the error message printed in the logger-class I think adding a new severity is the right way to ensure that Regarding the error messages raised from Cholesky, that are caught-- I Dan On Mon, May 9, 2016 at 10:39 AM, Karel Vesely notifications@github.com
|
- some TODO's are to be decided: - Can we remove the: 'IsKaldiError()'? (It's very 'dirty' function. And it's used only in the table-I/O to suppress printing 'what' messages from KALDI_ERR. IMHO, it may not be a good idea to suppress this.) - With Kirill's log-handler, the log is sent and then there's no abort() for errors/asserts (seems like a bad idea, but it is the way it worked previously).
Hi, could you please take a look at the updated code?
It is simplified and more logically structured. I already tested the 'KALDI_ERR', 'KALDI_ASSERT' and 'KALDI_LOG', Cheers, K. |
// 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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please don't indent the #ifdefs, I couldn't find any example in the Google C++ style guide of doing this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay. Well, it is not strictly against the Google style:
https://google.github.io/styleguide/cppguide.html#Preprocessor_Macros
Indents make the macros more readable, but I can put it back as it was if it is an issue...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not specifically forbidden in that text, but I've never seen code like
this elsewhere in Google stuff or in Kaldi-- please put it back.
On Tue, May 10, 2016 at 1:42 PM, Karel Vesely notifications@github.com
wrote:
In src/base/kaldi-error.cc
#755 (comment):@@ -18,156 +19,122 @@
// limitations under the License.#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.
-#ifdef HAVE_CXXABI_H
-#include <cxxabi.h> // For name demangling.
-// Useful to decode the stack trace, but only used if we have execinfo.h
-#endif // HAVE_CXXABI_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.
- #ifdef HAVE_CXXABI_H
- #include <cxxabi.h> // For name demangling.
Okay. Well, it is not strictly against the Google style:
https://google.github.io/styleguide/cppguide.html#Preprocessor_MacrosIndents make the macros more readable, but I can put it back as it was if
it is an issue...—
You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub
https://github.com/kaldi-asr/kaldi/pull/755/files/24bef8dcb4c501a59324debcafd9dcd426bfde23#r62717661
Integrated the comments from Dan. |
It looks good to me now. |
Hi, it might be a good time to merge this... |
Would you mind changing the enum variables to start with a k, like kError, kWarning, etc.? I know this was Kirill's code... the Google style guide now mandates this style for enums (or all upper-case). |
Sure, the 'k' is added to the enum. I'll also send an email to Kirill @kkm000 , so he knows the API is little different now. |
Thanks for paging me in. I am totally fine with adding another enum value. I am not using stack traces in the messages, but I think it might make sense to keep them if available. Getting rid of
I did not intend it to work this way. If it does, it's a bug I introduced. Errors and assets should be fatal, Kaldi is just coded this way. |
Karel, I had static void SendToLog(const LogMessageEnvelope &envelope, ... {
// Send to a logging handler if provided.
if (g_log_handler != NULL) {
g_log_handler(envelope, message);
return;
}
// Otherwise, use Kaldi default logging.
...
} and then MessageLogger::~MessageLogger() ... {
SendToLog(envelope_, str.c_str());
if (envelope_.severity > LogMessageEnvelope::Error)
return;
// On error, throw an exception with the message, plus traceback info if available.
if (!std::uncaught_exception()) {
. . . The new code changed that, so that aborting does not happen if custom error logger is installed. Is this really intended? It can be argued that this behavior has its merit, but we must decide on one or the other. To me, it is way too unsafe to allow the handler to return and continue after KALDI_ERROR -- most code assumes errors/asserts are not continuable. Also, it will break the table handlers that rely on |
Hi, I see, from the code it was not clearly obvious that the 'return' in the 'SendToLog' was followed by throwing the exception in the ~MessageLogger. Okay, let's do the aborting on asserts and errors when custom log handler is used... Thanks for the info! K. |
I am wondering if there is much point now in having |
Hm. We might be able to just take one element off the stack trace. Regarding the behavior of errors and asserts, it needs to be precisely as
Quite a lot of code assumes that error throws an exception, there are cases Dan On Tue, May 17, 2016 at 2:42 PM, Kirill Katsnelson <notifications@github.com
|
That's what I read in the latest Karel's code. |
I was thinking of the |
OK- it looks good to me now. Karel, are you running any experiments right now? |
Hi, I tried to cause an error, a failed assert and to run the 'rm' recipe up to sgmm2. All looks normal... Should I try something more? |
OK that sounds enough. I'll merge now. On Wed, May 18, 2016 at 11:33 AM, Karel Vesely notifications@github.com
|
IsKaldiError function was removed from Kaldi. See kaldi-asr/kaldi#755
'std::cerr << e.what();' -> 'fprintf(stderr, e.what().c_str());'
'stderr', and 'stderr' is already used for logging...