sigabrt -> fehler finden

soul_rebel

ist immer auf der flucht
ich bekomme mehr oder weniger reproduzierbar bei einem programm abort signale und finde den fehler nicht :(
ein core wird gedumpt, aber enthält keinen stack, lässt sich nicht debuggen...
der fehler sieht so aus:
Code:
kports in free(): error: chunk is already free

Program terminated with signal SIGABRT, Aborted.
The program no longer exists.
habe natürlich erstmal alle aufrufe von delete und free in meinem prog gecheckt (um doppeltes löschen oder ähnliches auszuschließen), aber die sehen alle gut aus...
woran könnte sowas liegen/bzw wie debugged man SIGABRTs wenn man keinen stack hat?
vielen dank
 
Kann viele Ursachen haben:

- doppeltes free() auf einen Speicherbereich
- zerstörter Heap (irgendwo Überläufe im Code, dann hat free() es festgestellt)
- zerstörter Stack (Pointer auf den Speicherbereich zeigt ganz woanders hin)

Ich würde in dieser Reihenfolge nach den Fehlern suchen.
 
Ich will Dir ja nicht zu nahe treten, aber die Fehlermeldung ist sehr eindeutig und bei mir war es bisher immer so, dass tatsaechlich Speicher mehrfach freigegeben wurde. Ich wuerde an Deiner Stelle die new und delete Aufrufe nochmal checken oder einen die Aufrufe debuggen. Du koenntest bspw. die Aufrufe durch Macros ersetzen und die Adressen mitschreiben incl der Stelle, wo der Aufruf stattfand. Damit sollte sich die Stelle finden lassen. Ansonsten gibt es noch valgrind, der solche Fehler auch finden kann.

HTH
 
mhm toll ich kann jetzt den fehler auf diesen code abschnitt eingrenzen:
Code:
	KProcIO proc; 
	proc.setName("installProc");
	
	if (getuid!=0)
		proc << QStringList::split(' ', "kdesu --caption=KPorts -t -c ") << cmd;
	else
		proc << "/bin/sh" << "-c" << cmd;

	
	QApplication::postEvent(this, new QMyEvent(1199, cmd));	/// signal it out
	

	QString	Buffer(""), err("");
	
	
	/// append this proc to the list of active procs
	activeProcs.append(proc.name());
proc.enableReadSignals(false);
	proc.setComm(KProcess::AllOutput);
	proc.start(KProcess::OwnGroup, true); /// ownGroup so children spawned by proc can be killed too + comm=alloutput
	int i = 0;
	
	while ((i = proc.readln(Buffer, false) >= 0) || (proc.isRunning()))
	{
		if (i > 0)	/// there is output
		{
			Buffer.remove('\n');
			Buffer.remove(QChar(13));
			qDebug("Buffer: "+Buffer +" length: " +QString::number(Buffer.length()));
//			QApplication::postEvent(this, new QMyEvent(1200, Buffer));	/// signal it out
		}
		
		
		if (toBeStoppedProcs.contains(proc.name()) || toBeStoppedProcs.contains("*")) /// should be interrupted
		{
			proc.kill(SIGINT); /// try to terminate nicely
			if (!proc.wait(3))
				proc.kill(SIGTERM);/// then we kill it
			if (!proc.wait(3))
				proc.kill(SIGKILL);/// then we kill it
				
			Buffer = "--> Process interrupted by User."; /// get line from output and make it red
			QApplication::postEvent(this, new QMyEvent(1200, Buffer));	/// signal it out
		}
		
		Buffer = "";
	}
das sigabrt passiert irgendwann im while loop. macht imo garkeinen sinn...
:confused:
wie ihr seht gibts darin keine news und deletes, auch arbeite ich nicht mit pointer (eigentlich mache ich garnichts im loop).
legt für mich den schluss nahe dass es bei kprocio, also im readln aufruf liegt, habe mir den schon angeschaut, sehe aber keine fehler (und der aufruf ist in der art schon jahre in den kdelibs und scheint immer funktioniert zu haben).

danke für jede hilfe

bin langsam am verückt werde, das scheiß problem mit den prozessen beschäftigt mich jetzt schon wochen! :mad: :mad: :mad:
langsam werde ich wahnsinnig :zitter: :zitter: :zitter:
 
Ich geb Dir recht, in diesem Zusammenhang hilft die Meldung nicht wirklich weiter. :(

Hast Du schon probiert, die Zeilen innerhalb der Schleife auszukommentieren und nach und nach wieder reinzunuehmen, um den Fehler noch weiter einzugrenzen?

Ansonsten seh ich nur die Zeile mit QApplication :: postEvent(), die ein new enthaelt. Aber wenn postEvent() die Eigentuemerschaft uebernimmt (was es meines Wissens tut), sollte das ja auch kein Problem sein.

Koennte der Fehler vielleicht dadurch entstehen, dass Du aus 2 verschiedenen Threads auf eine Variable zugreifst?
 
Hallo soul_rebel,

Code:
if (i > 0)	/// there is output
{
	Buffer.remove('\n');
	Buffer.remove(QChar(13));
	qDebug("Buffer: "+Buffer +" length: " +QString::number(Buffer.length()));
//	QApplication::postEvent(this, new QMyEvent(1200, Buffer));	/// signal it out
}

Du schreibst zweimal "Buffer.remove". Ich sehe nicht, dass Du auch wirklich abfrägst, ob auch mindestens zwei Zeichen in Deinem Buffer sind.

Viele Grüße

Jürgen
 
xbit schrieb:
Ansonsten seh ich nur die Zeile mit QApplication :: postEvent(), die ein new enthaelt.
ich habe extra schon den code umgeschrieben so dass werte und keine adresse oder pointer übergeben werden....
juedan schrieb:
Du schreibst zweimal "Buffer.remove". Ich sehe nicht, dass Du auch wirklich abfrägst, ob auch mindestens zwei Zeichen in Deinem Buffer sind.
remove ist ein qt befehl, der durchsucht den string nach allen angegeben zeichen oder substrings und entfernt diese, wenn ers sie nicht findet macht er auch nichts.
ist schon seltsam... hab jetzt mal alles im whil-loop auskommentiert und er verursachst immrenoch den fehler. was heißt das der fehler im readln aufruf liegt.
hab mal geschaut ob es am befehl liegt den ich ausführe und stattdessen einfach "cat /dev/random" ausgeführt, hilft aber auch nicht was al letzte möglichkeit eigentlich nur ein problem der kprocio bzw. der kprocessklasse und damit der kdelibs übriglässt.
echt mist sowas, als hätte man nicht schon genug zu tun. (ich hasse programmier zeit mit etwas zu vergeuden was nicht programmieren ist -> wochenlang einen weg zu suchen eine shell auszuführen, die man inklusive kinder killen kann) :mad:
 
Hallo soul_rebel,

mach mal folgendes - es ist zwar blöd, aber so findet man manchmal am schnellsten den Fehler:
Code:
printf("line: %d\n", __LINE__);
Trage das in nach jeder Code-Zeile ein. Ich nenne das immer die "Ich sehe den Wald vor lauter Bäumen nicht"-Funktion.


Viele Grüße

Jürgen
 
danke juedan,
aber ich war sicher, dass es am readln aufruf liegen musste. (hab alles andere auskommentieren können).
die __LINE__ variable ist natürlich trotzdem was feines, merke ich mir!
habe jetzt eine vorläufige lösung. undzwar scheint der fehler nicht verursacht zu werden wenn ich den while-loop künstlich bremse, dazu hänge ich an die erste if-bedingung ein
Code:
else
    proc.wait(1);
dran. wenn also bei einem while-durchlauf kein output verfügbar ist wartet er 1 sekunde bevor einen neuen durchlauf startet vorausgesetzt der prozess ist noch aktiv.
das funktioniert bis jetzt ganz gut und verursacht nur minimale verzögerung.
 
Das bringt mich auf eine Idee. Vielleicht ist Deine while() Bedingung das Problem. Kannst Du nicht innerhalb der while() Schleife die Aufrufe machen und nur ein Flag setzen und anhand des Flags entscheiden, ob die Schleife weiterlaeuft oder nicht?
Wenn Du das umschreibst, so dass Du readline() und proc.isRunning() getrennt auswertest, findet sich vielleicht auch SIGABRT.

HTH
 
hab ich schon probiert (also das i = readline einfach innerhalb des loops gemacht) hat aber nix genützt. anscheinend macht er einfach stress wenn ich immerwigge readlines mache, das ist ja auch nicht die vorgesehene vorgehensweise ( ;) ) um prozesse unter qt/kde auszuwerten.
danke auf jeden fall
 
nein ich meinte in einem while loop readlines zu machen. man benutzt bei kprocess (->qt) signals+slots, das macht manches einfacher, aber hier musste das nun mal so gelöst werden.
 
Kannst Du nicht nur die Ausgabe der Prozesse, die Du jetzt in der while() Schleife einliest, ueber Signale melden lassen und dann ausgeben und in der Schleife nur pruefen, ob Du den Prozess beenden sollst, weil der User das moechte?

Im Header steht auch, man soll readln() auch nur mit dem Signal readReady() verwenden. Vielleicht kommt daher das Problem?

Use readln() in response to a readReady() signal.

http://websvn.kde.org/branches/KDE/3.5/kdelibs/kdecore/kprocio.h?rev=465272&view=auto

HTH
 
war mir schon klar mit den signalen und slots aber um dir möglichst simpel meine situation zu erklären:
nennen wir die funktion mit while loop funktion a, member von klasse 1 und das gui objekt welches den output auswertet klasse 2.
bei dem aufbau könnte ich einfach einen slot in 2 mit dem signal aus 1 connecten und bräuchte das ganze nicht, jetzt kommt aber folgendes erschwehrend hinzu:
a wird nicht aus klasse 1 aufgerufen sondern über eine referenz an ein objekt das qthread erbt gegeben welches es ausführt, dieses objekt nennen wir jetzt klasse 3. über diese konstruktion kann ich fast alle prozesse die arbeit irgendwelcher art verrichten parallellisieren.
nun das eigentliche problem ist jetzt, dass unter qt3 signal und slots verbindungen immer im eventloop des senders ausgeführt werden, was darin resultierenden würde dass das "eine-zeile-angekommen"-signal ein änderung des interfaces bewirkt was dann wiedrum in ein "XLib: Async Reply" hervoruft.
deswegen postet a events an 1 die dieses dann im eventloop des guitreads als signal abgibt welches den slot in 2 bedient.
ich könnte das zwar auch mit signalen und slots machen, indem ich in 1 einen slot machen der ein event an eins postet was wiederum als signal abgegeben wird, aber das wäre erstens noch komplizierter und zweitens würde es mein thread handling durcheinander bringen, welches explizit so ausgelegt es ein funktion auszuführen und danach zu terminieren (ansonsten gäbe es niemand der die daten der funktion aufräumt).
puh
;)
 
Danke fuer die ausfuehrliche Erklaerung. Das macht das Ganze etwas uebersichtlicher fuer mich. :)
Ausserdem verstehe ich die Problematik.

Ginge nicht folgendes (ich find's allerdings nicht so super gelungen):

Klasse 1 greift sich das readln() Signal von KProcIO und sendet das mittels postEvent() an den GUI Thread. Das Problem ist dabei nur, dass Klasse 1 eine Referenz auf Klasse 2 braucht.
Damit sollte dann aber auch das Event-Handling mit Threads funktionieren.

Ich hoffe, das hilft irgendwie weiter.
 
ja das könnte man machen aber ich wollte das ganze thread und event gefrickel von den guiklassen fernhalten, dann kann ich ab kde4 einfach klasse 1 an das neue threading modell anpassen und brauch nicht änderungen im ganzen programm vornehmen.
danke trotzdem
(es geht ja auch jetzt so wie es ist)
 
Naja, fuer QT4 muesstest Du dann, wenn das so geht wie Du schreibst, ja nur die Signale anders verbinden und die Referenz auf die GUI Klasse wegschmeissen.

Ich dachte nur, dass sich ueber die Signale vielleicht der SIGABRT vermeiden liesse und Du keine Wartezeit einbauen musst.

Hauptsache es laeuft jetzt. :)
 
wie gesagt es tritt kaum verzögerung auf, da er nur wartet wenn beim letzten durchlauf kein inhalt verfügbar war. solange inhalt da ist postet er fleißig events...
 
Zurück
Oben