IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Linux Discussion :

fuite de memoire: timer_delete


Sujet :

Linux

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2008
    Messages : 11
    Points : 8
    Points
    8
    Par défaut fuite de memoire: timer_delete
    Bonjour,

    J'utilise les minuteurs (timers) temps réel de l'extension POSIX sous Linux (Dernières Ubuntu et Debian) (timer_create, timer_delete, timer_settime, ...).

    J'arrive à les utiliser convenablement, mais j'ai un petit soucis lorsque je défini l'événement de notification comme étant un thread (SIGEV_THREAD assigné à sigevent.sigev_notify): Je n'arrive tout simplement pas à me débarrasser de deux erreurs valgrind:

    1) valeur non initialisée lors de l'appel timer_delete:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Conditional jump or move depends on uninitialised value(s)
    ==29792==    at 0x4E30608: timer_delete (in /lib/librt-2.9.so)
    ==29792==    by 0x400B06: main (in /home/alex/svn/libcomm/test_timer2)
    ==29792==  Uninitialised value was created by a heap allocation
    ==29792==    at 0x4C278AE: malloc (vg_replace_malloc.c:207)
    ==29792==    by 0x4E3044A: timer_create (in /lib/librt-2.9.so)
    ==29792==    by 0x400A65: main (in /home/alex/svn/libcomm/test_timer2)
    2) fuite de mémoire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    272 bytes in 1 blocks are possibly lost in loss record 1 of 1
    ==29792==    at 0x4C25684: calloc (vg_replace_malloc.c:397)
    ==29792==    by 0x4012225: _dl_allocate_tls (in /lib/ld-2.9.so)
    ==29792==    by 0x53AC5E3: pthread_create@@GLIBC_2.2.5 (in /lib/libpthread-2.9.so)
    ==29792==    by 0x4E31558: (within /lib/librt-2.9.so)
    ==29792==    by 0x53B25D2: pthread_once (in /lib/libpthread-2.9.so)
    ==29792==    by 0x4E30421: timer_create (in /lib/librt-2.9.so)
    ==29792==    by 0x400A65: main (in /home/alex/svn/libcomm/test_timer2)
    Bon la première erreur est moins importante car elle apparaît qu'en x86_64. Par contre la fuite de mémoire est plus embêtante, surtout que j'utilise ces timers dans le cadre d'une bibliothèque et que je n'ai pas envie qu'il y ait de fuite de mémoire.

    Pour reproduire ces erreurs, je vous invite à essayer le code suivant (trouvé ici )

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    /* Tests for POSIX timer implementation. */
    #include <errno.h>
    #include <signal.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <unistd.h>
     
    void hexdump(int * data, size_t length);
     
    static void
    notify_func1 (union sigval sigval)
    {
      puts ("notify_func1");
    }
     
    static void
    intr_sleep (int sec)
    {
      struct timespec ts;
     
      ts.tv_sec = sec;
      ts.tv_nsec = 0;
     
      while (nanosleep (&ts, &ts) == -1 && errno == EINTR)
        ;
    }
     
    #define ZSIGALRM 14
     
    void
    hexdump(int * data, size_t length)
    {
      unsigned int i;
      size_t wordlength = length / 4;
      for (i=0; i < wordlength; i++)
        {
          if ((i % 8) == 0)
            printf("\n");
          printf("%08x ", data[i]);
        }
      printf("\n");
    }
     
    int
    main (void)
    {
      timer_t timer_thr1;
      struct sigevent sigev2;
      struct itimerspec itimer2 = { { 0, 100000000 }, { 0, 500000000 } };
      struct itimerspec old;
     
      memset(&timer_thr1, '\0', sizeof(timer_thr1));  
      memset(&sigev2, '\0', sizeof(sigev2));  
     
      sigev2.sigev_notify = SIGEV_THREAD;
      sigev2.sigev_notify_function = notify_func1;
      sigev2.sigev_notify_attributes = NULL;
      /* It is unnecessary to do the following but to set a good example
         we do it anyhow.  */
      sigev2.sigev_value.sival_ptr = NULL;
     
      setvbuf (stdout, 0, _IOLBF, 0);
     
      hexdump((int *)&sigev2, sizeof(sigev2));
      hexdump((int *)&timer_thr1, sizeof(timer_thr1));
     
      if (timer_create (CLOCK_REALTIME, &sigev2, &timer_thr1) != 0)
        {
          printf ("timer_create for timer_thr1 failed: %m\n");
          exit (1);
        }
     
      hexdump((int *)&sigev2, sizeof(sigev2));
      hexdump((int *)&timer_thr1, sizeof(timer_thr1));
     
      if (timer_settime (timer_thr1, 0, &itimer2, &old) != 0)
        {
          printf ("timer_settime for timer_thr1 failed: %m\n");
          exit (1);
        }
     
      hexdump((int *)&sigev2, sizeof(sigev2));
      hexdump((int *)&timer_thr1, sizeof(timer_thr1));
      intr_sleep (6);
     
      if (timer_delete (timer_thr1) != 0)
        {
          printf ("timer_delete for timer_thr1 failed: %m\n");
          exit (1);
        }
      return 0;
    }
    Quelqu'un aurait-il une piste à suivre pour éviter une telle fuite (timers mal utilisés)?

    Rappelez-vous que cela n'arrive que lorsque je défini une notification par thread (SIGEV_THREAD). Lorsque je mets (SIGEV_NONE) il y a pas de fuite. J'ai l'impression que c'est un bug de l'implémentation du noyau Linux.

    D'avance merci.

    P.S. Je pense que ce sujet devrait être déplacé dans Linux -> Programmation...

  2. #2
    Membre émérite Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Points : 2 280
    Points
    2 280
    Par défaut
    bon, j'ai nettoyé ton code pour que les gens puissent plus facilement le comprendre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    /* Tests for POSIX timer implementation. */
    #include <errno.h>
    #include <signal.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <unistd.h>
     
    static void hexdump(void const * data, size_t length)
    {   
       unsigned char const * raw_bytes = data;
     
       for (size_t i = 0; i < length; i++)
       {
          if ((i % 8) == 0)
             puts("");
     
          printf("%02hhx ", raw_bytes[i]);
       }
     
       puts("");
    }
     
    static void notify_func1(union sigval sigval)
    {
       puts(sigval.sival_ptr);
    }
     
    int main(void)
    {
       timer_t timer;
     
       struct sigevent event =
       {
          .sigev_notify = SIGEV_THREAD,
          .sigev_notify_function = notify_func1,
          .sigev_value.sival_ptr = "argument pass to thread"
       };
     
       struct itimerspec timeout = 
       {
          { .tv_nsec = 100000000 }, 
          { .tv_nsec = 500000000 }
       };
     
       hexdump(&event, sizeof event);
       hexdump(&timer, sizeof timer);
     
       if(timer_create(CLOCK_REALTIME, &event, &timer) == -1)
       {
          printf("timer_create for timer failed: %m");
       }
       else
       {
          hexdump(&event, sizeof event);
          hexdump(&timer, sizeof timer);
     
          if(timer_settime(timer, 0, &timeout, NULL) == -1)
          {
             printf("timer_settime for timer failed: %m\n");
          }
          else
          {
             hexdump(&event, sizeof event);
             hexdump(&timer, sizeof timer);
     
             sleep(6);
          }
     
          timer_delete(timer);
       }
     
       return 0;
    }
    Pour le premier warning, il vient du fait que la bibliothèque temps réel (librt) est compiler en mode release et non en mode debug, les optimisations qu'opère le compilateur dans ce cas là trahisse valgrind, il faudrait récupérer les sources et la recompiler avec les options "-O0 -ggdb3".
    Pour le second warning, il faut savoir que la bibliothèque pthread est bourré de leak mémoire, une partie est déjà caché par l'équipe de valgrind dans les fichiers .supp qui vont bien, pour le reste, tu peux toujours tenter l'impossible, c'est à dire faire comprendre à Monsieur Drepper qu'il n'est pas infaillible (d'autre s'y sont déjà essayé en vain: http://sources.redhat.com/bugzilla/show_bug.cgi?id=5171 ).
    Cordialement.

Discussions similaires

  1. [JVM]Fuite de mémoire
    Par anykeyh dans le forum Général Java
    Réponses: 6
    Dernier message: 28/09/2009, 23h43
  2. [memoire]Fuite de memoire?
    Par clovis dans le forum C++Builder
    Réponses: 2
    Dernier message: 27/01/2006, 23h04
  3. Outils pour rechercher des fuites de memoires dans un prog
    Par elekis dans le forum Applications et environnements graphiques
    Réponses: 5
    Dernier message: 29/04/2005, 22h06
  4. fuite de memoire dans une liste de pointeur sur composant
    Par Nicolos_A dans le forum Composants VCL
    Réponses: 2
    Dernier message: 16/12/2004, 09h46
  5. correction de fuite de memoire
    Par vince3320 dans le forum C
    Réponses: 38
    Dernier message: 28/06/2004, 12h27

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo