Segmentation fault in nested QOpenGLWidget
-
Hello.
I write this post because I am really depleted of ideas. I have desktop application that has mainQWindowwith nestedQOpenGLWidgetwindow. Earlier to handle all this OpenGL stuff I used glut lib hovewere finally I growed up to get rid of it.
Problem is now when I run my app, on the very beginnng I have segmentation fault and I really don't know why.int main(int argc, char *argv[]) { QApplication a(argc, argv); //the same version of context for all GL widgets QSurfaceFormat format; format.setDepthBufferSize(24); format.setStencilBufferSize(8); format.setVersion(4, 5); format.setProfile(QSurfaceFormat::CoreProfile); QSurfaceFormat::setDefaultFormat(format); //restores std::stof divides numbers by '.' instead of local std::setlocale(LC_ALL, "C"); if (argc > 2 && std::string(argv[1]) == "--config") { Config(std::string(argv[2])); } else { Config(); } //creation and displaying main window MainWindow w = new MainWindow(); w.show(); //<------ somwhere below segmentation happens return a.exec(); }Main window looks like this:
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow) { inpMan = &ObjManager::getInstance(); tm = &TimelapseManager::getInstance(); ui->setupUi(this); oglWindow = std::make_unique<OGLWindow>(qobject_cast<OGLWindow*>(ui->oglWindow)); if (!oglWindow) { oglWindow = std::make_unique<OGLWindow>(new OGLWindow(this)); ui->oglWindow->setParent(nullptr); ui->oglWindow->deleteLater(); ui->centralwidget->layout()->addWidget(oglWindow.get()); } initGUI(); enableUIElements(false); // glutInit(argc, argv); //<----remnant of glut }segmentation happens when
w.show()is proceeded and statck trace looks like this:1 QOpenGLContext::functions() const 0x7ffe7131809a 2 QOpenGLWidget::qt_static_metacall(QObject *, QMetaObject::Call, int, void * *) 0x7ffeb7f921da 3 QOpenGLWidget::makeCurrent(QOpenGLWidget::TargetBuffer) 0x7ffeb7f93798 4 QWidget::event(QEvent *) 0x7ffe72f09d90 5 QApplicationPrivate::notify_helper(QObject *, QEvent *) 0x7ffe72eb5b5c 6 QCoreApplication::notifyInternal2(QObject *, QEvent *) 0x7ffe71aa73aa 7 QWidgetPrivate::sendPaintEvent(QRegion const&) 0x7ffe72f0113e 8 QOpenGLWidget::resizeEvent(QResizeEvent *) 0x7ffeb7f92fea 9 QWidget::event(QEvent *) 0x7ffe72f0a417 10 QApplicationPrivate::notify_helper(QObject *, QEvent *) 0x7ffe72eb5b5c 11 QCoreApplication::notifyInternal2(QObject *, QEvent *) 0x7ffe71aa73aa 12 QWidgetPrivate::sendPendingMoveAndResizeEvents(bool, bool) 0x7ffe72f0105b 13 QWidgetPrivate::show_helper() 0x7ffe72f06349 14 QWidgetPrivate::setVisible(bool) 0x7ffe72f094a4 15 QWidgetPrivate::showChildren(bool) 0x7ffe72f05df1 16 QWidgetPrivate::show_helper() 0x7ffe72f06366 17 QWidgetPrivate::setVisible(bool) 0x7ffe72f094a4 18 QWidgetPrivate::showChildren(bool) 0x7ffe72f05df1 19 QWidgetPrivate::show_helper() 0x7ffe72f06366 20 QWidgetPrivate::setVisible(bool) 0x7ffe72f094a4 21 main main.cpp 33 0x7ff641ae586fIt tells me something is with context but what? During debug everything is initialized in my
OGLWindow::OGLWindow(QWidget *parent):QOpenGLWidget(parent)window properlyvoid OGLWindow::initializeGL() { initializeOpenGLFunctions(); glEnable(GL_PROGRAM_POINT_SIZE); glEnable(GL_DEPTH_TEST); glEnable(GL_BLEND); createShaders(); fillBufferCross(); fillBufferScale(); }What I miss?
-
Hi and welcome to devnet,
The first thing I would do: remove all these smart pointers. They don't play well with Qt's parent child paradigm.
Then, which version of Qt are you using ?
Which OS are you running ? -
Hi SGaist.
Win10, 64 bits, Qt 6.10.1.
I work under VS Code.This is my CMakeLists
cmake_minimum_required(VERSION 4.2) if(POLICY CMP0167) cmake_policy(SET CMP0167 OLD) endif() project ( RadarVis ) # C++17 is needed because of toml++ set(CMAKE_CXX_STANDARD 17) if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Debug CACHE STRING "Build type" FORCE) endif() # Flagi kompilatora dla trybu Debug (MinGW / GCC) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -O0 -DDEBUG") # Instruct CMake to run moc automatically when needed. set(CMAKE_AUTOMOC ON) # Instruct CMake to run uic automatically when needed. set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOUIC_SEARCH_PATHS ui/custom ui/window) set(CPP_LIBS "e:/storage/cpp/libs") set(BOOST_ROOT "${CPP_LIBS}/boost") set(BOOST_INCLUDEDIR "${BOOST_ROOT}") set(BOOST_LIBRARYDIR "${BOOST_ROOT}/libs") set(Boost_NO_SYSTEM_PATHS ON) find_package(Boost REQUIRED) set(Qt6_DIR "e:/storage/cpp/Qt/6.10.1/mingw_64/lib/cmake/Qt6") find_package(Qt6 COMPONENTS Core Widgets OpenGLWidgets Gui REQUIRED) find_package(OpenGL REQUIRED) file(GLOB_RECURSE SOURCES "src/*.cpp") file(GLOB_RECURSE HEADERS "config/*.h" "gui/*.h" "input/*.h" "scene/*.h") file(GLOB_RECURSE UI "ui/**/*.ui") set(TARGET_NAME radarvis) add_executable( ${TARGET_NAME} ${SOURCES} ${HEADERS} ${UI} ) target_compile_definitions(${TARGET_NAME} PRIVATE WIN32_LEAN_AND_MEAN ) target_include_directories( ${TARGET_NAME} PRIVATE ${Boost_INCLUDE_DIRS} ${CPP_LIBS}/glm ) target_link_libraries( ${TARGET_NAME} PRIVATE Qt6::Core Qt6::Widgets Qt6::OpenGLWidgets Qt6::Gui OpenGL::GL opengl32 ${Boost_LIBRARIES} ws2_32 )Your statement about smart pointers suprises me. Whole world says something quiet oposite: use them man, use them!
Can you extend it little bit? How can it interfere with inheritance? Finally smart pointer is just a wrapped pointer. -
Hi SGaist.
Win10, 64 bits, Qt 6.10.1.
I work under VS Code.This is my CMakeLists
cmake_minimum_required(VERSION 4.2) if(POLICY CMP0167) cmake_policy(SET CMP0167 OLD) endif() project ( RadarVis ) # C++17 is needed because of toml++ set(CMAKE_CXX_STANDARD 17) if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Debug CACHE STRING "Build type" FORCE) endif() # Flagi kompilatora dla trybu Debug (MinGW / GCC) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -O0 -DDEBUG") # Instruct CMake to run moc automatically when needed. set(CMAKE_AUTOMOC ON) # Instruct CMake to run uic automatically when needed. set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOUIC_SEARCH_PATHS ui/custom ui/window) set(CPP_LIBS "e:/storage/cpp/libs") set(BOOST_ROOT "${CPP_LIBS}/boost") set(BOOST_INCLUDEDIR "${BOOST_ROOT}") set(BOOST_LIBRARYDIR "${BOOST_ROOT}/libs") set(Boost_NO_SYSTEM_PATHS ON) find_package(Boost REQUIRED) set(Qt6_DIR "e:/storage/cpp/Qt/6.10.1/mingw_64/lib/cmake/Qt6") find_package(Qt6 COMPONENTS Core Widgets OpenGLWidgets Gui REQUIRED) find_package(OpenGL REQUIRED) file(GLOB_RECURSE SOURCES "src/*.cpp") file(GLOB_RECURSE HEADERS "config/*.h" "gui/*.h" "input/*.h" "scene/*.h") file(GLOB_RECURSE UI "ui/**/*.ui") set(TARGET_NAME radarvis) add_executable( ${TARGET_NAME} ${SOURCES} ${HEADERS} ${UI} ) target_compile_definitions(${TARGET_NAME} PRIVATE WIN32_LEAN_AND_MEAN ) target_include_directories( ${TARGET_NAME} PRIVATE ${Boost_INCLUDE_DIRS} ${CPP_LIBS}/glm ) target_link_libraries( ${TARGET_NAME} PRIVATE Qt6::Core Qt6::Widgets Qt6::OpenGLWidgets Qt6::Gui OpenGL::GL opengl32 ${Boost_LIBRARIES} ws2_32 )Your statement about smart pointers suprises me. Whole world says something quiet oposite: use them man, use them!
Can you extend it little bit? How can it interfere with inheritance? Finally smart pointer is just a wrapped pointer.@Riwar said in Segmentation fault in nested QOpenGLWidget:
Your statement about smart pointers suprises me. Whole world says something quiet oposite: use them man, use them!
Can you extend it little bit? How can it interfere with inheritance? Finally smart pointer is just a wrapped pointer.Bjarne himself recommends them but also states that as with every other tool, you have to understand when to not use them as well.
In the case of Qt, see Object Trees & Ownership. Qt has managed the lifetime of its QObject based classes way before C++ got all these smart pointers hence their are not an appropriate tool in this context. You will get things like double deletion happening. I am not saying that this is the cause in your case as your code sample is not complete enough to test but it wont hurt to remove these. Note that there's nothing wrong with using them alongside Qt for other objects lifetime management.
-
FIY
std::make_uniquedoesn't take a pointer and make it unique, it creates a new object and return it in aunique_ptr.Your code regarding
oglWindowis very confusing. -
FIY
std::make_uniquedoesn't take a pointer and make it unique, it creates a new object and return it in aunique_ptr.Your code regarding
oglWindowis very confusing.@GrecKo Yes. You are right about
make_unique.
This is kind of experiment. Whole this block about oglWindow is trial of replacement object done by designer with own one. At some moment I had impression the reason may whole window is not initialized at this very moment. However it acts exactly in the same manner. I will clean this.I used gdb and it clearly shows:
Thread 1 received signal SIGSEGV, Segmentation fault.
0x00007ffe8440809a in QOpenGLContext::functions() const () from E:\c++\RadarVis_6\app\Qt6Gui.dll -
I see I cant edit such old posts. Then main window should looks like this
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow) { inpMan = &ObjManager::getInstance(); tm = &TimelapseManager::getInstance(); ui->setupUi(this); initGUI(); enableUIElements(false); } -
Without a proper minimal compilable reproducer, it's going to be close to impossible to find what goes wrong.
-
Without a proper minimal compilable reproducer, it's going to be close to impossible to find what goes wrong.