Unsolved QVector<QVector3D>::reallocData segmentation fault (SIGSEGV) in QOpenGlWidget
-
I would ask the community for a help as i can't solve the problem since long time.
Workaround:
I use a simple QOpenGLWidget derived class to display point clouds of measured points. Points are displayed as vertices and a shader program with attributes vertex and color are used. The measurement is continuous and therefore adding subsequent vertices occurs. Containers for vertices and colors are (like in all Qt open samples shown) QVector<QVector3D> m_vertices and QVector<QVector3D> m_colors are used.
Problem:
During append procedure a segmentation fault occur. The reallocData() method of QVector catches an unknown exception:
QT_CATCH (...) { Data::deallocate(x); QT_RETHROW; }
Data::deallocate causes segmentation fault. The reason is that the parameter x has a value of 0x0.
This occur in a Qt::QueuedConnection slot, there the QVector<QVector3D> vertices elements are pushed back to the QVector<QVector3D> m_vertices. QVector m_vertices is in onPaint() method of QOpenGlWidget. Both instances are existing and no other thread (usage of QMutex) is accessing the vectors. instance m_vertices has 5592404 elements and vertices has 738 elements.
Source code:
concerning part of mainwindow.cpp:
connecting in constructor:
QObject::connect(&m_mainCtrl, SIGNAL(vertices_ready_signal(QVector<QVector3D>,QVector<QVector3D>)), this, SLOT(vertices_ready_slot(QVector<QVector3D>,QVector<QVector3D>)), Qt::QueuedConnection);
concerning slot :
void CMainWindow::vertices_ready_slot(QVector<QVector3D> vertices,QVector<QVector3D> colors)
{
if (ui)
{
ui->glWidget->addVertices(vertices, colors);
}
}in header:
public slots:
void vertices_ready_slot(QVector<QVector3D> vertices,QVector<QVector3D> colors);
A OpenGlsWidget derived class header glwidget.h
class GlWidget : public QOpenGLWidget
{
Q_OBJECTpublic:
explicit GlWidget(QWidget *parent = 0);
~GlWidget();
QSize sizeHint() const;bool addVertices(QVector<QVector3D> &vertices, QVector<QVector3D> colors); void remVertices(); void getVertices(QVector<QVector3D> &vertices, QVector<QVector3D> &colors);
public slots:
void setXRotation(int angle); void setYRotation(int angle); void setZRotation(int angle); void setDistance(int dist);
signals:
void xRotationChanged(int angle); void yRotationChanged(int angle); void zRotationChanged(int angle); void distanceChanged(int dist);
protected:
void initializeGL(); void resizeGL(int width, int height); void paintGL(); void mousePressEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *event); void wheelEvent(QWheelEvent *event);
private:
QMatrix4x4 m_pMatrix; QGLShaderProgram m_shaderProgram; QVector<QVector3D> m_vertices; QVector<QVector3D> m_colors; double m_alpha; double m_beta; double m_gamma; double m_dist; QPoint m_lastMousePosition; QVector<QVector3D> m_grid; QVector<QVector3D> m_grid_color; QMutex m_verticesMutex;
};
GlWidget::GlWidget(QWidget *parent)
: QOpenGLWidget(parent)
{
m_alpha = 0;
m_beta = 15;
m_gamma = 325;
m_dist = 115.0;// define the grid m_grid << QVector3D(0, 0, 0) << QVector3D(50, 0, 0) // X << QVector3D(0, 0, 0) << QVector3D(0, 50, 0) // Y << QVector3D(0, 0, 0) << QVector3D(0, 0, 50); // Z m_grid_color << QVector3D(1, 0, 0) << QVector3D(1, 0, 0) // red << QVector3D(0, 1, 0) << QVector3D(0, 1, 0) // green << QVector3D(0, 0, 1) << QVector3D(0, 0, 1); // blue //m_vertices.reserve(PS_MAX_SAVED_VERTICES); m_colors.reserve(PS_MAX_SAVED_VERTICES);
}
GlWidget::~GlWidget()
{
for (int i=0;i<m_shaderProgram.shaders().size();i++)
{
m_shaderProgram.removeShader(m_shaderProgram.shaders()[i]);
}
}QSize GlWidget::sizeHint() const
{
return QSize(640, 480);
}void GlWidget::remVertices()
{
glClearColor(0.267,0.753,0.757,1);m_shaderProgram.release(); m_shaderProgram.disableAttributeArray("vertex"); m_shaderProgram.disableAttributeArray("color"); m_verticesMutex.lock(); m_vertices.clear(); m_colors.clear(); m_verticesMutex.unlock(); repaint();
}
void GlWidget::getVertices(QVector<QVector3D> &vertices, QVector<QVector3D> &colors)
{
m_verticesMutex.lock();vertices = m_vertices; colors = m_colors; m_verticesMutex.unlock();
}
void GlWidget::setXRotation(int angle)
{
m_alpha = PS_MILLI_TO_UNIT * angle;
repaint();
}void GlWidget::setYRotation(int angle)
{
m_beta = PS_MILLI_TO_UNIT * angle;
repaint();
}void GlWidget::setZRotation(int angle)
{
m_gamma = PS_MILLI_TO_UNIT * angle;
repaint();
}void GlWidget::setDistance(int dist)
{
m_dist = PS_MILLI_TO_UNIT * dist;
repaint();
}bool GlWidget::addVertices(QVector<QVector3D> &vertices, QVector<QVector3D> colors)
{
m_verticesMutex.lock();qDebug() << "copying start"; try { for(int i=0;i<vertices.count();i++) { m_vertices.push_back(vertices[i]); m_colors.push_back(colors[i]); } } catch(...) { qDebug() << "adding vertices failed"; } qDebug() << "copying finished"; m_verticesMutex.unlock(); qDebug() << "repainting"; repaint(); return true;
}
//! [0]
void GlWidget::initializeGL()
{
//! [0]
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);glClearColor(0.5,0.5,0.5,1); m_shaderProgram.addShaderFromSourceFile(QGLShader::Vertex, ":/vertexShader.vsh"); m_shaderProgram.addShaderFromSourceFile(QGLShader::Fragment, ":/fragmentShader.fsh"); m_shaderProgram.link(); repaint();
}
void GlWidget::resizeGL(int width, int height)
{
if (height == 0) {
height = 1;
}m_pMatrix.setToIdentity(); m_pMatrix.perspective(60.0, (float) width / (float) height, 0.001, 1000); glViewport(0, 0, width, height);
}
void GlWidget::paintGL()
{
// cleas scressn (gray color)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// define the projection matrix QMatrix4x4 modelViewMatrix; modelViewMatrix.setToIdentity(); modelViewMatrix.lookAt(QVector3D(m_dist, 0, 0),QVector3D(0,0,0),QVector3D(0,0,1.0)); modelViewMatrix.rotate(m_alpha, 1, 0, 0); modelViewMatrix.rotate(m_beta, 0, 1, 0); modelViewMatrix.rotate(m_gamma, 0, 0, 1); // bind the shader program and set projection matrix as an uniform value m_shaderProgram.bind(); m_shaderProgram.setUniformValue("mvpMatrix", m_pMatrix * modelViewMatrix); qDebug() << "binding"; // enable vertex shader m_shaderProgram.enableAttributeArray("vertex"); m_shaderProgram.enableAttributeArray("color"); qDebug() << "arrays enabled"; // draw the x,y and z axles m_shaderProgram.setAttributeArray("vertex", m_grid.constData()); m_shaderProgram.setAttributeArray("color", m_grid_color.constData()); glDrawArrays(GL_LINES, 0, m_grid.size()); qDebug() << "drawing grid"; m_verticesMutex.lock(); m_shaderProgram.setAttributeArray("vertex", m_vertices.constData()); // color from reflectancy m_shaderProgram.setAttributeArray("color", m_colors.constData()); qDebug() << "attribute arrays set"; // draw to canvas qDebug() << "before drawing"; glDrawArrays(GL_POINTS, 0, m_vertices.size()); qDebug() << "after drawing"; m_verticesMutex.unlock(); m_shaderProgram.disableAttributeArray("vertex"); m_shaderProgram.disableAttributeArray("color"); qDebug() << "attribute arrays disabled"; m_shaderProgram.release(); qDebug() << "program released";
}
void GlWidget::mousePressEvent(QMouseEvent *event)
{
m_lastMousePosition = event->pos();event->accept();
}
void GlWidget::mouseMoveEvent(QMouseEvent *event)
{
int deltaX = event->x() - m_lastMousePosition.x();
int deltaY = event->y() - m_lastMousePosition.y();if (event->buttons() & Qt::LeftButton) { m_gamma += deltaX; if (m_gamma < 0) { m_gamma += 360; } if (m_gamma >= 360) { m_gamma -= 360; } m_beta += deltaY; if (m_beta < 0) { m_beta += 360; } if (m_beta >= 360) { m_beta -= 360; } emit zRotationChanged(PS_UNIT_TO_MILLI * m_gamma); emit yRotationChanged(PS_UNIT_TO_MILLI * m_beta); repaint(); } m_lastMousePosition = event->pos(); event->accept();
}
void GlWidget::wheelEvent(QWheelEvent *event)
{
int delta = event->delta();if (event->orientation() == Qt::Vertical) { if (delta < 0) { m_dist *= 1.1; } else if (delta > 0) { m_dist *= 0.9; } repaint(); } emit distanceChanged(PS_UNIT_TO_MILLI * m_dist); event->accept();
}
vertexShader.vsh :
//! [0]
uniform mat4 mvpMatrix;in vec4 vertex;
in vec4 color;out vec4 varyingColor;
void main(void)
{
varyingColor = color;
gl_Position = mvpMatrix * vertex;
}
//! [0]fragmentShader.vsh:
//! [0]
in vec4 varyingColor;out vec4 fragColor;
void main(void)
{
fragColor = varyingColor;
}
//! [0]Call stack:
0 load<int> C:/Qt/5.4/mingw491_32/bin/Qt5Cored.dll 90 0x6ba57902
1 QBasicAtomicInteger<int>::load C:/Qt/5.4/mingw491_32/bin/Qt5Cored.dll 110 0x6ba57902
2 QtPrivate::RefCount::isStatic C:/Qt/5.4/mingw491_32/bin/Qt5Cored.dll 90 0x6ba70a23
3 QArrayData::deallocate C:/Qt/5.4/mingw491_32/bin/Qt5Cored.dll 121 0x6b79a858
4 QTypedArrayData<QVector3D>::deallocate qarraydata.h 222 0x47fb47
5 QVector<QVector3D>::reallocData qvector.h 539 0x4992fe
6 QVector<QVector3D>::append qvector.h 601 0x499513
7 QVector<QVector3D>::push_back qvector.h 224 0x499759
8 GlWidget::addVertices glwidget.cpp 100 0x405d69
9 CMainWindow::vertices_ready_slot CMainWindow.cpp 106 0x4027ed
10 CMainWindow::qt_static_metacall moc_CMainWindow.cpp 138 0x4071c4
11 QMetaCallEvent::placeMetaCall C:/Qt/5.4/mingw491_32/bin/Qt5Cored.dll 485 0x6b953b60
12 QObject::event C:/Qt/5.4/mingw491_32/bin/Qt5Cored.dll 1245 0x6b954925
13 QWidget::event C:/Qt/5.4/mingw491_32/bin/Qt5Widgetsd.dll 9084 0xaba5350
14 QMainWindow::event C:/Qt/5.4/mingw491_32/bin/Qt5Widgetsd.dll 1495 0xacc1f38
15 QApplicationPrivate::notify_helper C:/Qt/5.4/mingw491_32/bin/Qt5Widgetsd.dll 3720 0xab6f4dd
16 QApplication::notify C:/Qt/5.4/mingw491_32/bin/Qt5Widgetsd.dll 3685 0xab6f360
17 QCoreApplication::notifyInternal C:/Qt/5.4/mingw491_32/bin/Qt5Cored.dll 935 0x6b92f330
18 QCoreApplication::sendEvent C:/Qt/5.4/mingw491_32/bin/Qt5Cored.dll 228 0x6b9d542b
19 QCoreApplicationPrivate::sendPostedEvents C:/Qt/5.4/mingw491_32/bin/Qt5Cored.dll 1552 0x6b9304c8
20 QCoreApplication::sendPostedEvents C:/Qt/5.4/mingw491_32/bin/Qt5Cored.dll 1410 0x6b92ffae
21 QWindowsGuiEventDispatcher::sendPostedEvents C:/Qt/5.4/mingw491_32/plugins/platforms/qwindowsd.dll 81 0x6285ee21
22 qt_internal_proc(HWND__ *, unsigned int, unsigned int, long) *16 C:/Qt/5.4/mingw491_32/bin/Qt5Cored.dll 412 0x6b97dae8
23 USER32!SetManipulationInputTarget 0x771ed273
24 USER32!DispatchMessageW 0x771ce84a
25 USER32!DispatchMessageW 0x771ce1a4
26 USER32!DispatchMessageW 0x771cdf60
27 QEventDispatcherWin32::processEvents C:/Qt/5.4/mingw491_32/bin/Qt5Cored.dll 806 0x6b97f1d4
28 QWindowsGuiEventDispatcher::processEvents C:/Qt/5.4/mingw491_32/plugins/platforms/qwindowsd.dll 73 0x6285ecfc
29 QEventLoop::processEvents C:/Qt/5.4/mingw491_32/bin/Qt5Cored.dll 128 0x6b92d3b4
30 QEventLoop::exec C:/Qt/5.4/mingw491_32/bin/Qt5Cored.dll 204 0x6b92d647
31 QCoreApplication::exec C:/Qt/5.4/mingw491_32/bin/Qt5Cored.dll 1188 0x6b92f973
32 QGuiApplication::exec C:/Qt/5.4/mingw491_32/bin/Qt5Guid.dll 1507 0x1666c78
33 QApplication::exec C:/Qt/5.4/mingw491_32/bin/Qt5Widgetsd.dll 2956 0xab6c7ef
34 qMain main.cpp 24 0x4016e1
35 WinMain *16 C:/_projects/PS_LogFile_To3D/50.Program/build-PSLogFileTo3D-Desktop_Qt_5_4_2_MinGW_32bit2-Debug/PSLogFile2PointCloud/debug/PSLogFile2PointCloud.exe 113 0x409220
36 main 0x4ad4fdqDebug() output in application output window:
copying start
copying finished
repainting
binding
arrays enabled
drawing grid
attribute arrays set
before drawing
after drawing
attribute arrays disabled
program released
copying start -
Hi! First thing I noticed:
bool GlWidget::addVertices(QVector<QVector3D> &vertices, QVector<QVector3D> colors) { m_verticesMutex.lock(); qDebug() << "copying start"; try { for(int i=0;i<vertices.count();i++) { m_vertices.push_back(vertices[i]); m_colors.push_back(colors[i]); } }
I don't understand why you're doing it that way. The following would make much more sense to me:
bool GlWidget::addVertices(const QVector<QVector3D> &vertices, const QVector<QVector3D> &colors) { // ... m_vertices = vertices; m_colors = colors; // ... }
-
@CatBehemoth said in QVector<QVector3D>::reallocData segmentation fault (SIGSEGV) in QOpenGlWidget:
QVector<QVector3D>::push_back qvector.h 224 0x499759
You addresses seems a bit short, are you sure you aren't running out of memory? It appears you're running a 32 bit MinGW build, which translates to an absolute maximum of 3GB memory for the program (and the OS if your windows is 32bit as well).
-
@Wieland thank you for an answer. Anyway, the system should add the current measurement data to the entire set. A 2D sensor is scanning profiles and during its rotation or movement are single profiles added to the 3D point cloud.
So the idea is: m_vertices += vertices (same for colors)
-
@kshegunov Well, you are right, it is a MinGw32 build, and it was my first thought, but the application doesn't exceed 0,8 GB and the vector m_vertices (where the crash occurs) has 5592404 elements of QVector3D (12 bytes - 3 floats x,y, and z) so it is about 64 MB.
I can't use the 64 bit version as the application has to run on the older platforms too.