3

I have been tasked with the title above. There is currently zero exception handling. There are 100+ threads, all created from main().

Exceptions won't percolate up to main() - they won't leave the thread.

Each thread has a Make() function, invoked from main(), which initializes the data and subscribes to async messages. The system framework delivers the messages by invoking callbacks which were passed in the subscribe() function.

I don't think that I can wrap each thread in its own try catch. I fear that I must have a try/catch in each message handler, and management would baulk at that, as each thread has a dozen or so subscribed messages, meaning adding 1,000+ try/catch.

Is there a simpler solution, using C++ 14? Host is Windows and target is VxWorks, if that makes any difference.


Bottom line, I would have to add try/catch to every callback which handles a message, over 500 of them. I suggested a Python script, but it was decided to forget exceptions and go with a heartbeat mechanism

6
  • It depends what you want to achieve, but if you just want control over what happens on the way down: learn.microsoft.com/en-us/cpp/cpp/…
    – pjc50
    Commented Apr 24 at 11:02
  • 7
    But the most fundamental question: once you've caught the exception, what are you going to do with it?
    – pjc50
    Commented Apr 24 at 11:02
  • It seems like your threads are wrapped within objects of some sort, exposing a make method. If so, take a look at the futures / promise API, these catch the exceptions and contain them within the local state of the thread, and later exposes them as properties in the futures/promise object. This allows the callers to be aware of the failure without crashing the application. You can implement something similar, or rearrange your code based on futures / promises.
    – Ccm
    Commented Apr 24 at 12:36
  • 1
    Can you edit your question to include more information about the architecture of our application? Are your threads wrapped in their own objects? Are they just pointers to a function? Commented Apr 24 at 18:26
  • 1
    I think you can provide a better view of the system if you do this trick: capture a bunch of stack traces, each one from a different worker thread. See where the stack traces diverge from VxWorks (the framework) into your proprietary code. The proprietary code is where you have control over, and I suspect there's a single entry point that's used by all message handler threads (typically known as the thread entry point). With this information you can ask for permission to add the exception handler there.
    – rwong
    Commented Apr 29 at 14:06

1 Answer 1

8

The most important part of Structured Exception Handling is that last part - handling it or, in other words, doing something useful with it!

I would guess what's happened here is that a bunch of "Happy-Path" code - without Exception Handling - has been written and now you have to keep it alive because, sometimes, it throws Exceptions and thereby shoots itself in the foot.
I do not envy you being in this position.

Look at the code and the sorts of Exceptions being thrown and then decide at what point you can do something useful with those Exceptions.

  • Smothering / swallowing . discarding them is not an option. Ever.
  • Logging them to a file and losing them might work but at what cost to the Application? (And it could be hugely complex in a multi-threaded application).
  • If you really can't do anything useful with them, then perhaps the best thing to do is to let the application crash and burn ...
8
  • In most cases you will log and move on, without crashing what is potentially a sensitive application. Crash happy applications have a quick way to the recycle bin of engineering failures. Most exceptions are recoverable, and in a multi threading environment, assuming no global state has been altered, exception handling and recovery is surprisingly easy - you don't care if an exception is thrown as long as it is contained in a single thread. Just retry and move on.
    – Ccm
    Commented Apr 24 at 12:32
  • 3
    @Ccm "assuming no global state has been altered" is a pretty big assumption, especially when you include IO in "alters global state"
    – Caleth
    Commented Apr 24 at 13:17
  • 3
    @Ccm OP has given a very vague description of the system they are using. Certainly a sensible design for a system would have those properties. If the OP's system had been sensibly designed, would they be asking this question in the first place?
    – Caleth
    Commented Apr 24 at 13:33
  • 2
    @Ccm "Crash-only software" lwn.net/Articles/191059 is not only a viable approach but can improve integrity at the expense of availability. I worked on a point-of-sale application that took this approach, and it was extremely effective because it never lost more state than the last button press.
    – pjc50
    Commented Apr 25 at 8:36
  • 2
    RAII usually works, but that doesn't cover everything in most programs, where there is usually some global state. My point about unexpected exceptions is that the code will have been written without regard for what happens in unwinding, so is likely not to handle it well. And trying to ban C++ programmers from using raw pointers and new/malloc .. well, might work if you rigorously control a project from the beginning, but that's not the case here, is it?
    – pjc50
    Commented Apr 25 at 13:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.