Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Problem] EDIT => Preferences crashes at commit ac6f991ba #12542

Closed
2 tasks done
clytle374 opened this issue Feb 22, 2024 · 40 comments
Closed
2 tasks done

[Problem] EDIT => Preferences crashes at commit ac6f991ba #12542

clytle374 opened this issue Feb 22, 2024 · 40 comments
Labels
Core Issue or PR touches core sections (App, Gui, Base) of FreeCAD Missing: confirmation Missing confirmation from other testers Missing: diagnosis Missing: feedback If feedback is requested

Comments

@clytle374
Copy link

clytle374 commented Feb 22, 2024

Is there an existing issue for this?

  • I have searched the existing issues

Problem description

When clicking on Preferences under edit Freecad crashes with the following. This issue is a little old as I figured someone else would catch it and it wasn't really effecting me. Decided to finally report it as I was already reporting a different issue and was already in the mood to run git bisect.
Please let me know if I can provide more information, or assistance. Thanks!

./bin/FreeCAD
FreeCAD 0.22.0, Libs: 0.22.0devR35654 (Git)
© Juergen Riegel, Werner Mayer, Yorik van Havre and others 2001-2023
FreeCAD is free and open-source software licensed under the terms of LGPL2+ license.
FreeCAD wouldn't be possible without FreeCAD community.
 
QOpenGLFunctions created with non-current context
Addon Manager Warning: Could not import QtWebEngineWidgets -- README data will display as text-only
(qt.qpa.wayland) Wayland does not support QWindow::requestActivate()
**CRASH HAPPENS NEXT**
Program received signal SIGSEGV, Segmentation fault.
#0  /lib64/libc.so.6(+0x396a0) [0x7fec40c796a0]
#1  /usr/lib64/libpython3.11.so.1.0(+0xfa899) [0x7fec432fa899]
#2  /usr/lib64/libpython3.11.so.1.0(+0x183358) [0x7fec43383358]
#3  /usr/lib64/libpython3.11.so.1.0(PyDict_GetItem+0x8d) [0x7fec4338406d]
#4  /usr/lib/python3.11/site-packages/PySide2/QtCore.cpython-311-x86_64-linux-gnu.so(+0x221d74) [0x7febe5221d74]
#5  /usr/lib64/libpython3.11.so.1.0(PyObject_GetAttr+0x48) [0x7fec433949e8]
#6  /usr/lib64/libpython3.11.so.1.0(_PyObject_GetMethod+0x63) [0x7fec433954a3]
#7  /usr/lib64/libpython3.11.so.1.0(_PyEval_EvalFrameDefault+0x49b7) [0x7fec432ff4d7]
#8  /usr/lib64/libpython3.11.so.1.0(+0x21ff40) [0x7fec4341ff40]
#9  /usr/lib64/libpython3.11.so.1.0(+0x1503a4) [0x7fec433503a4]
#10  0x7fec4676c34a in Py::Callable::apply(Py::Tuple const&) const from /home/cory/freecad-build/lib/libFreeCADGui.so+0x4a
#11  0x7fec4703f9ea in Gui::Dialog::PreferencePagePython::loadSettings() from /home/cory/freecad-build/lib/libFreeCADGui.so+0x15a
#12  0x7fec46b7b14d in Gui::Dialog::DlgPreferencesImp::createPageInGroup(Gui::Dialog::PreferencesPageItem*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) from /home/cory/freecad-build/lib/libFreeCADGui.so+0x28b
#13  0x7fec46b7a2fc in Gui::Dialog::DlgPreferencesImp::setupPages() from /home/cory/freecad-build/lib/libFreeCADGui.so+0xe8
#14  0x7fec46b79d0e in Gui::Dialog::DlgPreferencesImp::DlgPreferencesImp(QWidget*, QFlags<Qt::WindowType>) from /home/cory/freecad-build/lib/libFreeCADGui.so+0x144
#15  0x7fec469d6bf3 in StdCmdDlgPreferences::activated(int) from /home/cory/freecad-build/lib/libFreeCADGui.so+0xb7
#16  0x7fec4698bdcc in Gui::Command::_invoke(int, bool) from /home/cory/freecad-build/lib/libFreeCADGui.so+0x280
#17  0x7fec4698baf5 in Gui::Command::invoke(int, Gui::Command::TriggerSource) from /home/cory/freecad-build/lib/libFreeCADGui.so+0x139
#18  0x7fec4697398c in Gui::Action::onActivated() from /home/cory/freecad-build/lib/libFreeCADGui.so+0x2a
#19  0x7fec469840e4 in QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, void (Gui::Action::*)()>::call(void (Gui::Action::*)(), Gui::Action*, void**) from /home/cory/freecad-build/lib/libFreeCADGui.so+0x7a
#20  0x7fec469836bd in void QtPrivate::FunctionPointer<void (Gui::Action::*)()>::call<QtPrivate::List<>, void>(void (Gui::Action::*)(), Gui::Action*, void**) from /home/cory/freecad-build/lib/libFreeCADGui.so+0x42
#21  0x7fec4698289d in QtPrivate::QSlotObject<void (Gui::Action::*)(), QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) from /home/cory/freecad-build/lib/libFreeCADGui.so+0x80
#22  /usr/lib64/libQt5Core.so.5(+0x2bcafd) [0x7fec414bcafd]
#23  0x7fec41f5c622 in QAction::triggered(bool) from /usr/lib64/libQt5Widgets.so.5+0x42
#24  0x7fec41f5f29f in QAction::activate(QAction::ActionEvent) from /usr/lib64/libQt5Widgets.so.5+0xaf
#25  /usr/lib64/libQt5Widgets.so.5(+0x2e7242) [0x7fec420e7242]
#26  /usr/lib64/libQt5Widgets.so.5(+0x2ef083) [0x7fec420ef083]
#27  0x7fec41fa5788 in QWidget::event(QEvent*) from /usr/lib64/libQt5Widgets.so.5+0x268
#28  0x7fec41f62eee in QApplicationPrivate::notify_helper(QObject*, QEvent*) from /usr/lib64/libQt5Widgets.so.5+0x7e
#29  0x7fec41f6b3d4 in QApplication::notify(QObject*, QEvent*) from /usr/lib64/libQt5Widgets.so.5+0x11c4
#30  0x7fec469270b4 in Gui::GUIApplication::notify(QObject*, QEvent*) from /home/cory/freecad-build/lib/libFreeCADGui.so+0x114
#31  0x7fec4148aaf8 in QCoreApplication::notifyInternal2(QObject*, QEvent*) from /usr/lib64/libQt5Core.so.5+0x138
#32  0x7fec41f696a0 in QApplicationPrivate::sendMouseEvent(QWidget*, QMouseEvent*, QWidget*, QWidget*, QWidget**, QPointer<QWidget>&, bool, bool) from /usr/lib64/libQt5Widgets.so.5+0x1c0
#33  /usr/lib64/libQt5Widgets.so.5(+0x1bef35) [0x7fec41fbef35]
#34  /usr/lib64/libQt5Widgets.so.5(+0x1c17bf) [0x7fec41fc17bf]
#35  0x7fec41f62eee in QApplicationPrivate::notify_helper(QObject*, QEvent*) from /usr/lib64/libQt5Widgets.so.5+0x7e
#36  0x7fec469270b4 in Gui::GUIApplication::notify(QObject*, QEvent*) from /home/cory/freecad-build/lib/libFreeCADGui.so+0x114
#37  0x7fec4148aaf8 in QCoreApplication::notifyInternal2(QObject*, QEvent*) from /usr/lib64/libQt5Core.so.5+0x138
#38  0x7fec4192638b in QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent*) from /usr/lib64/libQt5Gui.so.5+0x8cb
#39  0x7fec4190545c in QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) from /usr/lib64/libQt5Gui.so.5+0xac
#40  /usr/lib64/libQt5WaylandClient.so.5(+0xb0e80) [0x7fec3d4e2e80]
#41  /usr/lib64/libglib-2.0.so.0(+0x56e54) [0x7fec3e112e54]
#42  /usr/lib64/libglib-2.0.so.0(+0x59ee7) [0x7fec3e115ee7]
#43  /usr/lib64/libglib-2.0.so.0(g_main_context_iteration+0x2c) [0x7fec3e1164dc]
#44  0x7fec414daa56 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) from /usr/lib64/libQt5Core.so.5+0x66
#45  0x7fec414895bb in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) from /usr/lib64/libQt5Core.so.5+0x12b
#46  0x7fec414915cd in QCoreApplication::exec() from /usr/lib64/libQt5Core.so.5+0x8d
#47  0x7fec46765e40 in Gui::Application::runApplication() from /home/cory/freecad-build/lib/libFreeCADGui.so+0x2b04
#48  ./bin/FreeCAD(+0x272ca) [0x5583649a42ca]
#49  /lib64/libc.so.6(+0x23f3a) [0x7fec40c63f3a]
#50  /lib64/libc.so.6(__libc_start_main+0x85) [0x7fec40c63ff5]
#51  ./bin/FreeCAD(+0x265c1) [0x5583649a35c1]

Full version info

From the git where I started git bisect good

OS: Gentoo Linux (KDE/plasmawayland)
Word size of FreeCAD: 64-bit
Version: 0.22.0dev.35624 (Git)
Build type: Unknown
Branch: (HEAD detached at 893238c2ab)
Hash: 893238c2ab79eece488a61678525369fc7f4efc8
Python 3.11.7, Qt 5.15.12, Coin 4.0.0, Vtk , OCC 7.7.0
Locale: C/Default (C)
Installed mods: 
  * fasteners 0.4.75
  * kicadStepUpMod 10.22.5

Subproject(s) affected?

None

Anything else?

No response

Code of Conduct

  • I agree to follow this project's Code of Conduct
@maxwxyz maxwxyz added Core Issue or PR touches core sections (App, Gui, Base) of FreeCAD Missing: steps to reproduce Missing: diagnosis labels Feb 22, 2024
@maxwxyz
Copy link
Collaborator

maxwxyz commented Feb 22, 2024

Can you please add steps how to reproduce this? Could you try this with a fresh install?

@clytle374
Copy link
Author

Can you please add steps how to reproduce this? Could you try this with a fresh install?

Click edit in the menu bar, then click Preferences, crash

This was built in a clean build environment and is run in place.

@maxwxyz
Copy link
Collaborator

maxwxyz commented Feb 22, 2024

I cannot reproduce. Can you try this with the lates weekly build?

@maxwxyz maxwxyz added Missing: confirmation Missing confirmation from other testers and removed Missing: steps to reproduce labels Feb 22, 2024
@clytle374
Copy link
Author

I was having an build issue and was discussing it in the forums. Somehow pyside was turned off in cmake(I didn't know it was now an option to not have it) and I got build failures over a missing shiboken module. I turned pyside on and it builds and the the preferences crash went away as the same time.

So I guess this can be closed.

@clytle374
Copy link
Author

Tested a patch for the shiboken module missing from wmayer and that fixes my other build problem with pyside turned off in cmake, but the preferences crash returned. So if pyside is not optional, this is a bug. Try building without pyside and see if you can reproduce it.

@wwmayer
Copy link
Contributor

wwmayer commented Feb 22, 2024

crash went away as the same time.
but the preferences crash returned

I don't think that the crashes are related to the other issue. To me it rather looks like there is an issue that leads to random crashes

@wwmayer wwmayer reopened this Feb 22, 2024
@wwmayer
Copy link
Contributor

wwmayer commented Feb 22, 2024

In PreferencePagePython::loadSettings() after the try you can add this line:
printf("%s\n", page.ptr()->ob_type->tp_name);
Then we would know for which page the crash occurs.

@3x380V
Copy link
Contributor

3x380V commented Feb 22, 2024

Please note there are dozens way to crash FreeCAD when Python interface is used instead PySide C++. It was probably always broken.

@clytle374
Copy link
Author

AddonManagerOptions

Is the only new info from that. Let me know if that helps.

@wwmayer
Copy link
Contributor

wwmayer commented Feb 23, 2024

What happens if you enter this into the Python console of FreeCAD?

import AddonManagerOptions
page = AddonManagerOptions.AddonManagerOptions()
page.loadSettings()

You may test with enabled and disabled PySide.

@3x380V
Copy link
Contributor

3x380V commented Feb 23, 2024

This is one of hacks I'm using. It fixes that crash for me...

@@ -664,12 +668,18 @@ Py::Object PythonWrapper::fromQObject(QObject* object, const char* className)
     throw Py::RuntimeError("Failed to wrap object");
 #else
     // Access shiboken/PySide via Python
-    std::string typeName;
+    std::string typeName, moduleName("QtCore");
     if (className)
         typeName = className;
     else
         typeName = object->metaObject()->className();
-    return qt_wrapInstance<QObject*>(object, typeName, "QtCore");
+
+    // HACK: SEGFAULTs with QtCore...
+    if (typeName == "QAction") {
+      moduleName = "QtGui";
+    }
+
+    return qt_wrapInstance<QObject*>(object, typeName, moduleName);
 #endif

@clytle374
Copy link
Author

What happens if you enter this into the Python console of FreeCAD?

import AddonManagerOptions
page = AddonManagerOptions.AddonManagerOptions()
page.loadSettings()

You may test with enabled and disabled PySide.

When built with or without pyside.

import AddonManagerOptions

Returned the following to the shell FreeCAD was launched in,
(qt.qpa.input.methods) failed to create compose table
The next 2 lines had no output.

@wwmayer
Copy link
Contributor

wwmayer commented Feb 23, 2024

(qt.qpa.input.methods) failed to create compose table

This is a Qt warning and can usually be ignored.

The next 2 lines had no output.

This means that it has just worked. The executed code is basically what happens when loading the preferences and I don't know why it doesn't crash with enabled PySide now.

@clytle374
Copy link
Author

Being that using pyside fixes my issues I am happy to call this closed. If you want me to test more let me know what to do.

@3x380V
Copy link
Contributor

3x380V commented Feb 23, 2024

Please do not add more confusion to the issue. Problem is still there and existed even before ac6f991 Only very few people are not using Shiboken/PySide, so it stays hidden. You may want to try hack I posted earlier.

@clytle374
Copy link
Author

Please do not add more confusion to the issue. Problem is still there and existed even before ac6f991 Only very few people are not using Shiboken/PySide, so it stays hidden. You may want to try hack I posted earlier.

I'm not trying to add any confusion. I was just trying to be helpful offering to test. I did not know there was an issue with building without pyside, I didn't even know it was possible, not sure how I got into that state actually. The only thing I was referring to is opening preferences crashing FreeCAD which starts on my machine with ac6f991. If I can help fine, if I can't that's fine too.

@3x380V
Copy link
Contributor

3x380V commented Feb 23, 2024

Mentioned commit is just moving ifdeffery into qt_getCppType. How did you end having HAVE_PYSIDE and HAVE_SHIBOKEN undefined?

@wwmayer
Copy link
Contributor

wwmayer commented Feb 23, 2024

For testing purposes I have un-commented the line #undef HAVE_PYSIDE2. Now when opening the preferences I can confirm the crash.

You may want to try hack I posted earlier.

Your hack doesn't work for me because the method fromQObject() is not even called when opening the preferences.

Problem is still there and existed even before

The problem is fairly new. Since the beginning of the year there were done quite some changes to PythonWrapper.cpp. So, for testing purposes I switched back to the state of November 2023 and there it worked correctly, i.e. in both cases where HAVE_PYSIDE2 is set or unset the preferences could be loaded without problems.

@wwmayer
Copy link
Contributor

wwmayer commented Feb 23, 2024

After doing some manual bisecting I can confirm that the change to blame is: ac6f991

@wwmayer
Copy link
Contributor

wwmayer commented Feb 23, 2024

After looking at the code changes it was fairly easy to identify the culprit. It's this line:
void* ptr = qt_getCppPointer(Py::asObject(pyobj), shiboken, "getCppPointer");

For Python objects that are not controlled by youPy::asObject() mustn't be used because it's known that it steals a reference. Instead Py::Object() must be used. So, what happened is that the ref counter of the passed Python object has reached zero and was garbage collected before accessing it again.

@3x380V
Copy link
Contributor

3x380V commented Feb 23, 2024

Let me test it with both Qt5 and Qt6. I'll prepare a fix afterwards.

@wwmayer
Copy link
Contributor

wwmayer commented Feb 23, 2024

This change will fix it:

@@ -457,7 +458,7 @@ qttype* qt_getCppType(PyObject* pyobj)
     Py::Callable func = mainmod.getDict().getItem("getCppPointer");
 
     Py::Tuple arguments(1);
-    arguments[0] = Py::asObject(pyobj); // PySide pointer
+    arguments[0] = Py::Object(pyobj); // PySide pointer
     Py::Tuple result(func.apply(arguments));
     return reinterpret_cast<qttype*>(PyLong_AsVoidPtr(result[0].ptr()));
 }

@3x380V
Copy link
Contributor

3x380V commented Feb 23, 2024

Offending patch coalesced everything to Py::asObject, proposed fix uses Py::Object. Will not that break anything else? See:
ac6f991#diff-082ae745627da191ddc0452ff909d4158440ea7f1f1d50059ebc32f8a180e7c6L554
ac6f991#diff-082ae745627da191ddc0452ff909d4158440ea7f1f1d50059ebc32f8a180e7c6L572

@wwmayer
Copy link
Contributor

wwmayer commented Feb 23, 2024

Currently, Py::asObject is used correctly except for this case. Py::Object is used correctly everywhere as far as I can see

@3x380V
Copy link
Contributor

3x380V commented Feb 23, 2024

Hmm, okay. Both toQGraphicsItem and toQGraphicsObject where Py::asObject was used are called only from methods in src/Gui/PythonWrapper.cpp and those seem not to be called from anywhere, so even if that was wrong, it didn't matter. I'll prepare a PR.

@wwmayer
Copy link
Contributor

wwmayer commented Feb 23, 2024

Both toQGraphicsItem and toQGraphicsObject where Py::asObject was used

Yes, and this was wrong. I have written some test code to confirm that it will crash.

@3x380V
Copy link
Contributor

3x380V commented Feb 23, 2024

Okay. Unfortunately that ungly hack is still needed, otherwise just opening Draft WB ends with:

Program received signal SIGSEGV, Segmentation fault.
#0  /lib/x86_64-linux-gnu/libc.so.6(+0x3c050) [0x7f7671c5b050]
#1  /usr/local/lib/python3.11/dist-packages/shiboken6/Shiboken.abi3.so(+0x2d8e) [0x7f766c107d8e]
#2  /lib/x86_64-linux-gnu/libpython3.11.so.1.0(+0x1c9ba1) [0x7f76735c9ba1]
#3  /lib/x86_64-linux-gnu/libpython3.11.so.1.0(_PyObject_Call+0x54) [0x7f767357f014]
#4  0x7f7676962e57 in Py::Callable::apply(Py::Tuple const&) const from /home/ladis/src/FreeCAD-build/lib/libFreeCADGui.so+0x3b
#5  0x7f7677199e15 in Py::Object Gui::qt_wrapInstance<QObject*>(QObject*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) from /home/ladis/src/FreeCAD-build/lib/libFreeCADGui.so+0x24a
#6  0x7f7677197460 in Gui::PythonWrapper::fromQObject(QObject*, char const*) from /home/ladis/src/FreeCAD-build/lib/libFreeCADGui.so+0xc4
#7  0x7f7676b8bca6 in Gui::CommandPy::getAction(_object*) from /home/ladis/src/FreeCAD-build/lib/libFreeCADGui.so+0x1bc
#8  0x7f7676b898fb in Gui::CommandPy::staticCallback_getAction(_object*, _object*) from /home/ladis/src/FreeCAD-build/lib/libFreeCADGui.so+0xf3
#9  /lib/x86_64-linux-gnu/libpython3.11.so.1.0(+0x1c9ba1) [0x7f76735c9ba1]
#10  /lib/x86_64-linux-gnu/libpython3.11.so.1.0(_PyObject_MakeTpCall+0x7d) [0x7f767357be8d]
#11  /lib/x86_64-linux-gnu/libpython3.11.so.1.0(_PyEval_EvalFrameDefault+0x4a63) [0x7f7673509c63]
#12  /lib/x86_64-linux-gnu/libpython3.11.so.1.0(+0x26ab4a) [0x7f767366ab4a]
#13  0x7f761d713287 in PySide::SignalManager::callPythonMetaMethod(QMetaMethod const&, void**, _object*, bool) from /usr/local/lib/python3.11/dist-packages/PySide6/libpyside6.abi3.so.6.4+0x1cf
#14  /usr/local/lib/python3.11/dist-packages/PySide6/libpyside6.abi3.so.6.4(+0x199b8) [0x7f761d7169b8]
#15  /lib/x86_64-linux-gnu/libQt6Core.so.6(+0x16cc18) [0x7f7671f6cc18]
#16  0x7f7671f70d7a in QTimer::timeout(QTimer::QPrivateSignal) from /lib/x86_64-linux-gnu/libQt6Core.so.6+0x3a
#17  /usr/local/lib/python3.11/dist-packages/PySide6/QtCore.abi3.so(+0x27c342) [0x7f75cf27c342]
#18  0x7f7671f5f8de in QObject::event(QEvent*) from /lib/x86_64-linux-gnu/libQt6Core.so.6+0x1ce
#19  /usr/local/lib/python3.11/dist-packages/PySide6/QtCore.abi3.so(+0x27bff0) [0x7f75cf27bff0]
#20  0x7f7672d82a53 in QApplicationPrivate::notify_helper(QObject*, QEvent*) from /lib/x86_64-linux-gnu/libQt6Widgets.so.6+0x93
#21  0x7f7676aab365 in Gui::GUIApplication::notify(QObject*, QEvent*) from /home/ladis/src/FreeCAD-build/lib/libFreeCADGui.so+0xff
#22  0x7f7671f238b8 in QCoreApplication::notifyInternal2(QObject*, QEvent*) from /lib/x86_64-linux-gnu/libQt6Core.so.6+0x118
#23  0x7f7672058689 in QTimerInfoList::activateTimers() from /lib/x86_64-linux-gnu/libQt6Core.so.6+0x309
#24  /lib/x86_64-linux-gnu/libQt6Core.so.6(+0x30a32c) [0x7f767210a32c]
#25  /lib/x86_64-linux-gnu/libglib-2.0.so.0(g_main_context_dispatch+0x299) [0x7f76707da7a9]
#26  /lib/x86_64-linux-gnu/libglib-2.0.so.0(+0x54a38) [0x7f76707daa38]
#27  /lib/x86_64-linux-gnu/libglib-2.0.so.0(g_main_context_iteration+0x2c) [0x7f76707daacc]
#28  0x7f7672107f7c in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) from /lib/x86_64-linux-gnu/libQt6Core.so.6+0x6c
#29  0x7f7671f2d57a in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) from /lib/x86_64-linux-gnu/libQt6Core.so.6+0x2aa
#30  0x7f7671f266a8 in QCoreApplication::exec() from /lib/x86_64-linux-gnu/libQt6Core.so.6+0x98
#31  0x7f767695d0d4 in Gui::Application::runApplication() from /home/ladis/src/FreeCAD-build/lib/libFreeCADGui.so+0xa20
#32  ./bin/FreeCAD(+0x2e5ec) [0x561030c7d5ec]
#33  /lib/x86_64-linux-gnu/libc.so.6(+0x2724a) [0x7f7671c4624a]
#34  /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x85) [0x7f7671c46305]
#35  ./bin/FreeCAD(+0x2d801) [0x561030c7c801]

Hack updated:

diff --git a/src/Gui/PythonWrapper.cpp b/src/Gui/PythonWrapper.cpp
index e2128e3ec0..6a7c4d250e 100644
--- a/src/Gui/PythonWrapper.cpp
+++ b/src/Gui/PythonWrapper.cpp
@@ -687,7 +687,7 @@ Py::Object PythonWrapper::fromQObject(QObject* object, const char* className)
     throw Py::RuntimeError("Failed to wrap object");
 #else
     // Access shiboken/PySide via Python
-    std::string typeName;
+    std::string typeName, moduleName("QtCore");
     if (className) {
         typeName = className;
     }
@@ -695,7 +695,12 @@ Py::Object PythonWrapper::fromQObject(QObject* object, const char* className)
         typeName = object->metaObject()->className();
     }
 
-    return qt_wrapInstance<QObject*>(object, typeName, "QtCore");
+    // HACK: SEGFAULTs with QtCore...
+    if (typeName == "QAction") {
+      moduleName = "QtGui";
+    }
+
+    return qt_wrapInstance<QObject*>(object, typeName, moduleName);
 #endif
 }
 

I have no clue, what the culprit is.

Anyway, fix at #12576

@wwmayer
Copy link
Contributor

wwmayer commented Feb 24, 2024

Unfortunately that ungly hack is still needed, otherwise just opening Draft WB ends with:

