Exception handling

Here's the place for discussion related to coding in FreeCAD, C++ or Python. Design, interfaces and structures.
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Post Reply
triplus
Veteran
Posts: 9471
Joined: Mon Dec 12, 2011 4:45 pm

Re: Exception handling

Post by triplus »

I see on Linux it would be possible to go down the Windows path and do some things manually to catch more exceptions and to have less crashes but one possible down side could be without the actual crash happening and a fix for it one could think everything is fine but in reality exception handling mechanism would in a way take that exceptions and try to not crash the FreeCAD?

I am guessing this can only work fine to some extent and some exceptions thrown would be too much for exception handling mechanism and the result could be unpredicted behaviour?

Probably it makes sense to have as good exception handling mechanism possible but i doubt it can be that good for FreeCAD to newer crash again or start behaving in unpredicted way after some exceptions thrown?

I am guessing investing in quality exception handling mechanism plus capable developers detecting and fixing exceptions thrown is it in the end optimal result and one would say sane strategy? Or to not write code that introduces exceptions thrown in the first place (this path would probably slow down FreeCAD development too much and that is probably not optimal). :D
wmayer
Founder
Posts: 20319
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: Exception handling

Post by wmayer »

Here some more information related to the crash in the gear panel.
When you start FreeCAD without loading the Part module (i.e. we don't use OCC's signals framework) e.g. by defining Mesh as startup workbench and then run this Python code:

Code: Select all

FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/PartDesign/InvoluteGearFeature.ui")
You'll get a segmentation fault.

When trying to open the gear panel with the GUI you get this error instead:
*** Abort *** an exception was raised, but no catch was found.
FYI, the message is printed by OCC inside Standard_ErrorHandler::Abort().
In the latter case we activate OCC's signal handling which handles the actual segmentation fault and converts it into a C++ exception. When handling the OCC exception OCC tries to find an instance of error handlers and if there is none it writes the above error and exits. Now the question is how to work with these error handlers and if it's up to the programmer to instantiate it beforehand.

Back to the crash of the gear panel. It appeared that I was right with my assumption that it's due to the duplicate symbols of Qt's QtUiTools module which is linked by FreeCAD and PySide. So, I have implemented an alternative way which does not use PySide's QtUiTools any more and now it loads fine.
User avatar
cblt2l
Posts: 155
Joined: Sat May 15, 2010 3:59 am

Re: Exception handling

Post by cblt2l »

wmayer wrote:Here some more information related to the crash in the gear panel.
When you start FreeCAD without loading the Part module (i.e. we don't use OCC's signals framework) e.g. by defining Mesh as startup workbench and then run this Python code:

Code: Select all

FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/PartDesign/InvoluteGearFeature.ui")
You'll get a segmentation fault.
I noticed the same thing with my cura engine macro. I get random crashes either when loading or closing the form. I thought it was a problem on my part.
wmayer wrote: When trying to open the gear panel with the GUI you get this error instead:
*** Abort *** an exception was raised, but no catch was found.
The error I get is:

Code: Select all

*** Abort *** an exception was raised, but no catch was found.
	... The exception is:SIGSEGV 'segmentation violation' detected. Address 6156008
wmayer wrote: Back to the crash of the gear panel. It appeared that I was right with my assumption that it's due to the duplicate symbols of Qt's QtUiTools module which is linked by FreeCAD and PySide. So, I have implemented an alternative way which does not use PySide's QtUiTools any more and now it loads fine.
I will give it a test.
douardda
Posts: 25
Joined: Sat Feb 15, 2014 11:22 am

Re: Exception handling

Post by douardda »

wmayer wrote:Back to the crash of the gear panel. It appeared that I was right with my assumption that it's due to the duplicate symbols of Qt's QtUiTools module which is linked by FreeCAD and PySide. So, I have implemented an alternative way which does not use PySide's QtUiTools any more and now it loads fine.
Yes that explains the uninitalised ResourceBuilder that is at the origin of the null pointer leading to the segfault.

Nice job, it does work properly now. However, if the QtUiTools static lib is duplicated, shouldn't be enough not to include this static lib when linking FreeCAD's binary (when using PySide)?

More, I wonder why this whole UI loading code is written in C++ instead of pure Python?
I'm also a bit surprised adding the FCGear dialog to the PartDesign bench require C++ code? I've not looked in the code yet, but is there a strong reason for this ?

David
wmayer
Founder
Posts: 20319
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: Exception handling

Post by wmayer »

Yes that explains the uninitalised ResourceBuilder that is at the origin of the null pointer leading to the segfault.
Which null pointer on which ResourceBuilder?
However, if the QtUiTools static lib is duplicated, shouldn't be enough not to include this static lib when linking FreeCAD's binary (when using PySide)?
How should this work? PySide is an extension module that you don't bind at link time. You bind it at runtime by loading the module:

Code: Select all

from PySide import QtUiTools
More, I wonder why this whole UI loading code is written in C++ instead of pure Python?
Because it's a mechanism provided by Qt, the class QUiLoader. Indeed there is also an approach to do everything in Python but then we have to generate Python binding for our custom widget classes too which is not a trivial thing.
I'm also a bit surprised adding the FCGear dialog to the PartDesign bench require C++ code? I've not looked in the code yet, but is there a strong reason for this ?
We have a subclass of QUiLoader which overrides the virtual method "createWidget" so that we can create instances of our custom widgets. Again there are two different methods:
1. Use Qt's QUiLoader (or a subclass) and load .ui files
2. Generate Python code out of the .ui form.

See also viewtopic.php?f=10&t=5374
User avatar
jriegel
Founder
Posts: 3369
Joined: Sun Feb 15, 2009 5:29 pm
Location: Ulm, Germany
Contact:

Re: Exception handling

Post by jriegel »

Its in the PartDesign workbench cause a gear is after all a solid and should be in a PartDesign Body (in the future)...
Stop whining - start coding!
douardda
Posts: 25
Joined: Sat Feb 15, 2014 11:22 am

Re: Exception handling

Post by douardda »

wmayer wrote:
Yes that explains the uninitalised ResourceBuilder that is at the origin of the null pointer leading to the segfault.
Which null pointer on which ResourceBuilder?
I've recompiled a libQtUiTools with debug symbols (and I also have recompiled the pyside deb packages with debug symbols, which is huge so it's not included by debian packagers, see http://anonscm.debian.org/viewvc/python ... e?view=log )
So I could run FreeCAD with a more usable bt in gdb. I d'ont have the details here, but in the call stack is a call to domPropertyToVariant (qt4-x11-4.8.1/tools/designer/src/lib/uilib/properties.cpp) called for the geometry property of the InvoluteGearParameter widget (thus expecting a QRect-kind of QVariant). In this code, the afb->resourceBuilder() is a Null pointer.

I had no time no investigate more, but I couldn't make the breakpoints I put in some of the uilib methods to be reached. I guess the fact these symbols are present twice might explain this...
wmayer wrote:
However, if the QtUiTools static lib is duplicated, shouldn't be enough not to include this static lib when linking FreeCAD's binary (when using PySide)?
How should this work? PySide is an extension module that you don't bind at link time. You bind it at runtime by loading the module:

Code: Select all

