-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
Custom InstallFailureFunction does not prevent exit #249
Comments
The noreturn attribute applied to the interfaces of Since the problem is in the API, it's possible to One of the tricky bits is that Lines 85 to 92 in 7f91846
All of these changes could be done without modifying glog. It would be nice if there was cleaner solution for not calling |
Just to revise the previous comment. It's safe to There are multiple issues in the current implementation.
|
@sergiud What was the solution here? |
Indeed there is no good solution to this. It is a problem for us, certainly affects many others too, and a strong case for not using glog. @sergiud I believe this issue should be reopened. |
@sarlinpe Why do you believe there is no good solution to this? At least in @oliverdain's case, marking the |
You are right, it was only a bit more work: namespace google {
template <typename T>
class LogMessageFatalThrow : public LogMessage {
public:
LogMessageFatalThrow(const char* file, int line)
: LogMessage(file, line, GLOG_ERROR, &message_) {};
LogMessageFatalThrow(const char* file, int line, std::string* message)
: LogMessage(file, line, GLOG_ERROR, message), message_(*message) {};
LogMessageFatalThrow(const char* file, int line, const CheckOpString& result)
: LogMessage(file, line, GLOG_ERROR, &message_) {
stream() << "Check failed: " << (*result.str_) << " ";
// On LOG(FATAL) glog does not bother cleaning up CheckOpString so we do so here.
delete result.str_;
};
[[noreturn]] ~LogMessageFatalThrow() noexcept(false) {
Flush();
throw T(message_);
};
private:
std::string message_;
};
using LogMessageFatalThrowDefault = LogMessageFatalThrow<std::invalid_argument>;
template <typename T>
T ThrowCheckNotNull(const char* file, int line, const char* names, T&& t) {
if (t == nullptr) {
LogMessageFatalThrowDefault(file, line, new std::string(names));
}
return std::forward<T>(t);
}
} // namespace google
#undef COMPACT_GOOGLE_LOG_FATAL
#define COMPACT_GOOGLE_LOG_FATAL \
google::LogMessageFatalThrowDefault(__FILE__, __LINE__)
#undef LOG_TO_STRING_FATAL
#define LOG_TO_STRING_FATAL(message) \
google::LogMessageFatalThrowDefault(__FILE__, __LINE__, message)
#define LOG_FATAL_CUSTOM(exception) \
google::LogMessageFatalThrow<exception>(__FILE__, __LINE__).stream()
#undef CHECK_OP
#define CHECK_OP(name, op, val1, val2) \
CHECK_OP_LOG(name, op, val1, val2, google::LogMessageFatalThrowDefault)
#undef CHECK_NOTNULL
#define CHECK_NOTNULL(val) \
google::ThrowCheckNotNull( \
__FILE__, __LINE__, "'" #val "' Must be non NULL", (val)) I am happy to contribute this back if it is useful, for example as documentation. Still, I do believe that glog could make this kind of extension a little easier, e.g. with a macro |
Is there a reason there's a new class for this purpose? Can't we reuse |
If I understand you correctly, you are suggesting this: class LogMessageFatalThrow : public LogMessageFatal {
using LogMessageFatal::LogMessageFatal;
public:
~LogMessageFatalThrow() noexcept(false) {};
};
void ThrowingFailureFunction() {
throw std::invalid_argument("Fatal error");
}
google::InstallFailureFunction(&ThrowingFailureFunction);
// additional macros re-definitions This always ends up with an |
Yes, this is what I had in mind. Indeed, Please see 5645f3a and let me know if this works for you. |
Thanks, this indeed works. Some remaining issues:
|
Thanks for testing! Hopefully 772e325 fixes the remaining issues. |
I want to convert the
CHECK
macro so that failure throw an exception rather than callingabort
. Putting aside the difficulty that the function registered withInstallFailureFunction
is called from a destructor, I can't even get it to do nothing.Here's my test:
As I understand it the call to
FailingCheckFunction
should cause aFATAL
level log, that should callThrowingFailureFunction
which should log something but not exit/abort. That isn't what happens. MyThrowingFailureFunction
does get called and it does log, but then the gloggoogle::logging_fail
function gets called. When I step through it in a debugger I'm see that LogMessage::Fail is called which, as expected, calls my failure function. However, upon return the debugger jumps immediately tologging_fail
and the debugger just shows an extra stack frame that says "unknown source" so neither it nor I know how it go there or what called that function.So I really have a series of questions here:
LOG(FATAL)
orCHECK
fail from callingabort
?LogMessage
destructor, but ugly...LOG(FATAL)
stream) but the callback isn't passed any objects so I don't know how to access the message.Clearly I can define my own
CHECK
macro and use that but I'm also using 3rd party code which uses glog and I can easily fix all of that.The text was updated successfully, but these errors were encountered: