Unsolved SIGSEGV QLabel->setPixmap(QPixmap::fromImage(.));
Good morning everyone,
I hope someone can help me since other similar posts have not been helpful.
I am currently working on an Linux embedded system that runs qt code and which reads the signals from two video inputs in parallel (dev0, dev1)
and projects them to video using Qlabels.
For some strange reason the code crashes when setPixmap is executed.
I am using the v4l2 driver to read video signals in capture mode with mmap configuration.
I tried to debug with gdb but I don't get valid information and the address provided, relative to SIGSEGV, is not valid or not present.
Valgrind is not an option as it is not present in the embedded system.
Thanks in advance for any suggestions. Here part of the code that manages the image.
struct v4l2_buffer v4lbuf; CLEAR(v4lbuf); // Dequeue captured buffer v4lbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; v4lbuf.memory = V4L2_MEMORY_MMAP; v4lbuf.index = bufferIdx%V4L2_BUFF_COUNT; ioctl(devVideo->handle(), VIDIOC_DQBUF, &v4lbuf); buffers->uyvy2rgb(bufferIdx%V4L2_BUFF_COUNT, true); const uchar* rgb = buffers->getRgbBuff(); int bytesPerLine = buffers->getImageSize().width() * 3; int width = buffers->getImageSize().width(); int height = buffers->getImageSize().height(); QImage::Format format = QImage::Format_RGB888; if (rgb) image = QImage(rgb, width, height, bytesPerLine, format); // Queue captured buffer ioctl(devVideo->handle(), VIDIOC_QBUF, &v4lbuf); bufferIdx++; if(bufferIdx == V4L2_BUFF_COUNT) bufferIdx = 0; bufferImage = QImage(image.bits(), width, height, bytesPerLine, format); bufferImage.scaled(buffers->getImageSize().width(), buffers->getImageSize().height(), Qt::KeepAspectRatio); lbl->setPixmap(QPixmap::fromImage(bufferImage.copy()));
The code does not crashe if lbl->setPixmap(QPixmap::fromImage(bufferImage.copy())); is commented.
lbl is pass as QLabel* input
Thanks in advance
JonB last edited by
As @jsulm says. If you want to know why
lbl->setPixmap(QPixmap::fromImage(bufferImage.copy()));causes a SIGSEGV did you at least start by preceding that line with a
Q_ASSERT(lbl)? That is not the whole story --- the pointer could be non-null but pointing to rubbish --- but it is at least one condition which you must check....
Effectively, at the top of that function block I'm checking if the pointer is null but I will give a go using Q_ASSERT() instead. One question, could the problem be related to the image I pass as input? QImage use implicit data sharing and I wonder if can be corrupted, at memory level, in some way during thread process. Thanks for your suggestions.
Based on what you wrote, it seems that all the image processing happens in a different thread and you access a GUI element from that thread. That is strictly forbidden. Use signals and slots to transfer your QImage back to the main thread to put it on your label.
You can see a possible implementation of that in the Qt Mandelbrot example.
@SGaist I think that exactly my issue. I have implemented QMetaObject::invokeMethod() from worker threads but I can easily use signal and slot in case. I will check Monday and see if it solve the issue.
Thanks for the suggestion.