from PySide import QtUiTools
Yes I've seen this Python code executed from C++. Still, I don't get the point exactly. If this uitools code is loaded when the Python QtUiTools module is loaded, do we really need to include it in libFreeCADGui.so? Are all (some?) ui files dynamically loaded from C++? If so, wouldn't be a "quick an dirty" solution to link libFreeCADGui.so with QtUiTools.so ? (kind of ugly, but...)
wmayer wrote:
More, I wonder why this whole UI loading code is written in C++ instead of pure Python?
Because it's a mechanism provided by Qt, the class QUiLoader. Indeed there is also an approach to do everything in Python but then we have to generate Python binding for our custom widget classes too which is not a trivial thing.
I was speculating this. How many custom widget classes are there? Wouldn't it make sense to provide them for Python to be usable "everywhere" in FreeCAD? (maybe you noticed I find life a bit too short to write too much c++ :-) )
wmayer wrote:
I'm also a bit surprised adding the FCGear dialog to the PartDesign bench require C++ code? I've not looked in the code yet, but is there a strong reason for this ?
We have a subclass of QUiLoader which overrides the virtual method "createWidget" so that we can create instances of our custom widgets. Again there are two different methods:
1. Use Qt's QUiLoader (or a subclass) and load .ui files
2. Generate Python code out of the .ui form.
I've seen this subclass of the QUiLoader. Once again, it is required cause the custom widgets are not available as proper Designer plugin nor Python widget, right? IIRC, there are mecanisms in Qt an PySide to allow dynamic load of custom widgets.

I mean theses http://qt-project.org/doc/qt-4.8/quiloader.html ("If you have a custom component or an application that embeds Qt Designer, you can also use the QFormBuilder class provided by the QtDesigner module to create user interfaces from UI files.") and the equivalent for PySide.

Shouldn't it be the "right" way of doing it? (beside the amount of work it require :-/ )
wmayer wrote: See also viewtopic.php?f=10&t=5374
I'll read this topic, thanks

David
douardda
Posts: 25
Joined: Sat Feb 15, 2014 11:22 am

Re: Exception handling

Post by douardda »

jriegel wrote:Its in the PartDesign workbench cause a gear is after all a solid and should be in a PartDesign Body (in the future)...
I was not asking why it is in the PartDesign workbench, but I was expressing that I find a bit odd to have to recompile FreeCAD to add a menu entry that calls pure Python code. Having an embedded Python in FreeCAD (with GUI stuff avaible from Python), I would have expected to be able to do the whole gear generation stuff as Python code, including adding menu entries.

David
wmayer
Founder
Posts: 20319
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: Exception handling

Post by wmayer »

I had no time no investigate more, but I couldn't make the breakpoints I put in some of the uilib methods to be reached. I guess the fact these symbols are present twice might explain this...
OK, thanks for investigating on this.
Still, I don't get the point exactly. If this uitools code is loaded when the Python QtUiTools module is loaded, do we really need to include it in libFreeCADGui.so?
How do you know at linking time of libFreeCADGui.so that you later use PySide or not?
Are all (some?) ui files dynamically loaded from C++?
A few. From the majority of .ui files we create C++ code and compile it.
If so, wouldn't be a "quick an dirty" solution to link libFreeCADGui.so with QtUiTools.so ? (kind of ugly, but...)
Maybe. But then we have to know the absolute path and add it to the linker as argument which might be not so easy to make it working on all Linux distributions. Just doing -L<Lib path> -lQtUiTools won't work because the linker expects a file of the form libQtUiTools.so
I was speculating this. How many custom widget classes are there? Wouldn't it make sense to provide them for Python to be usable "everywhere" in FreeCAD? (maybe you noticed I find life a bit too short to write too much c++ )
We have around 30 custom widgets. For some of them we have a Qt plugin which however only provides the interface to create forms with the designer. The actual implementation has been removed because it otherwise links to libFreeCADGui.so.
I've seen this subclass of the QUiLoader. Once again, it is required cause the custom widgets are not available as proper Designer plugin nor Python widget, right?
Yes, but having the widgets in a fully working Qt plugin is not easy.
User avatar
jriegel
Founder
Posts: 3369
Joined: Sun Feb 15, 2009 5:29 pm
Location: Ulm, Germany
Contact:

Re: Exception handling

Post by jriegel »

I've seen this subclass of the QUiLoader. Once again, it is required cause the custom widgets are not available as proper Designer plugin nor Python widget, right?
Yes, but having the widgets in a fully working Qt plugin is not easy.
Most of our costume widgets have a certain Qt base class, you can use them in designer and do the exchange in the ui file.
Stop whining - start coding!
Post Reply