2010-05-12 2 views
1

Sur mon Windows 7, ce simple programme provoque l'utilisation continue de l'application en mémoire, sans limite supérieure. J'ai enlevé tout non-essentiel, et il semble clair que le coupable est la fonction de Microsoft Iphlpapi "GetIpAddrTable()". À chaque appel, il perd de la mémoire. Dans une boucle (par exemple, vérifier les modifications apportées à la liste d'interface réseau), cela n'est pas viable. Il ne semble pas y avoir d'API de notification asynchrone capable de faire ce travail, alors maintenant je suis confronté à devoir isoler cette logique dans un processus séparé et recycler le processus périodiquement - une solution laide.GetIpAddrTable() fuit la mémoire. Comment résoudre cela?

Des idées?

// IphlpLeak.cpp - demonstrates that GetIpAddrTable leaks memory internally: run this and watch 
// the memory use of the app climb up continuously with no upper bound. 
#include <stdio.h> 
#include <windows.h> 
#include <assert.h> 
#include <Iphlpapi.h> 
#pragma comment(lib,"Iphlpapi.lib") 

void testLeak() { 
    static unsigned char buf[16384]; 
    DWORD dwSize(sizeof(buf)); 
    if (GetIpAddrTable((PMIB_IPADDRTABLE)buf, &dwSize, false) == ERROR_INSUFFICIENT_BUFFER) 
    { 
     assert(0); // we never hit this branch. 
     return; 
    } 
} 
int main(int argc, char* argv[]) { 
    for (int i = 0; true; i++) { 
     testLeak(); 
     printf("i=%d\n",i); 
     Sleep(1000); 
    } 
    return 0; 
} 

Répondre

1

Je suis allé partout dans cette question maintenant: il semble qu'il n'y a pas d'accusé de Microsoft en la matière, mais même Une application triviale se développe sans limites sur Windows 7 (pas XP, cependant) lors de l'appel de l'une des API qui récupèrent les adresses IP locales. Donc, la façon dont je l'ai résolu - pour l'instant - était de lancer une instance séparée de mon application avec un commutateur de ligne de commande spécial qui lui dit "récupérer les adresses IP et les imprimer sur stdout". Je gratte stdout dans l'application parent, l'enfant se termine et le problème de fuite est résolu.

Mais il gagne "dang laide solution à un problème ennuyeux", au mieux.

1

Juste pour être complet, ce qui se passe à l'utilisation de la mémoire si vous commentez le bloc entier if et le sleep? S'il n'y a pas de fuite, je dirais que vous avez raison de savoir ce qui cause le problème. Dans le pire des cas, signalez-le à MS et voyez s'il peut y remédier - vous avez un bon cas de test simple à travailler, ce qui est plus que ce que je vois dans la plupart des rapports de bogues.

Une autre chose que vous pouvez essayer est de vérifier le code d'erreur par rapport à NO_ERROR plutôt qu'une condition d'erreur spécifique. Si vous revenez une autre erreur que ERROR_INSUFFICIENT_BUFFER, il peut y avoir une fuite pour cela:

DWORD dwRetVal = GetIpAddrTable((PMIB_IPADDRTABLE)buf, &dwSize, false); 
if (dwRetVal != NO_ERROR) { 
    printf ("ERROR: %d\n", dwRetVal); 
} 
+0

Merci - oui, le code cesse de fuir si j'arrête d'appeler GetIpAddrTable. L'idée de vérifier un code de retour alternatif est bonne, mais le code de production fait cela - la fuite persiste. Pour ce qui est de la notification à Microsoft ... eh bien, je suppose que j'ai une obligation communautaire à le faire, mais pour ce qui est de résoudre mon problème afin que je puisse expédier le produit, ce n'est pas vraiment pratique. Je pense à changer complètement de vitesse - appelez gethostname(), puis gethostbyname() pour récupérer la liste des adresses IP liées à ce nom. Cela devrait suffire, bien qu'il laisse ce mystère irritant. – Stabledog

2

@Stabledog: J'ai exécuté votre exemple, non modifié, pendant 24 heures mais n'a pas observé que la taille de validation du programme a augmenté indéfiniment. Il est toujours resté en dessous de 1024 kilooctets. C'était sur Windows 7 (32 bits, et sans Service Pack 1).

+0

Merci d'être venu. Comme c'était il y a plusieurs années, je ne me souviens pas si je suis allé au fond du problème ou pas - ma propre solution affichée sur cette réponse indique que j'ai pris une solution de contournement. Ces jours-ci, je ne travaille même pas sur Windows, et mon cerveau vieillissant ne peut pas retenir les détails sur de telles choses! :) – Stabledog

Questions connexes