AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein C++ Speicherlecks in fremdem Code/Programm finden
Thema durchsuchen
Ansicht
Themen-Optionen

Speicherlecks in fremdem Code/Programm finden

Ein Thema von Dalai · begonnen am 30. Dez 2016 · letzter Beitrag vom 31. Jan 2017
Antwort Antwort
nahpets
(Gast)

n/a Beiträge
 
#1

AW: Speicherlecks in fremdem Code/Programm finden

  Alt 6. Jan 2017, 16:04
Meine C++-Kenntnisse tendieren gegen 0.

In der von Dir genannten Routine wird in 'ner Schleife mehr oder weniger häufig
Code:
currentBlock = new xAPBlockHeader(currentPos);
bzw.
Code:
currentBlock = new xAPBlockData(currentPos);
aufgerufen. Hier wird ja wohl irgendwas neu erstellt. Was ich nicht finden kann ist die Stelle, an der wieder aufgeräumt wird.
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#2

AW: Speicherlecks in fremdem Code/Programm finden

  Alt 6. Jan 2017, 18:06
Aufgräumt wird später in Zeile 271, aber so wie ich das sehe wird im Block von 239 - 249 unter bestimmten Konditionen das push_back vergessen.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.684 Beiträge
 
Delphi 5 Professional
 
#3

AW: Speicherlecks in fremdem Code/Programm finden

  Alt 8. Jan 2017, 15:18
Aufgräumt wird später in Zeile 271 [...]
So ist es.

Zitat:
[...] aber so wie ich das sehe wird im Block von 239 - 249 unter bestimmten Konditionen das push_back vergessen.
Nein. Man muss hier leider ein bisschen um die Ecke denken. Der Header wird erst beim folgenden Schleifendurchlauf in die Variable blocks aufgenommen. Der letzte Datenblock folgt dann durch das push_back() nach der while-Schleife.

---

Ich glaube aber, das Leck gefunden zu haben - ich hoffe, ich bin da nicht vorschnell (Test läuft gerade). Im xAP-Protokoll, das SpeedFan da benutzt, wird Broadcasting eingesetzt, d.h. die Pakete aller Rechner kommen auf jedem Munin-Node an. Zusätzlich gibt es wohl Heartbeat-Pakete (Beispiel in example2.txt), die anzeigen "ich lebe noch".

Der Inhalt der Variable blocks wird durch die while-Schleife zusammengebaut, egal, was da für ein Paket reinkommt. Für jeden Abschnitt des Pakets wird mit new ein currentBlock erzeugt, und einzeln an blocks angehängt. In Zeile 267 wird der Inhalt der Variable blocks nur dann an die Klassenvariable m_Blocks weitergegeben, wenn die UID übereinstimmt (und es ein Datenpaket war und kein Heartbeat).

Aber was passiert mit dem Inhalt der Variable blocks, wenn das nicht zutrifft, es also das Paket mit einer anderen UID oder ein Heartbeat war? Der dengelt weiter im Speicher rum, ohne zerstört zu werden, denn die Zerstörung passiert nur mit dem Inhalt der Klassenvariable beim nächsten Paket. Das erklärt auch, warum die Zunahme des Speichers mit der Anzahl der mit SpeedFan (mit aktiviertem xAP) laufenden Rechner im LAN ansteigt - mehr Heartbeats, mehr auf dem Heap erzeugte Objekte, die nicht wieder weggeräumt werden.

Meine Lösung sieht daher momentan so aus, dass ich in Zeile 276 folgenden Teil zur if-Bedingung aus 267 ergänzt habe:
Code:
} else {
    for (std::vector<xAPBlock *>::iterator it = blocks.begin(); it != blocks.end(); it++)
      delete *it;
}
um alle Objekte in blocks wieder aufzuräumen. Das sollte alle nötigen Fälle abdecken.

Ob's das wirklich ist (und das einzige Leck), wird sich zeigen.

Grüße
Dalai

Geändert von Dalai ( 8. Jan 2017 um 15:21 Uhr)
  Mit Zitat antworten Zitat
Delphi-Laie

Registriert seit: 25. Nov 2005
1.474 Beiträge
 
Delphi 10.1 Berlin Starter
 
#4

AW: Speicherlecks in fremdem Code/Programm finden

  Alt 8. Jan 2017, 16:44
Trägt zwar nichts zur Problemlösung bei, soll aber verdeutlichen, daß es den Menschen wie den Leuten geht: Wen zur Abwechslung mal interessiert, wie ein sehr schwierig aufzuspürender Softwarefehler wochenlang gesucht, irgendwann gefunden und dann recht einfach beseitigt wurde, der möge diese Dokumentation dazu lesen.
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.684 Beiträge
 
Delphi 5 Professional
 
#5

AW: Speicherlecks in fremdem Code/Programm finden

  Alt 10. Jan 2017, 20:57
Kleiner Nachtrag: Das Speicherleck ist definitiv gestopft. Nach 7,5 Stunden Laufzeit und einer Zunahme des Working Set von nur ca. 40 KB kann ich das guten Gewissens behaupten; diesmal lief es auf einem Win7 x64 mit x64 Prozess, daher ist der Wert nur bedingt vergleichbar mit den vorherigen. Möglicherweise sind noch weitere kleinere Lecks enthalten, aber das kann nur mit einem wesentlich längeren Untersuchungszeitraum ermittelt werden.

Ich habe den Code noch etwas angepasst:
Code:
size_t SpeedFanNodePlugin::ListenerThread::ProcessBuffer(char *buffer)
{
  ...
  bool clearblocks = false;
  ...

  if (headerBlock != NULL) {
    ...
    if (headerBlock->uid == uid && headerBlock->xAPClass == "PC.status") {
    ...
    } else {
      clearblocks = true;
    }
  } else {
    clearblocks = true;
  }

  if (clearblocks)
    for (std::vector<xAPBlock *>::iterator it = blocks.begin(); it != blocks.end(); it++)
      delete *it;
  ...
}
So wird in jedem Fall aufgeräumt, wenn's nix zu verarbeiten gab. Wahrscheinlich könnte man die boolsche Variable sogar weglassen, weil die Funktion im "guten" Fall sowieso vorher mit return verlassen wird.

Danke an alle Beteiligten!

Grüße
Dalai
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.684 Beiträge
 
Delphi 5 Professional
 
#6

AW: Speicherlecks in fremdem Code/Programm finden

  Alt 31. Jan 2017, 17:42
Nach gut zwei Wochen ununterbrochener Laufzeit des Munin Node auf meinem Server (XP) und einer einzigen Zunahme des Working Set um ~75 KiB nach einem Tag (aber keiner weiteren) kann ich behaupten, dass das Leck wohl das einzige war. Beschränkt wird diese Behauptung lediglich durch das OS sowie die von mir verwendete Konfiguration, in der nahezu alle Plugins eingeschaltet sind. Ich nehme aber schon an, dass sich der Node auf anderen Windows-Versionen analog verhält.

Klasse, endlich Munin Node auf Windows-Systemen ohne geplanten Task, der selbigen jede Woche neu startet .

Danke und Grüße
Dalai
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:43 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz