I have a boost::thread which performs synchronous reads on a boost::asio::serial_port. When I destroy an instance of the class which contains both, I want the thread to end gracefully even if its blocked in a read call. How can I do this?
Looking at the docs, I tried cancel, but it works only for asynchronous reads/writes. Then I tried close, but I got an exception and it wasn't the kind you can recover from. Perhaps using send_break or native_handle? (this is Windows and portability's not critical)
Update: I also tried to stop the io_service I passed to the serial port object's constructor, but the read wasn't unblocked.
Edit: The exception is actually "catchable", but I'd hate to put a try/catch block inside a destructor, and refactoring the code to do the shutdown process outside the destructor would trigger lots of changes in upper layers. So I'd only go for this solution if some Boost authority says there is no other way.
There is no way to unblock the synchronous read as you ask to.
There are two options:
close/shutdown the port and catch an exception, which was raised
use asynchronous reads and cancel them, when you shutdown your application
The first one, of course, is not a good idea, because you cannot distinguish terminating application from error.
On close, you say that you get an exception that 'wasn't the kind you can recover from'.
What does this mean?
The solution seems to be to catch the exception. Why cannot you do that?
For the case when you want to distinguish between an error and program termination, set a flag on program termination before the close. In the exception handler ( catch ) check the flag. If set, handle as program termination, else handle as error.
You say that you do not wish to place a try/catch block inside a destructor. This seems like an odd prejudice to me, but OK there are other ways.
You can allow the exception to propagate all the way to the topmost catch block that surrounds all your code, and handle it there. ( You do have such a try/catch block protecting your entire application, of course :-)
Other ways are also possible ... but boss just dropped by
Related
There are a few SO posts about whether or not declaring main() using function-try-block syntax is valid syntax, and the general consensus seems to be that it's perfectly valid. This left me wondering... is there any reason (performance, style, thread synchronization, multithreading) why one wouldn't use this syntax for main() as a general rule to catch any unhandled exceptions anywhere more gracefully?
Obviously, ideally there won't be unhandled exceptions, but they happen and I think it'd be nice to provide something more informative than the OS-specific default handler. For example, in my case, I'd like to provide a support email address to the user so they can report the crash and have my program submit a log to my cloud-based crash log.
For example, in my case, I'd like to provide a support email address to the user
Well, how are you going to do that in a server with no user-facing interface?
Actually, how are you going to do that even in a process with user-facing components, if you have no way to tell in the catch block what state they're in?
And, for those processes where you can't show the user anything useful (or don't have any concept of a "user" in the first place), what would you do in your catch block that would be better than the default terminate?
As for
... more informative than the OS-specific default handler ...
many OS' default behaviour will be to save a complete snapshot of the process execution state, at the point the un-handled exception is thrown, to a file for debugging. As the developer, I can't think of many default behaviours that would be more informative.
Admittedly I'd prefer something more polished as the end user of a desktop app, but that's a pretty small subset of C++ programs.
You can easily convert
int main() try {
// The real code of main
}
catch (...)
{
}
to
int realMain()
{
// The real code of main
}
int main()
{
try
{
return realMain();
}
catch ( ... )
{
}
}
without losing functionality/behavior.
I am going to guess that whether you use the first version or the second version is a matter of coding practices of a team. From a compiler and run time standpoint, I don't see any semantic difference.
If you happened to have a variable that you want to access in your catch block, you would need the curly braces to provide visibility. But even that could be handled with nested try/catch...
why one wouldn't use this syntax for main() as a general rule to catch
any unhandled exceptions anywhere more gracefully?
compatibility with C.
Sometimes there is no way to handle unhandled exceptions more gracefully.
Obviously, ideally there won't be unhandled exceptions, but they
happen and I think it'd be nice to provide something more informative
than the OS-specific default handler. For example, in my case, I'd
like to provide a support email address to the user so they can report
the crash and have my program submit a log to my cloud-based crash
log.
If unexpected exception happens you can not be sure that it is possible to handle it correctly. What are you going to do if there is a network error exception in your example. And trying to send e-mail causes another exception? There can be other errors when you can not be sure that your data is not corrupted and you can not be sure that your program can run correctly after this error. So if you don't know what error happened it is better to allow your program to crash.
You can implement another "watcher" service that checks if process is running and if it has been crashed it can send e-mail to your users with the logs and core dumps.
If you catch the (otherwise) uncaught object, you won't be able to figure out how the execution reached the throw by inspecting the stack trace, because when exception handler is executed, the stack has already been unwound.
If you let the unexpected exception to be uncaught, you may be able to inspect the stack trace in the terminate handler - this is not guaranteed by the standard, but that's not a big deal since there is no standard way to inspect the stack trace either (in C++). You can either use platform specific API within the program, or an external debugger for the inspection.
So for example in your case, the advantage of not catching the exception would be that you can attach a stack trace to the log entry that you intend to submit.
Also, there are cases where an exception can not be handled by a catch block. For example, when you throw from a destructor that is being executed as a result of throwing an exception. So, to handle these "uncatchable" exceptions, you need a terminate handler anyway, so there is little advantage in duplicating the functionality in the case of uncaught exceptions.
As for the syntax that you use to catch the exception, there is no difference. The case where the function try block is different is a constructor, where it allows catching exceptions thrown by sub object constructors.
I was reading thinking in c++ (exceptional handling).
I didn't understand following line
C++ exceptions cannot be used to handle asynchronous events because the exception and its handler are on the same call stack.
I tried searching over web but couldn't able to under stand this line.(specially call stack part)
Can anyone help on it?
EDIT:
what does same call stack means?
Exceptions, when thrown, divert the current thread's execution path to the handling of that exception. There's no way to avoid this by, say, getting another thread to perform the exception handling. The stack is important here because the exception handling involves stack-unwinding which isn't conducive to asyncronouis event handling, or much else.
The problem is like so
try {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// do some really long running operation here
longFunctionToCalculate42();
// oops, some critical error!
throw std::runtime_error( "Something went wrong!" );
});
} catch ( const std::exception& e ) {
// this won't do what you think it does
std::cerr << e.what() << std::endl;
}
The asynchronous block is executed separately from the call site, and the caller of that asynchronous function (the dispatched block) cannot catch the exception thrown from it.
You actually can handle async events using exceptions. Weather or not you should is another matter. I'll only address that briefly: you usually shouldn't because there are more purpose-direct mechanisms to handle such things. Like passing messages between threads or raising some kind of event.
As to how you can accomplish this, what you have to do is catch the exception in the throw-ing thread, record the information somewhere, and have the other thread pick that up. Note that this really boils down fundamentally to passing messages between threads, with the additional complexity of stack unwinding and the like.
C++11 provides current_exception(), returning a exception_ptr, which provides the means to save the information about the exception somewhere the responding thread can pick it up. It is still up to you to build the code that actually retrieves and processes this exception_ptr up from wherever you saved it, and that's beyond the scope of this answer.
Note when thinking about this that, unless you need actual exceptions, doing this gains you nothing over simply passing messages between threads, and costs you the stack unwinding and semantic implications of throwing and catching exceptions.
It means that asynchronous events do not follow the exception's model where "exception and its handler are on the same call stack". That is -
exceptions rely on the dynamic chain of function calls on the program
s runtime stack (they have dynamic scope ), whereas asynchronous
events must be handled by completely separate code that is not part of
the normal program flow (typically, interrupt service routines or
event loops)
Note "completely separate code", which means that you'd have to rely on some other mechanism to handle asynchronous events (if you really need so).
So imagine you've got an exception you're catching and then in the catch you write to a log file that some exception occurred. Then you want your program to continue, so you have to make sure that certain invariants are still in a a good state. However what actually occurs in the system after the exception was "handled" by a catch?
The stack has been unwound at that point so how does it get to restore it's state?
"Stack unwinding" means that all scopes between throw and the matching catch clause are left, calling destructors for all automatic objects in those scopes, pretty much in the same way function scopes are left when you return from a function.
Nothing else "special" is done, the scope of a catch clause is a normal scope, and leaving it is no different from leaving the scope of an else clause.
If you need to make sure certain invariants still hold, you need to program the code changing them in a thread-safe manner. Dave Abrahams wrote a classic on the different levels of exception safety, you might want to read that. Basically, you will have to consequently employ RAII in order to be on the safe side when exceptions are thrown.
Only objects created inside the try will have been destroyed during unwinding. It's up to you to write a program in such way that if an exception occurs program state stays consistent - that's called exception safety.
C++ doesn't care - it unwinds stack, then passes control into an appropriate catch, then control flow continues normally.
It is up to you to ensure that the application is recovered into a stable state after catching the exception. Usually it is achieved by "forgetting" whatever operation or change(s) produced the exception, and starting afresh on a higher level.
This includes ensuring that any resources allocated during the chain of events leading to the exception gets properly released. In C++, the standard idiom to ensure this is RAII.
Update
For example, if an error occurs while processing a request in a web server, it generates an exception in some lower level function, which gets caught in a higher level class (possibly right in the top level request handler). Usually the best possible thing to do is to roll back any changes done and free any resources allocated so far related to the actual request, and return an appropriate error message to the client. Changes may include DB transactions, file writes, etc - one must implement all these in an exception safe manner. Databases typically have built in transactions to deal with this; with other resources it may be more tricky.
This is up to the application. There are several levels of exception-safety. The level you describe is hard to achieve for the whole application.
Certain pieces of code, however, can be made 'Failure transparent', by using techniques like RAII, and by smartly ordering the sequence of actions. I could imagine a piece of code querying several urls for data, for instance: when one url would 'throw', the rest of the urls can still be handled. Or it can be retried...
If you have exception handling in every function you can resume on the next higher level but its rather complicated, in fact I use exceptions mainly to detect errors as close to the source as possible but don't use them for resuming execution.
if on the other hand there are errors that are predictable one can devise schemes to handle that, but for me exceptions are considered exceptions so I tend to try and exit gracefully instead with a good hint in the log file where it happened. JM2CW
It can't. Exceptions aren't resumable in C++. Nor in most
modern languages; some of the first languages to support
exceptions did support resumable exceptions, and found that it
wasn't a good idea.
If you want to be able to resume from some specific point, you
have to put your try/catch block there. If you just want to log
and continue, don't throw the exception in the first place.
I'm working on a library where I'm farming various tasks out to some third-party libraries that do some relatively sketchy or dangerous platform-specific work. (In specific, I'm writing a mathematical function parser that calls JIT-compilers, like LLVM or libjit, to build machine code.) In practice, these third-party libraries have a tendency to be crashy (part of this is my fault, of course, but I still want some insurance).
I'd like, then, to be able to very gracefully deal with a job dying horribly -- SIGSEGV, SIGILL, etc. -- without bringing down the rest of my code (or the code of the users calling my library functions). To be clear, I don't care if that particular job can continue (I'm not going to try to repair a crash condition), nor do I really care about the state of the objects after such a crash (I'll discard them immediately if there's a crash). I just want to be able to detect that a crash has occurred, stop the crash from taking out the entire process, stop calling whatever's crashing, and resume execution.
(For a little more context, the code at the moment is a for loop, testing each of the available JIT-compilers. Some of these compilers might crash. If they do, I just want to execute continue; and get on with testing another compiler.)
Currently, I've got a signal()-based implementation that fails pretty horribly; of course, it's undefined behavior to longjmp() out of a signal handler, and signal handlers are pretty much expected to end with exit() or terminate(). Just throwing the code in another thread doesn't help by itself, at least the way I've tested it so far. I also can't hack out a way to make this work using C++ exceptions.
So, what's the best way to insulate a particular set of instructions / thread / job from crashes?
Spawn a new process.
What output do you collect when a job succeeds?
I ask because if the output is low bandwidth I would be tempted to run each job in its own process.
Each of these crashy jobs you fire up has a high chance of corrupting memory used elsewhere in your process.
Processes offer the best protection.
Processes offer the best protection, but it's possible you can't do that.
If your threads' entry points are functions you wrote, (for example, ThreadProc in the Windows world), then you can wrap them in try{...}catch(...) blocks. If you want to communicate that an exception has occurred, then you can communicate specific error codes back to the main thread or use some other mechanism. If you want to log not only that an exception has occured but what that exception was, then you'll need to catch specific exception types and extract diagnostic information from them to communicate back to the main thread. A'la:
int my_tempermental_thread()
{
try
{
// ... magic happens ...
return 0;
}
catch( const std::exception& ex )
{
// ... or maybe it doesn't ...
string reason = ex.what();
tell_main_thread_what_went_wong(reason);
return 1;
}
catch( ... )
{
// ... definitely not magical happenings here ...
tell_main_thread_what_went_wrong("uh, something bad and undefined");
return 2;
}
}
Be aware that if you go this way you run the risk of hosing the host process when the exceptions do occur. You say you're not trying to correct the problem, but how do you know the malignant thread didn't eat your stack for example? Catch-and-ignore is a great way to create horribly confounding bugs.
On Windows, you might be able to use VirtualProtect(YourMemory, PAGE_READONLY) when calling the untrusted code. Any attempt to modify this memory would cause a Structured Exception. You can safely catch this and continue execution. However, memory allocated by that library will of course leak, as will other resources. The Linux equivalent is mprotect(YorMemory, PROT_READ), which causes a SEGV.
I have a Windows C++ console program, and if I don't call ReleaseDriver() at the end of my program, some pieces of hardware enter a bad state and can't be used again without rebooting.
I'd like to make sure ReleaseDriver() gets runs even if the program exits abnormally, for example if I hit Ctrl+C or close the console window.
I can use signal() to create a signal handler for SIGINT. This works fine, although as the program ends it pops up an annoying error "An unhandled Win32 exception occurred...".
I don't know how to handle the case of the console window being closed, and (more importantly) I don't know how to handle exceptions caused by bad memory accesses etc.
Thanks for any help!
Under Windows, you can create an unhandled exception filter by calling SetUnhandledExceptionFilter(). Once done, any time an exception is generated that is not handled somewhere in your application, your handler will be called.
Your handler can be used to release resources, generate dump files (see MiniDumpWriteDump), or whatever you need to make sure gets done.
Note that there are many 'gotchas' surrounding how you write your exception handler function. In particular:
You cannot call any CRT function, such as new
You cannot perform any stack-based allocation
If you do anything in your handler which causes an exception, Windows will immediately terminate your application by ripping the bones out of its back. You get no further chances to shut down gracefully.
You can call many Windows API functions. But you can't sprintf, new, delete... In short, if it isn't a WINAPI function, it probably isn't safe.
Because of all of the above, it is advisable to make all the variables in your handler function static variables. You won't be able to use sprintf, so you will have to format strings ahead of time, during initialization. Just remember that the machine is in a very unstable state when your handler is called.
If I'm not mistaken, you can detect if the console is closed or the program is terminated with Ctrl+C with SetConsoleCtrlHandler:
#include <windows.h>
BOOL CtrlHandler(DWORD)
{
MessageBox(NULL, "Program closed", "Message", MB_ICONEXCLAMATION | MB_OK);
exit(0);
}
int main()
{
SetConsoleCtrlHandler((PHANDLER_ROUTINE)&CtrlHandler, TRUE);
while (true);
}
If you are worried about exceptions, like bad_alloc, you can wrap main into a try block. Catch std::exception& which should ideally be the base class of all thrown exception, but you can also catch any C++ exception with catch (...). With those exceptions, though, not all is lost, and you should figure out what is being thrown and why.
Avoiding undefined behavior also helps. :)
You can't (guarantee code runs). You could lose power, then nothing will run. The L1 instruction cache of your CPU could get fried, then your code will fail in random ways.
The most sure way of running cleanup code is in a separate process that watches for exit of the first (just WaitForSingleObject on the process handle). A separate watchdog process is as close as you can get to a guarantee (but someone could still TerminateProcess your watchdog).