SIGSEGV, andere Fehler... Vielleicht durch implicit sharing?
Verfasst: 21. August 2012 09:48
Hallo!
Ich bekomme beim Ausführen meines Programms häufig SIGSEGV (segmentation fault), aber auch “Invalid address specified to RtlFreeHeap”, “Heap corruption detected at …” oder “
nternal error: pc 0xff in read in psymtab, but not in symtab.)”. Leider sind diese Fehler kaum reproduzierbar, treten an unterschiedlichen Stellen im Code einer Funktion sowie nach unterschiedlichen (Lauf-)zeitspannen auf. Ich poste euch einfach mal den Code, wo die Fehler auftreten:
Hier noch dei Funktion Screenshot(), aber ich glaube an ihr liegt es nicht (die Fehler treten auch alle in Aktualisierung() (s.o.) auf):
Meist treten die Fehler bei QLabel->setPixmap auf und zwar (nach meinem Verständnis des Stacks) bei der Freigabe der vorherigen Daten im Zuge der Neuzuweisung.
Der Stack sieht dann z.B. (bei "Heap block at 0BE2FCD8 modified at 0BE2FCC4 past requested size of ffffffe4" an oben markierter Stelle) so aus:
Habe mich also ein bisschen mit der Speicherverwaltung Beschäftigt und bin dabei auf "Implicit sharing" von Qt gestoßen. Könnte es sein, dass sich 'Zwischenspeicher' (QPixmap) und das QPixmap vom QLabel die Daten nach setPixmap() teilen, am Ende des scope's aber die daten (weil Zwischenspeicher "abgelaufen" ist) zerstört werden und daher der Speicher der alten Daten bei dem nächsten setPixmap() nicht freigegeben werden kann?
Ich hoffe jemand kann etwas mit dieser Fehlerdarstellung anfangen und mir weiterhelfen.
Danke schonmal!
Gruß Jake2012
Ich bekomme beim Ausführen meines Programms häufig SIGSEGV (segmentation fault), aber auch “Invalid address specified to RtlFreeHeap”, “Heap corruption detected at …” oder “
Code: Alles auswählen
void MainWindow::Aktualisierung(void)
{
verstrichene_wartezeit += Timer1->interval();
ui->label_20->setText(QString("Verstrichene Wartezeit: %1 Sekunden").arg(verstrichene_wartezeit/1000));
//Bildverarbeitung starten
QPixmap Zwischenspeicher = this->Screenshot();
if(!Zwischenspeicher.isNull())
{
//Große Vorschau darstellen
if(ui->checkBox->isChecked())
{
ui->label->setPixmap(Zwischenspeicher);
}
//Zwischenspeicher skalieren
Zwischenspeicher = Zwischenspeicher.copy(QRect(ui->verticalSlider->value() - ui->horizontalSlider->value()/2, ui->verticalSlider_2->value() - ui->horizontalSlider->value()/2, ui->horizontalSlider->value(), ui->horizontalSlider->value()));
//Vorschau darstellen
if(ui->checkBox_2->isChecked())
{
ui->label_3->setPixmap(Zwischenspeicher); //<--- Fehler tritt u.a. hier auf
}
//skalieren
Zwischenspeicher = Zwischenspeicher.scaledToHeight(ui->spinBox->value(), Qt::FastTransformation);
QImage Bild = Zwischenspeicher.toImage();
if(!Bild.isNull())
{
Bild = Bild.convertToFormat(QImage::Format_Mono, Qt::MonoOnly);
if(Zwischenspeicher.convertFromImage(Bild, Qt::AutoColor))
{
//darstellen
if(ui->checkBox_3->isChecked())
{
ui->label_5->setPixmap(Zwischenspeicher);
}
unsigned int whitePixels = 0;
//Pixel analysieren
for(int i=0; i < ui->spinBox->value(); i++)
{
for(int j=0; j < ui->spinBox->value(); j++)
{
if((int)Bild.pixel(i, j) & 0xFFFFFF)
{
whitePixels++;
}
}
}
//Weißwert anzeigen
ui->label_12->setText(QString("Weißwert: %1%").arg((whitePixels*100)/(ui->spinBox->value()*ui->spinBox->value())));
}
else
{
qDebug("Zwischenspeicher = 0 nach .convertFromImage()");
}
}
else
{
qDebug("Bild = 0 nach .toImage()");
}
}
else
{
qDebug("Zwischenspeicher = 0 nach Screenshot()");
}
}Code: Alles auswählen
QPixmap MainWindow::Screenshot(void)
{
HWND Fenster = FindWindow(NULL, (LPCWSTR)Fenstername.utf16());
if(Fenster)
{
HDC winDC = GetDC(Fenster);
HDC memDC = CreateCompatibleDC(winDC);
RECT rc;
GetClientRect(Fenster, &rc);
HBITMAP hbitmap = CreateCompatibleBitmap(winDC, rc.right-rc.left, rc.bottom-rc.top);
SelectObject(memDC, hbitmap);
BitBlt(memDC, 0, 0, rc.right-rc.left, rc.bottom-rc.top, winDC, 0, 0, SRCCOPY);
QPixmap Pixelkarte = QPixmap::fromWinHBITMAP(hbitmap, QPixmap::NoAlpha);
ReleaseDC(Fenster, winDC);
DeleteDC(memDC);
DeleteObject(hbitmap);
return Pixelkarte;
}
else
{
return QPixmap();
}
}Der Stack sieht dann z.B. (bei "Heap block at 0BE2FCD8 modified at 0BE2FCC4 past requested size of ffffffe4" an oben markierter Stelle) so aus:
Code: Alles auswählen
0 ntdll!DbgUiConnectToDbg C:\WINDOWS\system32\ntdll.dll 0
1 ntdll!RtlpNtMakeTemporaryKey C:\WINDOWS\system32\ntdll.dll 0
2 ntdll!RtlZeroHeap C:\WINDOWS\system32\ntdll.dll 0
3 ?? 0
4 ntdll!RtlpNtMakeTemporaryKey C:\WINDOWS\system32\ntdll.dll 0
5 ntdll!RtlpNtMakeTemporaryKey C:\WINDOWS\system32\ntdll.dll 0
6 ntdll!LdrFindEntryForAddress C:\WINDOWS\system32\ntdll.dll 0
7 ?? 0
8 ntdll!RtlpUnWaitCriticalSection C:\WINDOWS\system32\ntdll.dll 0
9 msvcrt!free C:\WINDOWS\system32\msvcrt.dll 0
10 ?? 0
11 QImageData::~QImageData qimage.cpp 226
12 QImage::~QImage qimage.cpp 1283
13 QRasterPixmapData::~QRasterPixmapData qpixmap_raster.cpp 95
14 QExplicitlySharedDataPointer<QPixmapData>::~QExplicitlySharedDataPointer qshareddata.h 166
15 QPixmap::~QPixmap qpixmap.cpp 350
16 QLabelPrivate::clearContents qlabel.cpp 1382
17 QLabel::setPixmap qlabel.cpp 425
18 MainWindow::Aktualisierung mainwindow.cpp 151
19 MainWindow::qt_static_metacall moc_mainwindow.cpp 75
20 QMetaObject::activate qobject.cpp 3547
21 QTimer::timeout moc_qtimer.cpp 148
22 QTimer::timerEvent qtimer.cpp 280
23 QObject::event qobject.cpp 1157
24 QApplicationPrivate::notify_helper qapplication.cpp 4554
25 QApplication::notify qapplication.cpp 3936
26 QCoreApplication::notifyInternal qcoreapplication.cpp 876
27 QCoreApplication::sendEvent qcoreapplication.h 231
28 QEventDispatcherWin32Private::sendTimerEvent qeventdispatcher_win.cpp 642
29 qt_internal_proc qeventdispatcher_win.cpp 501
30 USER32!GetDC C:\WINDOWS\system32\user32.dll 0
31 ?? 0
32 ?? qlist.h 692
33 ?? qstring.h 880
34 qt_fast_timer_proc qeventdispatcher_win.cpp 428
Ich hoffe jemand kann etwas mit dieser Fehlerdarstellung anfangen und mir weiterhelfen.
Danke schonmal!
Gruß Jake2012