Stack Buffer Overrun in Qt [2 Qt Bugtests included]

Alles rund um die Programmierung mit Qt
Antworten
CLRS530
Beiträge: 155
Registriert: 8. Oktober 2007 18:00

Stack Buffer Overrun in Qt [2 Qt Bugtests included]

Beitrag von CLRS530 »

Hi Leute,
das gleiche Problem, welches ich in meinem letzten Thread angesprochen habe, jedoch hat es einen anderen Ursprung. Es wird ein Problem sein, wo mir vielleicht nur eine Handvoll Leute eventuell weiterhelfen können, aber ich werde es versuchen.
Zuerst einmal die Meldung im Application Output vom QtCreator.

Code: Alles auswählen

warning: Lowest section in C:\\WINDOWS\\system32\\xpsp2res.dll is .rsrc at 00011000
warning:
Das kommt immer am Anfang vom Start des Programmes, das aber schon seit immer und ich denke nicht, dass es im Zusammenhang steht.

Code: Alles auswählen

 *** A stack buffer overrun occurred in D:/Programmieren/qt/Archiver/debug/Archiver.exe :

warning: This is usually the result of a memory copy to a local buffer or structure where the size is not properly calculated/checked.
warning: If this bug ends up in the shipping product, it could be a severe security hole.
warning: The stack trace should show the guilty function (the function directly above __report_gsfailure).
warning:  *** enter .exr 0022A3DC for the exception record
warning:  *** then kb to get the faulting stack
Das kommt jedesmal beim crash. Der crash passiert nicht immer, das heißt manchmal geht es. Oftmals besonders wenn ich manche Zeilen auskommentiere, worauf ich gleich näher eingehe.

Es handelt sich um ein Model für QTreeView, sozusagen einem Erweiterten QDirModel. Ich hantiere somit viel mit den Klasen QDir, QFileInfo und QIcon. Die ich oft erstelle und zuweise etc. Meinen Tests nach muss es irgendwie damit Zusammenhängen, ich habe wirklich viel versucht und auch versucht genauso vorzugehen, wie bei QDirModel (welches keine Probleme aufwirft aber auch nicht den Umfang hat), aber ohne wirklichen Erfolg.

Code: Alles auswählen

 quint32 entryCount = infoList.count();
    parent->children = QVector<DirModelEntry>(entryCount);

    for (quint32 i = 0; i < entryCount; ++i) {
        DirModelEntry &modelEntry = parent->children[i];

        modelEntry.populated = false;
        modelEntry.archiveEntry = 0;
        modelEntry.parent = !isModelRoot ? parent : 0;

        modelEntry.info = infoList.at(i);
        if (!isSystemRoot) {
            modelEntry.name = modelEntry.info.fileName();
        } else {
            modelEntry.name = modelEntry.info.filePath();
        }
        if (modelEntry.info.isDir()) {
            modelEntry.kind = Dir;
        } else if (isSupportedArchive(modelEntry.info.suffix())) {
            modelEntry.kind = Archive;
        } else {
            modelEntry.kind = File;
        }
        modelEntry.size = modelEntry.info.size();
        modelEntry.type = iconProvider->type(modelEntry.info);
        modelEntry.modified = modelEntry.info.lastModified();
        modelEntry.created = modelEntry.info.created();
        modelEntry.accessed = modelEntry.info.lastRead();
        modelEntry.attributes = getAttributes(modelEntry.info);

        modelEntry.icon = iconProvider->icon(modelEntry.info);
}
Ich denke dieser Auszug ist verständlich. Ihr kennt nicht jede Variable oder jede Struktur, aber es gibt einen Überblick über was ich tue und woran es liegen könnte. Komnmentiere ich die Zuweisung von QIcon aus, funktioniert es mehr, aber der Crash tritt trotzdem auf. Ich sitzte jetzt seit 3 Wochen vor dem Problem, setzte mich hin und wieder kurz drann, aber komme einfach hinter nichts.
Hoffentlich kennt jemand die tiefere Bedeutung von der "Fehlermeldung", hat selbst solche Erfahrungen gemacht oder sieht gar eine mögliche Fehlerquelle in dem Code.
Wenn jemand meint mir helfen zu können, wenn er das ganze Projekt bekommt und das auch tun möchte, so wäre ich eventuell dazu bereit. Dieses ganze Klassengeschiebe und Übergebe in Qt ist mir ein bisschen etwas neues, da ich in solchen Situationen, sonst immer zu Strukturen gegriffen habe und somit kein reiner OOP Programmierer bin *gg*
Zuletzt geändert von CLRS530 am 10. März 2009 02:43, insgesamt 2-mal geändert.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Schonmal mit einem Debugger geschaut wo genau der Fehler auftritt??
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
CLRS530
Beiträge: 155
Registriert: 8. Oktober 2007 18:00