Ah, good to know that. I can confirm this crash, too. To fix it two things must be done:

  1. Implement a method PythonWrapper::fromQAction(QAction* action) and use this in CommandPy::getAction
  2. The reason of the crash is that the Python package QtCore has no class QAction (but QtGui does). Because of this the call of qtmod.getDict().getItem(className); returns a Py::Object where the internal pointer is null. This null pointer will be passed to shiboken.wrapInstance and causes the crash. So, qt_wrapInstance should be changed to immediately return Py::None() in this case.

@3x380V
Copy link
Contributor

3x380V commented Feb 24, 2024

Thank you! I will implement above (and then happily start using Qt6 builds).

@3x380V
Copy link
Contributor

3x380V commented Feb 25, 2024

  1. Is implemented by Gui: PythonWrapper::fromQAction #12577
  2. Probably needs a bit more care. The PythonWrapper::fromQ... PySide methods are throwing exception when wrapping fails. So either they should also just return Py::None() or not PySide case (qt_wrapInstance) should be changed to throw exception too. Looking at the call sites, second option is most likely correct, but I'm not familiar with that code. Also it seems that passing null to those functions is likely to be wrong. There is a risk to hit a difference between what code does and what was intended to do. Any help to understand that appreciated.

@wwmayer
Copy link
Contributor

wwmayer commented Feb 25, 2024

should be changed to throw exception too

That's then the preferred way.

Also it seems that passing null to those functions is likely to be wrong. There is a risk to hit a difference between what code does and what was intended to do. Any help to understand that appreciated.

This behaviour (to return Py::Object with a null pointer) is defined by the PyCXX library and we have to deal with it

@3x380V
Copy link
Contributor

3x380V commented Feb 25, 2024

To clarify, I meant passing null to PythonWrapper::fromQ... family of methods. See fromQPrinter or fromQObject.

@wwmayer
Copy link
Contributor

wwmayer commented Feb 25, 2024

I see. This part has to be kept because it's not error handling but a valid use case.

There are cases where C++'s null pointer is equivalent to Python's None, e.g. the method setParent() accepts a null pointer in C++ or None in Python to clear the parenthood.

QObject* parent = ... // can be null
PythonWrapper wrap;
Py::Tuple args(1);
args[0] = wrap.fromQObject(parent);

Py::Object object(...);
object.callMemberFunction("setParent", args);

@3x380V
Copy link
Contributor

3x380V commented Feb 25, 2024

Thank you. However it does not explain fromQPrinter implementation. Here I do not know whenever it is intentional or copy&paste from other method. fromQPrinter does:

  • return Py::None() if printer is null, that seems invalid for printer.
  • obtain Python type object using typeForTypeName(typeid(qttype).name()) as others and if that fails try
    getPythonTypeObject("QPrinter"). So typeForTypeName was failing sometimes?

Shall I add more cleanup patches to #12577 or open another one once it gets merged?

@3x380V
Copy link
Contributor

3x380V commented Feb 26, 2024

Being that using pyside fixes my issues I am happy to call this closed. If you want me to test more let me know what to do.

@clytle374, could you test #12576 without PySide again, so this issue can be closed? I propose to continue in #12577 with remaining issues.

@luzpaz luzpaz changed the title EDIT => Preferences crashes at commit ac6f991baff6a536c2768f9d8b9468e028c91575 [Problem] EDIT => Preferences crashes at commit ac6f991ba Feb 26, 2024
@clytle374
Copy link
Author

I will test it out in a couple days as I can't get to the computer

@luzpaz
Copy link
Contributor

luzpaz commented Mar 2, 2024

@clytle374 ping

@luzpaz luzpaz added the Missing: feedback If feedback is requested label Mar 2, 2024
@wwmayer
Copy link
Contributor

wwmayer commented Mar 3, 2024

@clytle374
Please test with the latest sources. The issue should be fixed now.

@clytle374
Copy link
Author

My apologies, life got in the way.

The current source works properly with Pyside turned off.
Thanks!

@wwmayer
Copy link
Contributor

wwmayer commented Mar 3, 2024

Fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Core Issue or PR touches core sections (App, Gui, Base) of FreeCAD Missing: confirmation Missing confirmation from other testers Missing: diagnosis Missing: feedback If feedback is requested
Projects
None yet
Development

No branches or pull requests

5 participants