Memoryleaks finden - mit Programm
-
Hallo,
einige hier, die heute mittag im irc (#cpp) waren kennen evtl. schon mein Problem.
Ich arbeite uebrigens mit dem BCB6.
Aus mir voellig unerklaerlichen Gruenden schmirt das Programm an dem ich auf der Arbeit
arbeite ab, nachdem ich ein zweites mal eine Instanz einer Klasse erzeuge. Merkwuerdig ist,
dass das Programm nur dann abschmirt, wenn der Konstruktor ohne Parameter aufgerufen wird.
Rufe ich den ueberladenen Konstruktor mit einem Parameter auf (welcher bei zwei von drei
Klassen existiert), kann ich so viele Instanzen erzeugen, wie ich will. Das merkwuerdige ist,
dass wenn ich eine Instanz in einer Funktion erzeuge und die Funktion nach Abarbeitung
wieder aufrufe, das Programm ebenfalls abschmirt. Es ist also egal, ob eine vorhergehende
Instanz bereits zerstoert worden ist, erstelle ich eine zweite Instanz mit dem default
Konstruktor, schmirt das Programm ab. Beim Debuggen ist es so, dass ich beim zweiten Erstellen
einer Instanz nicht einmal bis zur Initialisierungsliste komme, d. h. der Fehler kann _nicht_
im CTor der Basisklasse liegen, da dieser gar nicht erst abgearbeitet wird.MyClass::MyClass() //<----- Wenn ich hier F8 druecke (Step Over) schmirt das Programm ab : BaseClass(...) //<----- Soweit komme ich gar nicht... {} //<----- ...der Body wird daher auch nicht abgearbeitet
Nun meinte King, dass es evtl. an nem Memoryleak haengen koennte. Ich suche daher ein
Programm, welches entweder den Quelltext analysieren kann (weiss aber nicht, ob das so
zuverlaessig ist) oder aber zur Runtime Memoryleaks aufspueren kann (was im Zusammenhang
mit dem Debuggen evtl. besseren Erfolg haben koennte).Ich habe bei Google gesucht, allerdings konnte ich solche Programme nur fuer den MSVC finden,
was mich allerdings nicht weiterbringt.Kennt vielleicht jemand von euch ein solches Programm?
Danke im Voraus, ich hoffe ich hab nichts vergessen und mein Problem relativ gut dargestellt.
mfg
v R
-
http://www.compuware.com/products/devpartner/bounds.htm
ther versions of BoundsChecker
In addition to having full support for Visual C++, BoundsChecker also has support for legacy versions of C++Builder and Delphi, which can be purchased separately.rapso->greets();
-
Würde es nicht mehr Sinn machen, zuvor noch mal die Klasse statisch zu analysieren, bevor Du dynamisch nach Fehlern suchst?
Also klassisch ausdrucken und Codereading machen?
Und dann mal die Klasse entrümpeln, es muß doch irgendwas sein, das Speicher allokiert. Wenn Du diese Punkte entfernst, passiert es dann auch? Und wenn Du alle delete entfernst, dann immer noch?
Weil Speicherloch halte ich für unwahrscheinlich, wenn dann eher ein Speicherüberlauf in einem Block, dyn. Array oder sowas.
-
Splint bzw. Lint helfen Dir vielleicht weiter... außerdem lohnt es sich vielleicht, Deinen Quellcode mal mit einem anderen Compiler zu compilieren, möglicherweise gibt er Dir mehr Informationen aus als der BCB6.
Gruß Winn
-
Speicherlöcher führen nicht zu Abstürzen.
-
Was ist mit dem beim BCB (Prof und Ent) mitgelieferten CodeGuard? Ausserdem gibt's da noch die Freeware Memproof.
Das hättest du mit einer Suche im BCB-Forum aber auch leicht selbst herausfinden können.
-
Bashar schrieb:
Speicherlöcher führen nicht zu Abstürzen.
wenn die memleaks den ganzen speicher vollaufen lassen und er dann mal eine neue instanz einer 100MB klasse instanziert könnte das ein grund sein, wobei du ja recht hast, direckt an den speicherlöchern leigt es nicht, aber indierekt könnte das der ursprung des bugs sein.
beim Devstudio, wenn man debugt, gibt er am ende eigentlich aus, ob speicher nicht freigegeben und wo er allokiert wurde.
mit dem boundscheker testet man ja eher ob eine bereichsüberschreibung stattfindet.
rapso->greets();
-
rapso schrieb:
Bashar schrieb:
Speicherlöcher führen nicht zu Abstürzen.
wenn die memleaks den ganzen speicher vollaufen lassen
... fliegt std::bad_alloc, was schließlich zum kontrollierten, aber sofortigen, Ende des Programms führt. Jedenfalls stürzt das Programm dann nicht mal eben einfach beim Eintritt in einen Ctor ab.
-
ja im optimalen fall
es gibt genug fälle wo dem leiter nicht ist, wenn man nur mit STL coden würde, wäre es auch recht schwer mißt zu bauen. aber manchmal braucht man sein
pPixel = new unsigned int[SizeX*SizeY];
und wenn da wat schiefgeht und man fängt es mit catch(...) ab, weil "man ja weiß dass beim laden der datei nur passieren kann dass eine datei nicht gefunden wurde, was anderes tritt da natürlich nicht auf" und scho ist man im a....
grundsätzlich können memoryleaks nunmal zu programmabstürzen führen.. so absurd ist das eigentlich nicht.
rapso->greets();
-
grundsätzlich können memoryleaks nunmal zu programmabstürzen führen.. so absurd ist das eigentlich nicht.
das ist absurd, weil eine Exception kein Programm absturz ist, sondern ein kontrolliertes beenden. Wenn man eine Exception wirft, wird der Code ja aufgeräumt, deswegen ist es wichtig, dass man Exception sicheren Code schreibt (zumindest so sicher, dass kein Müll im Speicher bleibt und alle Resourcen freigegeben werden).
Aber zu dem eigentlichen Problem in dem Thread kann es nicht führen. Ich würde eher sagen, dass es daran liegt, dass der Heap zerstört wird irgend wo (hab ich wirkliche Memoryleak im Chat gesagt?)
-
vR: Kann man mit deinem Debugger auch auf Assembler-Ebene durchsteppen? Mach das mal.
-
kingruedi schrieb:
das ist absurd, weil eine Exception kein Programm absturz ist, sondern ein kontrolliertes beenden. Wenn man eine Exception wirft, wird der Code ja aufgeräumt, deswegen ist es wichtig, dass man Exception sicheren Code schreibt (zumindest so sicher, dass kein Müll im Speicher bleibt und alle Resourcen freigegeben werden).
Soweit die Theorie.
Im praktischen Fall ist eine Exception meistens das, was der Kunde als "Absturz mit Hinweistext" erlebt - aber ein Absturz bleibt es doch sehr oft. Halt kontrolliert.
Aber so exceptionsicher sind die wenigsten Programme...
Stimme Dir aber in der Sache durchaus zu, so ein Fehler wird nicht durch ein Memoryleak ausgelöst. Selbst wenn der Speicher voll läuft, merkt man das doch, weil das System ab einem Punkt wie wild auf der Platte rumschrubbt und alles ziemlich träge wird. Das geschieht noch, bevor es zum Gau kommt. Und selbst wenn man einen VC hat, wo das new keine Exeception wirft sondern NULL liefert bekommt man immer noch eine Access Violation im Anschluß wenn man das nicht prüft, bzw. sieht das im Debugger EINDEUTIG.
Und das passt überhaupt nicht zum beschriebenen Fehlerbild.
Bei mir gingen solche Fehler auch oft weg, wenn ich einfach noch mal einen vollständigen Rebuild gemacht habe (statt inkrementell).
-
Marc++us schrieb:
Im praktischen Fall ist eine Exception meistens das, was der Kunde als "Absturz mit Hinweistext" erlebt
Bei einem NULL Pointer, gibt es aber einen wirklichen Absturz. Deswegen sind Exceptions doch besser.
-
Ich sagte nicht, daß der Weg besser ist... nur häufiger.
Bei einem NULL-Ptr bekommt ja auch gesagt: "Access Violation" - ist halt der System-Exceptionhandler. Wenn man halt keinen eigenen hat...
-
es gibt leute die fangen mitten im code mit catch(...)
und dann geht es weiter, dass dabei exceptions geworfen werden können die sie nicht bedacht haben, das kommt denen nicht in den sin, deswegen können exceptions zum absturz führen.
ich hab schon oft source gesehen, bei dem eine datei geladen wird und die gehen davon aus, dass sie nicht die volle implementation für das dateiformat haben, aber meißtens läuft das. in den fällen in denen es nicht läuft, schmeissen die manchmal selbst eine exception und manchmal das system, wenn sie z.B. im memory mapped bereich wegen fehlinterpretation von daten eine access violation hervorrufen. naja, dass ist den leuten ja eigentlich egal... fängt man ja alles mit catch(...)
aber manche dinge tretten dann auf die sie nicht bedacht haben z.B. dass das new garnicht funktioniert hat, deswegen die exception.. dann versuchen sie sauber den speicherbereich dort zu delete[]'en und dann stürtzt denen die application ab.ansonsten ist jeder programmabsturz eine exception und weil man sie alle an der wurzel mit catch(...) fangen kann, gibt es nur kontrollierte programmenden, sogar der "blue screen" ist eine (die letzte) instanz bei windows die exception fängt und danach den pc kontrolliert abschaltet.
ich frage mich jetzt aber wirklich, wenn ein absturz nicht durch eine exception hervorgerunfen wird, wodurch dann? ich dachte jeder absturz gründet auf einer exception.
rapso->greets();
-
Ist wohl eher eine Definitionsfrage... ob man eine Exception der eigenen Anwendung meint oder ob der Systemexceptionhandler zuschlägt.
-
@raspo
ui ui ui, dem Programmierer würde ich mal ein paar gute C++ Bücher empfehlen. (Ja ich weiss, dass viel Code sehr sehr schlecht geschrieben wird und man jedem 2. "Programmierer" das sagen müßte.)
-
So einfach kannst Du das nicht sagen. Durch die Libs für die GUIs ist es zumindest im Bereich der GUI fast unmöglich, exceptionsicheren Code zu schreiben. Da kommt eine Message an und der angehängte Codeblock ist ungültig, da schmiert dann schon der Handler in der Messagemap ab. Klar, hat einer (nicht das System!) falsch gefüllt, aber wer und wo... und dann noch alles asynchron. Oder nicht gesetzte Eventhandler, auch so ein Thema.
Und lustig, im Bereich des Backends hat man eigentlich selten Probleme mit unerwarteten Exceptions, selbst wenn der Code nicht strikt exceptionsicher ist. Dort stürzt einfach nichts ab, weil alles passt.
Da dreht man sich manchmal etwas im Kreis... den Teil den man voll im Griff hat macht man exceptionsicher, obwohl dort keine kommen, und der Teil der sie wirft, den hat man nicht im Zugriff. Und da nützt es gar nix, wenn man den Quellcode für die Lib hat. Wer will schon sowas debuggen?
-
Hi,
erstmal Sorry, dass ich noch nicht geantwortet hatte, ich war heut in der Schule und nicht im
Betrieb. Kam noch nicht dazu hier zu lesen.Und dann mal die Klasse entrümpeln, es muß doch irgendwas sein, das Speicher allokiert. Wenn Du
diese Punkte entfernst, passiert es dann auch? Und wenn Du alle delete entfernst, dann immer
noch?Die Klasse ist so schlank, dass es da eigentlich nichts zu entruempeln gibt. Aber ich werde
dennoch deine Vorschlaege mal durchgehen.Allerdings muesste das Programm doch dann auch abschmiren, wenn ich den CTor mit einem
Parameter aufrufe und genau das geht mir irgendwie nicht in den Kopf, warum fuehrt ein
erneutes erstellen mit diesem ueberladenen CTor nicht zum absturz?Ich werde morgen nochmal ein paar Dinge ausprobieren. Da ich diesen Code der Klasse lediglich
uebernommen habe, hoffe ich das ich den Fehler bald finden werde ;).Splint bzw. Lint helfen Dir vielleicht weiter... außerdem lohnt es sich vielleicht, Deinen
Quellcode mal mit einem anderen Compiler zu compilieren, möglicherweise gibt er Dir mehr
Informationen aus als der BCB6.Ja, ich habe versucht, den Code so umzuschreiben, dass es egal sein sollte, auf welchem
Compiler er compiliert wird. Deinen Vorschlag werde ich auch einmal durchfuehren.Was ist mit dem beim BCB (Prof und Ent) mitgelieferten CodeGuard? Ausserdem gibt's da noch die
Freeware Memproof. Das hättest du mit einer Suche im BCB-Forum aber auch leicht selbst
herausfinden könnenHmmm...sorry, war mehr oder weniger ne Verzweiflungstat, werde versuchen mich es naechste mal
zu benehmen... fliegt std::bad_alloc, was schließlich zum kontrollierten, aber sofortigen, Ende des
Programms führt. Jedenfalls stürzt das Programm dann nicht mal eben einfach beim Eintritt in
einen Ctor ab.std::bad_alloc fange ich eigentlich ab, aber er springt in den 'catch(...)'-Block.
Werde das morgen auch nochmal genau checken.Aber zu dem eigentlichen Problem in dem Thread kann es nicht führen. Ich würde eher sagen,
dass es daran liegt, dass der Heap zerstört wird irgend wo (hab ich wirkliche Memoryleak im
Chat gesagt?)Ich meine ja, kann mich aber auch irren (will dir aber nichts vorwerfen ;)).
vR: Kann man mit deinem Debugger auch auf Assembler-Ebene durchsteppen? Mach das mal.
Ja, dass habe ich auch schon gemacht. Er stuerzt innerhalb dieser Funktion ab:
__InitExceptBlockLDTC
leider kann ich damit ueberhaupt nichts anfangen und Google schweigt sich darueber auch aus.
Bei mir gingen solche Fehler auch oft weg, wenn ich einfach noch mal einen vollständigen
Rebuild gemacht habe (statt inkrementell).Das werde ich gleich morgen frueh auch nochmal machen.
Erstmal danke dass ihr euch schon die Zeit genommen habt, mir zu schreiben, werde mich
morgen nochmal melden, wenn ich alle eure Vorschlaege durchgegangen bin.mfg
v R