Destruktor-Aufruf führt zu SIGILL
-
Taschenschieber schrieb:
Die Implementierung würde den Rahmen etwas sprengen (sind fast 500 Zeilen), wenn's weiterhilft, kann ich den Code aber auch gerne noch posten...
Es würde weiterhelfen wenn du deine Implementierung auf das Wesentliche reduzierst - so dass man ein übersetzbares Programm erhält, bei dem der Fehler immernoch auftritt.
-
pumuckl schrieb:
Es würde weiterhelfen wenn du deine Implementierung auf das Wesentliche reduzierst - so dass man ein übersetzbares Programm erhält, bei dem der Fehler immernoch auftritt.
Und dabei würde es mir wiederum weiterhelfen, überhaupt mal zu wissen, was eigentlich mögliche Ursachen für einen SIGILL sind. Ansonsten wird das wohl ziemliches Gestocher im Nebel.
Leider sind alle Google-Treffer, die ich zu diesem Thema bisher hatte, mehr als vage und klingen eher danach, als würde dieses Signal eigentlich nur bei Compilerfehlern und Rumgespiele mit laufzeitgenerierten Funktionen auftreten (also Casts eines int-Arrays in eine Funktion und so Späße), andere potentielle Ursachen habe ich beim Googlen nicht gefunden. Also was wären denn mögliche Fehlerquellen, die sich nicht in einem SIGSEGV, sondern in einem SIGILL äußern? (Compiler ist G++4.4.3 unter Windows 7, 64bit)
-
Taschenschieber schrieb:
pumuckl schrieb:
Es würde weiterhelfen wenn du deine Implementierung auf das Wesentliche reduzierst - so dass man ein übersetzbares Programm erhält, bei dem der Fehler immernoch auftritt.
Und dabei würde es mir wiederum weiterhelfen, überhaupt mal zu wissen, was eigentlich mögliche Ursachen für einen SIGILL sind. Ansonsten wird das wohl ziemliches Gestocher im Nebel.
Steht da nicht mehr bei? Oft steht da was über die Ursache. Wenn du es eingestellt hast, bekommt du sogar einen Coredump. Vielleicht versteckt deine Umgebung diese Details vor dir, aber sie sind bestimmt irgendwo zu finden.
SIGKILL ist jedenfalls ein ziemlich hefitges Signal und wird vom Betriebssystem nur in Ausnahmefällen geschickt, zum Beispiel wenn der Kernel ganz dringend Arbeitsspeicher braucht und quasi einen Prozess zu Gunsten der Allgemeinheit opfern muss (ja, es geht rau zu in der Prozesswelt
). Sofern solche Ausnahmefälle nicht vorliegen, sollte das Signal von einem anderen Programm stammen. Vielleicht eine IDE oder ein Debugger, in denen das Programm läuft? Die sollten das dann natürlich irgendwo melden, aber da musst du natürlich erst nach suchen. Falls es doch das Betriebssystem ist, was das schickt, sollte es eine Nachricht in seine Logdateien schreiben. Wie schon gesagt, ist ein automatisches SIGKILL eine heftige Aktion, das passiert nicht mal eben so.
-
@SeppJ: Du verwechselst wohl SIGKILL mit SIGILL. SIGILL steht für ILLegal instruction.
Siehe: http://en.wikipedia.org/wiki/SIGILL
-
Eher ein freudscher Verleser. Zu viele Rechtschreibfehler im Forum lassen mich manchmal Buchstaben ergänzen, wo es eigentlich richtig war.
Immerhin hat der Threadersteller nun auch eine Erklärung zu SIGKILL, wenn er ihm mal begegnet und die Wikipediaseite erklärt die Ursachen von SIGILL.
edit: Ich empfehle übrigens mal valgrind mit allen Tests auf das Programm loszulassen. Und.oder sich mal einen Coredump anschauen. Oder im Debugger schauen, warum genau die Anweisung fehlschlägt.
-
Valgrind ist eher schwierig, da dürfte ich erstmal eine vollständige Entwicklungsumgebung unter Linux aufsetzen, für Win gibt es das ja leider nicht.
Der Debugger hat sich aber doch noch erbarmt, ein paar mehr Details auszugeben, und zwar zeigt der Stack hierhin:
#0 0x0f543180 in ?? () No symbol table info available. #1 0x6a225b5e in QObjectPrivate::deleteChildren (this=0xf4d4638) at kernel\qobject.cpp:1908 i = 1 reallyWasDeleted = true #2 0x6a223bde in QObject::~QObject (this=0xd0921d8, __in_chrg=<value optimized out>) at kernel\qobject.cpp:927 d = 0xf4d4638 #3 0x00420e80 in Level::~Level (this=0xd0921d8, __in_chrg=<value optimized out>) at debug//../level.h:38 No locals.Die genaue Fehlermeldung im Debugger ist "Illegal instruction (Signal SIGILL)".
Und mit Eingabe des Funktionsnamens "QObjectPrivate::deleteChildren" (der mir bisher wirklich noch nicht aufgefallen war...) weiß auch Google eine Lösung: Level hat Kinder, die auf dem Stack anstatt auf dem Heap angelegt werden - diese werden gelöscht, wenn der Scope abläuft, aber der Parent versucht trotzdem noch, das Kind zu entfernen, wenn der Parent gelöscht werden soll. Dabei tritt dann verständlicherweise ein Fehler auf.
Mal gucken, ob ich das Problem mit dieser Erkenntnis gelöst kriege. Danke jedenfalls an alle Helfer.
-
Ist es denn überhaupt möglich Stack Objekte als Kind in einem Qt Objekt zu haben.
Normalerweise tut man das ja nicht, da Qt selber immer den Speicher aufräumt.
-
Quelle war dieser Link hier: http://comments.gmane.org/gmane.comp.lib.qt.general/33444
edit: Und ja, das war wohl eine Fehlinformation. Zu früh gefreut.
-
Leider erzeugt das aber ein SIGILL. Die Stacktrace zeigt dabei auf die beiden Zeilen, die ich oben mit einem Sternchen markiert habe,also auf der untersten Ebene auf die geschlossene Klammer (!) am Ende des Destruktors!
Das heißt eigentlich, das der Fehler bei automatischem code nach dem destruktor aufgetreten ist. Normalerweise irgendein destruktor, der noch ausgeführt wird. Spontan seh ich da jetzt keinen direkten schuldigen, aber ich würd mir eventuell
QList<MapTile> map;anschaun, das ist der einzige Kandidat den ich auf den ersten blick als schuldigen sehe (außer du hast deinen destruktor noch etwas reduziert, denn du gepostet hast)
-
Wie gesagt, meine Klasse hat keinen expliziten Destruktor mehr. Trotzdem tritt noch ein Fehler in Level::~Level() auf.
-
Nicht "in" - "danach", also nach Level::~Level().
Deswegen ist der cursor auch am Ende der geschweiften Klammer, und nicht bei einer Code-Zeile im D-Tor, würd ich mal behaupten.
-
Taschenschieber schrieb:
Wie gesagt, meine Klasse hat keinen expliziten Destruktor mehr. Trotzdem tritt noch ein Fehler in Level::~Level() auf.
Einfache klare Frage:
hast du Kinder die auf dem Stack angelegt werden?
-
Level hat Member, die auf dem Stack angelegt werden, diese sind aber keine Kinder von Dungeon.
-
kleiner Troll schrieb:
Nicht "in" - "danach", also nach Level::~Level().
Deswegen ist der cursor auch am Ende der geschweiften Klammer, und nicht bei einer Code-Zeile im D-Tor, würd ich mal behaupten.Nee. Es ist normal, dass der Cursor im Callstack auf der nächsten Anweisung steht.
-
Taschenschieber schrieb:
Level hat Member, die auf dem Stack angelegt werden, diese sind aber keine Kinder von Dungeon.
Das war nicht die Frage.
Du läufst irgendwann in ein deleteChildren() rein. dh du hast irgendwo ein Objekt dem du Kinder gegeben hast. zB indem du setParent() für das Kind aufgerufen hast.Und die Frage ist ob du hier uU Stack Objekte als Kind verwendest. Denn deleteChildren() schlägt idR nur dann fehl, wenn es ein delete auf ein Stack Objekt macht.
Welche Member deine Objekte haben ist dabei nicht wichtig. Die Frage ist nur, kann ich das Objekt per delete löschen.
-
Laut seiner Deklaration von der ersten Seite kommt für diesen Effekt eigentlich nur noch MapTile infrage. Er hat ja keine von QObject abgeleiteten Member.
-
Der Typ MapTile ist übrigens ein enum. Die Tiles sind also auch eher unschuldig.