Beitrag von CLRS530 »

Ja sicher. Das Problem ist halt, dass es an sehr seltsamen Stellen auftritt. Anfänglich war es zum Beispiel, als ich das Model auf ein TreeView gesetzt habe (setModel). Und zwar erst bei 2. (es sind 2 nebeneinander). Die beiden hängen in keiner Weise zusammen.
Ich kann es jetzt noch einmal versuchen, da es nach einigen Änderungen nun wo ganz anders auftritt, aber ich bezweifele, dass mir das wirklich weiterhilft.
Ich nehme an, dass an irgendwelchen Stellen eine Beschädigung des Heaps/Stacks vorkommt, welches dann an diversen Stellen erst ersichtlich wird. Der Callstack zumindestens zeigt random Funktionen, am Ende immer irgend etwas der ntdll -> tdll.dll. Zwischendurch meist eine Funktion von Qt. Der Rest außerhalb meines Projekts und von Qt.

EDIT:

Code: Alles auswählen

modelEntry.modified = modelEntry.info.lastModified();
Die Zeile ist es, nachdem Zugriffe auf info zuvor funktionieren (zumindestens nichts schief geht, aber das heißt gemeinhin natürlich nicht viel)
CLRS530
Beiträge: 155
Registriert: 8. Oktober 2007 18:00

Beitrag von CLRS530 »

Krass, ich habe den Fehler wohl gefunden. Es liegt an den 3 Funktionen lastModified, created und accessed, die scheinbar bei den drives (QDir::drives) einen Fehler hervorrufen. Ich gebe zu, dass sie dort nicht wirklich viel Sinn machen. Aber Zerstörung sollten sie dennoch nicht hervorrufen.
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag von solarix »

Ich nehme an, dass an irgendwelchen Stellen eine Beschädigung des Heaps/Stacks vorkommt, welches dann an diversen Stellen erst ersichtlich wird.
Da geb ich dir Recht.. Fehler im Umgang mit Pointer erzeugen mehr oder weniger zufällige Probleme im Programmfluss. Unter Linux wäre noch "valgrind" eine Variante.. unter Windows kenn ich mich nicht aus. Sonst mal das Projekt soweit wie möglich reduzieren und uns danach zur Verfügung stellen.

[EDIT]
Wenn das Kopieren eines QDateTimes mittels QFileInfo::lastModified() ein Crash verursacht, liegt das Ziel (in deinem Fall "modified") im Acker...
CLRS530
Beiträge: 155
Registriert: 8. Oktober 2007 18:00

Beitrag von CLRS530 »

Ich habe es jetzt so modifiziert, dass diese 3 Werte beim Systemroot nicht gesetzt werden.
Mein DirModel kann von einem Root C:\ D:\ zu den Drives zurück (im Gegensatz zu QDirModel). Der Fehler trat immer erst auf, wenn ich von solch einem zurückgegangen bin. Beim ersten Anzeigen der Drives, was zur Zeit der Start ist, gibt es keinerlei Probleme.
Eventuell ist das der Grund, wieso QDirModel kein Crash verursacht, da auch dort lasModified von Drives ausgegeben wird.
Ich werde dem noch weiter nachgehen und dann eventuell ein Bugreport an die Trolls schicken, wenn ich ausschließen kann, dass es an mir liegen könnte.
CLRS530
Beiträge: 155
Registriert: 8. Oktober 2007 18:00

Beitrag von CLRS530 »

Ich habe eine schnelle Testapplikation geschrieben. In einem QSplitter sind 3 QTreeViews nebeneinander. In jedem erstelle ich ein QDirModel, welchem ich den Root zuweise.

Gebe ich anstelle von:

Code: Alles auswählen

ui->treeView->setRootIndex(dirModel1->index(QString("/")));
ui->treeView_2->setRootIndex(dirModel2->index(QString("/")));
ui->treeView_3->setRootIndex(dirModel3->index(QString("/")));
das:

Code: Alles auswählen

ui->treeView->setRootIndex(dirModel1->index(QString("c:\\")));
ui->treeView_2->setRootIndex(dirModel2->index(QString("c:\\")));
ui->treeView_3->setRootIndex(dirModel3->index(QString("c:\\")));
an,
gibt es kein Absturz. Ich bitte um ein paar Tester, die das Szenario bestätigen oder beneinen können oder mir beibringen, das ich dort irgendwelchen Unfug betreibe ;). Meine Testplattform ist derzeit QtCreator 1.0 und somit Qt 4.5, ich habe es aber unter 4.4.3 ebenso vorgefunden. XP Sp3 ist mein Betriebssystem und ich habe es derzeit weder unter Linux, noch unter Mac getestet, aber es bietet sich sicherlich an, dass das nur ein Windowsfehler ist.
Dateianhänge
testapp.zip
(3.14 KiB) 151-mal heruntergeladen
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag von solarix »

Gebe ich anstelle von: ... das: ...an, gibt es kein Absturz.
Irgendwas muss ich da überlesen haben.. ich dachte bisher, der Crash wird _ausschliesslich_ mit deinem (eigenen) Modell beobachtet? Du kannst also mit dem erwähnten Code den Crash unter Windows (auf meinem Mac gibt's damit keine Probleme) mit diesem Qt-Code reproduzieren? Was erwartest du eigentlich von 'index("/")' unter Windows... ich meine nur, Qt sollte zwar nicht abstürtzen, aber liefert das ein gültiger Index (QModelIndex::isValid())?
CLRS530
Beiträge: 155
Registriert: 8. Oktober 2007 18:00

Beitrag von CLRS530 »

Ja richtig, ich hatte es bisher nur mit meinem eigenen Model zum Absturz gebracht, das liegt aber daran, dass ich diese Situation mit 3 TreeViews bisher nie hatte und mit einem einzigen kommt dieser Absturz auch nicht vor.

Du hast recht, dass "/" unter Windows an sich quatsch ist, aber in diesem Fall wird unter Windows trotzdem das QDirModel auf drives gesetellt, da der QModelIndex wie von dir erwähnt nicht valid ist. Also ist das eine völlig normale Situation. ich hätte auch gar keinen Pfad einstellen brauchen, dann wäre es auch der Root. Ich habe das nur zur besseren Abfolge gemacht.
Da QDirModel auch lastModified benutzt und für drives() keine Extrabehandlung verwendet, muss es sich im Grunde ähnlich verhalten wie mein Model. Das bestätigt sich zumindestens auf meiner Maschine mit diesem Beispiel.
Gut zu wissen, dass es sich in deinem Fall nicht so ist, aber bei Windows sind die Disks auch in Drives drinnen. Die Abstürze konnte ich nämlich bei einem Disk Drive feststellen, eventuell tritt bei Mac das gleiche in Volumes auf.
Da das ganze aber ziemlich auf Funktionen des Systems beruhen wird, nehme ich an, dass es wirklich nur bei Windows so ist.
CLRS530
Beiträge: 155
Registriert: 8. Oktober 2007 18:00

Beitrag von CLRS530 »

Ich habe noch einen zweiten, sinnvolleren Test hinzugefügt. Diesmal gänzlich ohne QDirModel.

Code: Alles auswählen

QFileInfoList infoList = QDir::drives();
    for (int i = 0; i < 100; ++i) {
        for (int j = 0; j < infoList.count(); ++j) {
            infoList[j].setCaching(false);
            for (int k = 0; k < 20; ++k) {
                qDebug(infoList[j].filePath().toAscii());
                new QListWidgetItem(infoList[j].lastModified().toString(), ui->listWidget);
                new QListWidgetItem(infoList[j].created().toString(), ui->listWidget);
                new QListWidgetItem(infoList[j].lastRead().toString(), ui->listWidget);
            }
        }
        ui->listWidget->clear();
    }
Der Sinn ist einfach, von allen Drives die created, modified und access Zeiten sehr oft durchzugehen, sodass es auf jeden Fall crasht, wenn ein Problem vorliegt.

Es ist wohl zumindestens kein wirkliches Qt Problem. Es kommt jetzt 100%ig nur wegen meinem Laufwerk H:\ vor, welches ein DVD Brenner von LG ist und zusätzlich passiert es von den 3 von mir getesteten CDs nur bei einer. Eine gebrannte Daten CD (funktioniert aber). Eine zweite gebrannte CD brachte nicht den selben Effekt.
Andererseits habe ich die CD noch nicht so lange drinnen, sodass es auch nicht nur die sein kann.
Wenn gar keine CD im Laufwerk liegt gibt es auch keinen crash.
Wäre trotzdem schön, wenn die Programme getestet werden könnten.

EDIT:
Eventuell doch ein Qt Problem, denn das Wechseln dieser CD in mein 2. Laufwerk, ein DVD Player von Philipps brachte das selbe Resultat. Die CD hat, so sieht es aus keine gesetzten modified und created Zeitwerte, denn die Werte bringen einen leeren String.
Dateianhänge
testapp2.zip
(2.52 KiB) 146-mal heruntergeladen
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Das letzte Testprojekt funktioniert bei mir unter Windows, Qt 4.5.0, msvc ohne Probleme.
Da bleibt wohl wirklich nur valgrind under Linux übrig.
Ist an der CD irgend etwas besonderes? z.B. Joilet only oder irgendwas in der Richtung (sollte man z.B. mit IsoBuster rausbekommen)
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
CLRS530
Beiträge: 155
Registriert: 8. Oktober 2007 18:00

Beitrag von CLRS530 »

Die CD hat einen kaputten Sektor ganz am Ende. Mit Isobuster muss irgend etwas mit 0en vollgeschrieben werden. Die CD funktioniert aber ansonsten ziemlich tadellos. Ich habe somit auch ein Image dieser CD erstellt, gemounted und der Fehler tritt wieder auf.
Ich versuche als nächstes ein Miniimage zu erstellen, welches den Fehler beeinhaltet. Gut wäre dazu, wenn ich die Dateien Raw löschen könnte, ohne das das Iso neu erstellt wird. Mit Programmen die ich bisher getestet habe funktioniert das nicht.
Ich kenne mich mit dem Iso Format auch zu wenig aus.

EDIT:
In einem Versuch habe ich die letzten 500kb der Datei auf ein neues Image (welches ich von diesem Erstellt habe) stumpf kopiert. Die CD funktionierte noch, wenn man davon absieht, dass die PDF Datei am Ende der neuen CD defekt war. Fehlerlos kam die CD dann trotzdem durch den Test.
Muss ich wohl intelligenter angehen.
Wenn jemand ein Tool kennt welches mir helfen kann (z.B. wahnsinnig wichtige Infos über das Image/die CD wiedergibt) immer her damit.
Antworten