Everything I have read suggests that memcpy does not throw an exception so try-catch statements cannot be used to handle such an error. I have been provided memory addresses and ranges by the hardware team and am accessing them through mmap, but there have been some integration issues (i.e. things for them to fix).
One DDR channel works perfectly while the same code doing the same operations often dies for another channel. The program simply halts with "Bus Error" printed on the terminal.
Once this is figured out, memory interactions should be much smoother, but this interface accepts memory operations from another device (i.e. another team). I can try to validate any incoming operations, but then there is the possibility that the hardware team does something weird as well to change what is valid or simply results in "Bus Error" for a valid operation.
So how can I keep my C++ application from dying due to future/unexpected changes from another team? Do I need to set up a signal handler? Are there other options?
Expanding @user2725742's suggestion of using long jumps, here is a version that converts the signal into an exception. I use it to catch both bus and segmentation fault errors because frankly I don't know a good way of generating bus errors.
We start by defining an RAII class to set and restore signal handlers since we will mix exceptions and global state changes. This is a rather minimal, non-moveable version but sufficient for our needs.
We can now define the actual handler for the signals. The idea is this:
longjmplongjmplongjmpreturns to the place where it was set. There the signal state is converted into an exceptionIn order to make this work in a multithreaded environment, the longjmp buffer and saved signal state need to be a thread local variable.
Now we can use this to guard the
memcpyor some other functions. Specific requirements:sigsetjmpandsiglongjmpwill be forgotten without invoking their destructor firstman 3 siglongjmp(curiously absent from other man-pages with the same title)Anyway,
memcpyis safe to use with this:And here is a quick test to see it working: