Seite 1 von 1

[gelöst] Qt und Q_ASSERT Debuggen

Verfasst: 25. April 2008 12:18
von Flachkoepper
Moin,

ich arbeite unter Linux und debugge mit dem gdb. Das klappt auch alles ganz gut, solange ich Fehler habe wie "Speicherzugriffsfehler" -> Debugger anschmeißen, Fehler gefunden, fertig.
Wie kann ich aber ein Q_ASSERT debuggen? Wenn ich z.B. auf einen ungültigen Index in einem QVector zugreifen will, bekomme ich die Meldung

Code: Alles auswählen

ASSERT failure in QVector<T>::operator[]: "index out of range", file /usr/local/Trolltech/Qt-4.3.4/include/QtCore/qvector.h, line 298
Schön und gut, aber wie finde ich jetzt raus, welche Zeile in meinem Programm den Fehler verursacht hat? Wenn ich mit gdb den Stack überprüfen will, kriege ich nur als Meldung "No stack".

Hoffe, mir kann wer helfen.

Verfasst: 25. April 2008 12:37
von Christian81
Das ist noch so ein Grund warum ich gdb nicht mag - damit habe ich keine gute Möglichkeit gefunden dies zu debuggen - bei msvc ist der bt dort korrekt.
Die einzigste Möglichkeit ist, ein qvector.h:298 einen Breakpoint zu setzen - zumindest ist mir nichts anders bekannt.

Verfasst: 25. April 2008 13:21
von RHBaum
der gdb hat keine Aufrufliste ???

Ich hab hier auch nur den msvc, mit dem isses gar kein problem ....

Kann es sein, das der Vector (also der operator[] genauer) von nem code fragment angesprungen wird, wo du keine debug infos zu generiert hat ?
Also weils ned teil deines projects ist, oder du debug infos ned angeschalten hasst ?

Ciao ...

Verfasst: 25. April 2008 13:27
von solarix
naja.. das haengt weniger mit dem Debugger zusammen als mit dem Runtimesystem und was der Compiler daraus macht.. denn wenn man in die qglobal.cpp schaut, sieht man u.a., dass

Code: Alles auswählen

#if (defined(Q_OS_UNIX) || defined(Q_CC_MINGW)) && defined(QT_DEBUG)
        abort(); // trap; generates core dump
#else
        exit(1); // goodbye cruel world
#endif
je nach Umgebung anderst abgebrochen wird. Unter Unix mit Debug-Qt sollte also "abort" (und damit einen core-dump oder stack-ausgabe im gdb) ausloesen.

Falls dies nicht geschieht, hilft wohl nur ein eigener qFatal-Handler:
http://doc.trolltech.com/4.3/qtglobal.h ... MsgHandler

Bei

Code: Alles auswählen

case QtFatalMsg:
koenntest du dann den Breakpoint setzen..

Verfasst: 25. April 2008 13:52
von ConfusedSushi
Unter Windows mit Visual Studio hab ich mir mein eigenes ASSERT-Makro definiert.

Das sieht wie folgt aus

Code: Alles auswählen

#define ASSERT(x) \
	{ \
		if(!(x)) \
		{ \
			qDebug("Assertion \"" #x "\" failed.\n"); \
			DebugBreak(); \
		} \
	}
Damit bleibt der VS-Debugger genau an der Stelle stehen an der das ASSERT-Makro im Code steht.

Vielleicht gibt es ja so etwas ähnliches wie DebugBreak() auch in Verbindung mit gcc/gdb?

Wenn ja verat mir doch bitte wie es heisst.

Verfasst: 25. April 2008 13:56
von solarix
Vielleicht gibt es ja so etwas ähnliches wie DebugBreak() auch in Verbindung mit gcc/gdb?

Code: Alles auswählen

#include <stdlib.h>
void abort(void);

Verfasst: 25. April 2008 14:13
von ConfusedSushi
das Problem an abort() ist das der Debugger nicht im eigenen Code anhält sondern in einer lib vom Compiler, so das man im CallStack erstmal 'zurücksuchen' muss.

unter x86 kann man alternativ auch den Interrupt 3 auslösen,
in VC sieht das so aus:

Code: Alles auswählen

__asm
{
	int 3
}
wie und ob das mit dem gcc und unter amd64 funktioniert weiß ich allerdings nicht.

Verfasst: 25. April 2008 14:53
von Flachkoepper
Danke für die vielen Antworten.

Der Tipp von solarix war die Lösung. Mit einem Breakpoint im eigenen MessageHandler kann man dann sogar unter Linux mit gdb den stack zurückverfolgen.

Besten Dank nochmal!

Gruß,
Flachkoepper

Edit: Wäre das nicht vielleicht was für die FAQ? Kann mir vorstellen, dass der eine oder andere Neuling da unter Linux mit gdb ebenso ratlos ist wie ich.