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...