Wie nach memory leaks suchen?
-
Statische Codeanalyse kann helfen, cppcheck zB ist ganz gut darin, memory leaks zu finden.
-
Zudem sind Memory-Leaks mit steigender Erfahrung kein Problem mehr, wenn man sich eine saubere Art und Weise der Softwareentwicklung angewöhnt hat und mit den neuesten Standards arbeitet.
-
@It0101 sagte in Wie nach memory leaks suchen?:
wenn man sich eine saubere Art und Weise der Softwareentwicklung angewöhnt hat und mit den neuesten Standards arbeitet.
So wie VS2008?
-
@SoIntMan
Du könntest DrMemory probieren: https://drmemory.org/
Gerade mit älteren VS Versionen sollte das gut funktionieren. Idealerweise auch mit einem nicht zu aktuellen Windows. Im Falle des Falles einfach in einer VM mit ner älteren Windows Version laufen lassen.Damit bekommst du dann nicht nur Anzahl/Grösse/Inhalt der Leaks angezeigt, sondern jeweils auch wo die Allokation passiert ist (Callstack).
-
@Mechanics sagte in Wie nach memory leaks suchen?:
@It0101 sagte in Wie nach memory leaks suchen?:
wenn man sich eine saubere Art und Weise der Softwareentwicklung angewöhnt hat und mit den neuesten Standards arbeitet.
So wie VS2008?
Mit VS**** kenne ich mich leider nicht aus.
Angefangen beim ersten "neuen" C++, nämlich mit c++11 meinte ich die Verwendung von smart-Pointer anstatt dem gewurschtel mit new und delete.
Zeitlich danach kommt dann der Verzicht auf Smart-Pointer, wo es eben möglich ist und die Verwendung von std::move zum bewegen von Datenstrukturen.
Des Weiteren meine ich sauberes Klassen-Design z.B. mit RAII, usw...
-
@It0101 Kleiner Tip: Visual Studio 2008 ist im Jahr (1x darfst du raten) 2008 rausgekommen (soll sein 2007 oder 2009, manchmal ist MS da ein Jahr daneben). Und C++11 im Jahr ...
Und deswegen ...
-
@hustbaer sagte in Wie nach memory leaks suchen?:
@SoIntMan
Du könntest DrMemory probieren: https://drmemory.org/
Gerade mit älteren VS Versionen sollte das gut funktionieren. Idealerweise auch mit einem nicht zu aktuellen Windows. Im Falle des Falles einfach in einer VM mit ner älteren Windows Version laufen lassen.
Damit bekommst du dann nicht nur Anzahl/Grösse/Inhalt der Leaks angezeigt, sondern jeweils auch wo die Allokation passiert ist (Callstack).Super, vielen Dank ,das probiere ich doch einfach mal aus (ja habe dafür ne VM mit Win7 und VS2008)
@Quiche-Lorraine sagte in Wie nach memory leaks suchen?:
@SoIntMan
Ist es denn ein Memory Leak? Kannst du diesen provozieren s.d. du einen stetig steigenden RAM Verbrauch hast?
Ein Memory Leak am Programmende hört sich nach einer globalen Variablen an, welche nicht freigegeben wurde wie z.B. HBITMAP. Ist nicht weiter schlimm.
Ich würde alternativ noch ein paar weitere Tools wie CppCheck und Dr. Memory drüber laufen lassen.Kann es denn auch was anderes sein außer ein memory leak ?? hmm ne globale variable ist es ehr nicht, und HBITMAP verwende ich an dieser stelle nicht.
Ich probiere jetzt mal die zwei von euch erwähnten tools aus.
@It0101: Wie schon in anderen Posts von mir erwähnt, komme ich bei manchen Projekten (retrofil, legancy-fit,brownfield) nicht um alte Tools drum herum. In der Industrie wird aus (never-touch-a-running-system) versucht so lange wie möglich auf die Technologien zu setzen weil es eben funktioniert. Und große Player wie Siemens sind da auch etwas träge.. wird alles seine Gründe haben.
Und ja ich gebe mein besten um Sauber zu programmieren, ich konnte ja schon die 2 zeilen Code ermitteln welche ich aus kommentieren muss, um die leaks zu provizieren oder nicht.
-
Ok Cppcheck hat mir schon paar Hinweise
Dr. Memory, funzt leider nicht, es komme 2 MessageBoxen: (bei ausführen in VS2008 durch Tools-> Menus )
Unable to load client library: import MoveFileExW not found in KERNALBASE.dll. Unable to load client library: drmemorylib.dll: unable to process imports of client library.
jemand hier noch ne Idee?
Habe alle nach bestem Wissen der Anleitung nach gemacht und installiert
-
@It0101 sagte in Wie nach memory leaks suchen?:
Angefangen beim ersten "neuen" C++, nämlich mit c++11 meinte ich die Verwendung von smart-Pointer anstatt dem gewurschtel mit new und delete.
Zeitlich danach kommt dann der Verzicht auf Smart-Pointer, wo es eben möglich ist und die Verwendung von std::move zum bewegen von Datenstrukturen.
Des Weiteren meine ich sauberes Klassen-Design z.B. mit RAII, usw...SmartPointer kann man seit C++98 und der Entwicklung der Boost.SmartPtr Klassen nutzen. Das hat damals schon sehr gut funktioniert. Dinge wie unique_ptr sind allerdings erst seit C++11 möglich. Meines Erachtens sollte es möglich sein, eine entsprechend alte Boost.SmartPtr Klasse mit einem alten MVC Compiler zu nutzen. Ganz schlimm sind nur die wirklich alten C++ Versionen von Microsoft.
-
@SoIntMan sagte in Wie nach memory leaks suchen?:
Kann es denn auch was anderes sein außer ein memory leak ??
Naja, sobald die Speicheranforderung kontinuierlich größer werden, hast du ein Memory Leak.
Und sorry, ich muss nochmals nachfragen: Ist es definitiv ein Memory-Leak? Kannst du beispielsweise eine Aktion wiederholen und die Speicheranforderungen steigen stetig? Kannst du so z.B. 10MByte verballern?
Ich habe nämlich schon einige angebliche Speicherlöcher gesehen, welche keine waren, sondern nur eine Eigenarten der C Runtime, Windows oder auch der WinAPI. Denn du nutzt die MFC, welche auf der WinAPI basiert. Und die WinAPI ist tückisch.
Hast du den Visual Leak Detector for Visual C++ ausprobiert? Alternativ könntest du auch noch DebugDiag ausprobieren.
-
Du kannst einen Weekly-Build von Dr. Memory probieren. Oder eine andere Windows Version. Dr. Memory hat da leider manchmal Probleme die ich nicht ganz nachvollziehen kann. Die haben z.B. einen eigenen Loader drinnen mit dem sie ihre "Client DLL" laden. Warum auch immer, keine Ahnung. Und dieser Loader kann auf deinem OS wohl die Funktion
MoveFileExW
nicht finden.Du kannst auch einen Case hier aufmachen: https://github.com/DynamoRIO/dynamorio/issues
-
@SoIntMan sagte in Wie nach memory leaks suchen?:
Unable to load client library: import MoveFileExW not found in KERNALBASE.dll. Unable to load client library: drmemorylib.dll: unable to process imports of client library.
jemand hier noch ne Idee?
Ich habe keine Ahnung von der Software, aber Windows hat meines Wissens keine
KERNALBASE.dll
sondern eineKernelBase.dll
. Darin findet sich auch dieMoveFileExW
-Funktion, und dass bereits seit Windows XP. Sieht mir irgendwie nach einem Tippfehler in deiner Version aus. Schon etwas komisch, denn gerade bei so einem Fehler würde ich erwarten, dass er bei Tests sehr schnell auffällt. Probier's mal mit dem Vorschlag von @hustbaer, eine andere Version zu nehmen. Das schaut sehr danach aus, als wäre ein Bug-Report angebracht.P.S.: Scheint auch ein Beispiel für diese lustigen Fehlermeldungen zu sein, die einen öfter mal auf die falsche Fährte führen. Da wird einfach ein "catch all" gemacht und alle Fehler wie der einzige Fehler behandelt, den sich die Entwickler in dem Moment vorstellen konnten. Hier z.B. dass das Symbol
MoveFileExW
nicht inKERNALBASE.dll
existiert. Dabei ist wohl der eigentliche Fehler, dass bereits die Datei nicht existiert. Kennt ihr diese Fehlermeldungen? Das ist hier noch ein sehr harmloses Beispiel, das geht auch schlimmer. Hab schon viel Zeit damit verschwendet, Fehlermeldungen wortwörtlich zu nehmen
-
Einen wunderschönen Guten Morgen:)
@Quiche-Lorraine sagte in Wie nach memory leaks suchen?:
Naja, sobald die Speicheranforderung kontinuierlich größer werden, hast du ein Memory Leak.
Und sorry, ich muss nochmals nachfragen: Ist es definitiv ein Memory-Leak? Kannst du beispielsweise eine Aktion wiederholen und die Speicheranforderungen steigen stetig? Kannst du so z.B. 10MByte verballern?
Ich habe nämlich schon einige angebliche Speicherlöcher gesehen, welche keine waren, sondern nur eine Eigenarten der C Runtime, Windows oder auch der WinAPI. Denn du nutzt die MFC, welche auf der WinAPI basiert. Und die WinAPI ist tückisch.
Hast du den Visual Leak Detector for Visual C++ ausprobiert? Alternativ könntest du auch noch DebugDiag ausprobieren.ich konnte das Memory-Leak lokalisieren (durch hinweise des cppckecks), also ja es war wirklich so, dass in ner loop (all 200ms, 2byte allokiert wurden aber nicht mehr frei gegeben wurden. Jetzt ist der Memory-Dump weg.
@hustbaer sagte in Wie nach memory leaks suchen?:
Du kannst einen Weekly-Build von Dr. Memory probieren. Oder eine andere Windows Version. Dr. Memory hat da leider manchmal Probleme die ich nicht ganz nachvollziehen kann. Die haben z.B. einen eigenen Loader drinnen mit dem sie ihre "Client DLL" laden. Warum auch immer, keine Ahnung. Und dieser Loader kann auf deinem OS wohl die Funktion MoveFileExW nicht finden.
Du kannst auch einen Case hier aufmachen: https://github.com/DynamoRIO/dynamorio/issuesok dann probiere ich mal ein andere release aus... danke danke
@Finnegan sagte in Wie nach memory leaks suchen?:
Ich habe keine Ahnung von der Software, aber Windows hat meines Wissens keine KERNALBASE.dll sondern eine KernelBase.dll. Darin findet sich auch die MoveFileExW-Funktion, und dass bereits seit Windows XP. Sieht mir irgendwie nach einem Tippfehler in deiner Version aus. Schon etwas komisch, denn gerade bei so einem Fehler würde ich erwarten, dass er bei Tests sehr schnell auffällt. Probier's mal mit dem Vorschlag von @hustbaer, eine andere Version zu nehmen. Das schaut sehr danach aus, als wäre ein Bug-Report angebracht.
das war ein Schreibfehler meinerseits "KERNALBASE.dll" ich habe den Text aus der MsgBox abgetippt.
-
Achje, ja, die tollen MessageBoxen wo Ctrl+C nicht funktioniert. Das sollte MS auch mal fixen.
-
Was mir noch aufgefallen ist, ich mache viel GID Kram in meiner MFC App, und mir war nicht klar,
dass ich für jedes GDI Object .. hier CPen/CBrush.. die "DeleteObject" Method explizt aufrufen muss, dachte das mach dann deren Dtor... und Memory Dumpy bekam ich da auch nicht...CPen blackPen; blackPen.CreatePen(PS_SOLID,1,RGB(0,0,0)); CBrush brush(atol(m_Data.GetAt(i-1,2))); Cpen* poldPen = pDC->SelectObject(&blackPen); CBrush * poldBrush= pDC->SelectObject(brush); ... pDC->SelectObject(poldPen ); pDC->SelectObject(poldBrush ); brush.DeleteObject(); blackPen.DeleteObject();
-
@SoIntMan sagte in Wie nach memory leaks suchen?:
und mir war nicht klar,
dass ich für jedes GDI Object .. hier CPen/CBrush.. die "DeleteObject" Method explizt aufrufen muss, dachte das mach dann deren Dtor... und Memory Dumpy bekam ich da auch nicht...CPen blackPen; blackPen.CreatePen(PS_SOLID,1,RGB(0,0,0)); CBrush brush(atol(m_Data.GetAt(i-1,2))); pDC->SelectObject(&blackPen); pDC->SelectObject(brush); ... brush.DeleteObject(); blackPen.DeleteObject();
Wieso meinst du dass du das musst bzw. dass der von dir gezeigte Code korrekt ist?
Soweit ich weiss sollte das eher so aussehen:
CPen blackPen; blackPen.CreatePen(PS_SOLID,1,RGB(0,0,0)); CBrush brush(atol(m_Data.GetAt(i-1,2))); CPen* originalPen = pDC->SelectObject(&blackPen); CBrush* originalBrush = pDC->SelectObject(&brush); ... pDC->SelectObject(originalPen); pDC->SelectObject(originalBrush);
-
@hustbaer sagte in Wie nach memory leaks suchen?:
Wieso meinst du dass du das musst bzw. dass der von dir gezeigte Code korrekt ist?
Soweit ich weiss sollte das eher so aussehen:CPen blackPen;
blackPen.CreatePen(PS_SOLID,1,RGB(0,0,0));
CBrush brush(atol(m_Data.GetAt(i-1,2)));
CPen* originalPen = pDC->SelectObject(&blackPen);
CBrush* originalBrush = pDC->SelectObject(&brush);
...
pDC->SelectObject(originalPen);
pDC->SelectObject(originalBrush);ja siehe oben, das habe ich noch vergessen im code-snipped (SelectObject(orgObjects).. aber trotzdem mit DeleteObject
EDIT: hmmm.. was is nun richtig....!?
-
@SoIntMan sagte in Wie nach memory leaks suchen?:
@hustbaer sagte in Wie nach memory leaks suchen?:
Wieso meinst du dass du das musst bzw. dass der von dir gezeigte Code korrekt ist?
Soweit ich weiss sollte das eher so aussehen:CPen blackPen;
blackPen.CreatePen(PS_SOLID,1,RGB(0,0,0));
CBrush brush(atol(m_Data.GetAt(i-1,2)));
CPen* originalPen = pDC->SelectObject(&blackPen);
CBrush* originalBrush = pDC->SelectObject(&brush);
...
pDC->SelectObject(originalPen);
pDC->SelectObject(originalBrush);ja siehe oben, das habe ich noch vergessen im code-snipped (SelectObject(orgObjects).. aber trotzdem mit DeleteObject
EDIT: hmmm.. was is nun richtig....!?
Die schreiben doch auch dass das
DeleteObject
nicht nötig ist:Not that it makes much difference (I consider it good style to call CGdiObject::DeleteObject explicitly) but the destructor for the individual object types will delete the object automatically.
Therefore there is no actual need to call DeleteObject if you're declaring a local GDI object inside a loop (providing you remember to deselect it from the DC first) as it will be called automatically when the object goes out of scope.Gut, der meint dass er es "good style" findet trotzdem selbst
DeleteObject
aufzurufen. Ich bin da ganz anderer Meinung. Ich finde dass das ganz schlechter Stil ist. Unnötiger Code bremst bloss beim Lesen und ist - gerade für Leute die sich noch nicht perfekt mit dem verwendeten Framework auskennen - verwirrend/schädlich. Weil man normalerweise halt nicht davon ausgeht dass jemand was hinschreibt was völlig redundant ist. Und daher kann man dann schnell annehmen, dass es halt nicht redundant ist. Was ja wie gesagt nicht stimmt.Darüber ob die Objekte jetzt automatisch gelöscht werden oder nicht besteht aber kein Zweifel. Das steht da auch klar in dem Thread dass sie das werden.
-
@SoIntMan sagte in Wie nach memory leaks suchen?:
Nun habe ich beim schließen der App Memoryleaks:
wenn ein prozess beendet wird, erlischt auch sein virtueller adressraum.
d.h ein normales windows-programm kann üblicherweise keine memLeaks erzeugen, die das ganze system beeinträchtigen.
-
@Foulpelz sagte in Wie nach memory leaks suchen?:
d.h ein normales windows-programm kann üblicherweise keine memLeaks erzeugen, die das ganze system beeinträchtigen.
Doch.