C++ and Rhino Development -> Avoid Crashing

Hi,

I would like to ask if there is any way to prevent rhino from crashing when the code has some errors?

I tried to use try catch statement but this does not help anyhow. I am not using external libraries. Each time I have to restart Rhino, therefore the development takes always a long time to debug. If there is no prevention from crash, for what try and catch statement is used in C++ ?

    try {
             ....methods
	}
	catch (char const* exception) {
		RhinoApp().Print(exception);
	}	catch (...) {
		RhinoApp().Print("Caught exception : Some other exception");
	}

It depends on where your errors originated. If an exception was thrown (and you should throw exceptions that inherit from std::exception, see std::exception - cppreference.com) these can be caught. But if you, for example, dereference a null pointer, a crash will happen without an exception.
This means that you should program more defensively, checking all pointers for null, all loops for range, etc. etc. My personal experience is that about half the code I write is handling of potential errors.

https://en.cppreference.com/w/cpp/language/throw

Yes, I’m not a professional programmer but when I write code for somebody else, I’d say that at least 2/3 of it are to make it as fool proof as I’m able to. It’s a hard task to do, and a huge mental undertaking to think everything through and mend potential weaknesses or exploits.

The try clause well tries all code that’s placed inside of it’s scope, and when an exception occurs and you’re trying to catch that specific exception, the catch clause is run.
The more general the exception that you’re trying to catch, the better the chance, however this is considered bad programming, since it potentially obfuscates debugging information.
std::exception is the mother class that all other exceptions inherit from. When you try to catch it, it potentially catches all sub exceptions. I guess you see the problem here.
However, the more specific you get, the greater the chance that you don’t catch certain ones.
I’d say don’t try to catch unknown exceptions. Only use this if you’re certain what to catch.

As Menno already pointed out, you usually want to raise the exception with the throw expression, since this also stops code execution. Outputting stuff to a console, like RhinoApp().Print(), does just that, and then continues to run.

I suppose it’s better to use managed code if you REALLY want to avoid any crash…

You probably need to use __except / _set_se_translator to catch more general errors (such as null pointer derefs) passed by SEH.

This is what I also thought. Running python code for wrapped for C++, because C# crash as well.

I read about SEH exceptions and I added to my code.
Could you elaborated what is _set_se_translator?

Thank you @diff-arch and @menno for the advice. I know that I need to handle errors myself, but from time to time I find new ones. The bigger issue is that during development I constantly need to display geometry and rework the code. Knowing how long the Rhino application takes to load the whole debugging process becomes very slow, requiring tens of time to reload rhino.

I do not know how you guys fast debug your code. Do you first develop code outside rhino with a quick debugging like Console App or some custom visualizer and only then port to Rhino?

It would be perfect that it would be possible to automatically unload and reload .rhp files because currently .rhp cannot be rebuild unless Rhino is closed:

Severity Code Description Project File Line Suppression State
Error LNK1104 cannot open file ‘C:\IBOIS57_Code\Software\Raccoon_Litter_Box\joinery_solver\x64\Release\joinery_solver_rhino7.rhp’ joinery_solver_rhino7 C:\IBOIS57_Code\Software\Raccoon_Litter_Box\joinery_solver\joinery_solver_rhino7\LINK 1

Not ideal, but you can make use of UnmapViewOfFile to release the file handle of RHP files and delete RHP files on the fly.

There has been a way to “reload” C# plug-ins for a while now, and we’re using this method too, both for RHP and GHA files.

See How To Debug/Recompile Without Restarting Rhino
and New way to load a C# .net plugin

Briefly, it makes a separation of the commands that reside in the plug-ins, and the command implementations that reside in another assembly. This command implementation assembly is reloaded every time the command executes using Assembly.Load(File.ReadAllBytes(<path/to/implemetation-dll>)); This can be done multiple times, and the newly loaded assembly will overwrite or take precedence over the old assembly.

Is it only for C# or for C++ as well?

Could you show how to use this command?
I imagine this is not a rhino command

Only for C#

@menno
If you do not enable debugging of native code, pure C# can use a function
in vs2019, and there is no need to restart Rhino;
1637739763(1) <----- this icon

I am on C++, it seems there is no other way than restart, or compile to python bindings…