shmget: comportement que je ne comprends pas

shmget: comportement que je ne comprends pas - C - Programmation

Marsh Posté le 06-12-2007 à 22:46:23    

Voici un bout de code qui met en évidence ce que je ne pige pas (c'est un extrait dépouillé d'un plus gros programme sur lequel je suis en ce moment):

 
Code :
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <sys/shm.h>
  5. #define SIZE_MAX 32
  6. #define SHM_WATCH_OFFSET 0x02200000
  7. void *ipctool_shared_get(key_t shared_key);
  8. int ipctool_shared_create(key_t shared_key, char *pval, int len, size_t size, void **ppshm);
  9. int main(int argc, char **argv)
  10. {
  11.     fprintf(stderr, "dbg0: sizeof(key_t): %i\n", sizeof(key_t));
  12.    
  13.     ipctool_shared_create((key_t)(SHM_WATCH_OFFSET + 80    ), NULL, 0, sizeof(void *) * SIZE_MAX, NULL);
  14.     ipctool_shared_create((key_t)(SHM_WATCH_OFFSET + 8080), NULL, 0, sizeof(void *) * SIZE_MAX, NULL);
  15.    
  16.     ipctool_shared_get((key_t)(SHM_WATCH_OFFSET + 80    ));
  17.     ipctool_shared_get((key_t)(SHM_WATCH_OFFSET + 8080));
  18.     ipctool_shared_get((key_t)(SHM_WATCH_OFFSET + 1080));
  19.     return 0;
  20. }
  21. void *ipctool_shared_get(key_t shared_key)
  22. {
  23.     int id, *ptr;
  24.    
  25.     fprintf(stderr, "dbg2: shared_key: %08X\n", shared_key);
  26.     if ((id = shmget(shared_key, 0, 0600)) == -1)
  27.     {
  28.         perror("ipctool_shared_get.shmget:" );
  29.         return NULL;
  30.     }
  31.     if ((ptr = shmat(id, NULL, 0)) == (void *)-1)
  32.     {
  33.         perror("ipctool_shared_get.shmat:" );
  34.         return NULL;
  35.     }
  36.     return (void *)ptr;
  37. }
  38. int ipctool_shared_create(key_t shared_key, char *pval, int len, size_t size, void **ppshm)
  39. {
  40.     int id, *ptr;
  41.    
  42.     fprintf(stderr, "dbg1: shared_key: %08X\n", shared_key);
  43.    
  44.     if ((id = shmget(shared_key, size, IPC_CREAT | 0600)) == -1)
  45.     {
  46.         perror("ipctool_shared_create.shmget:" );
  47.         return EXIT_FAILURE;
  48.     }
  49.     if ((ptr = shmat(id, NULL, 0)) == (void *)-1)
  50.     {
  51.         perror("ipctool_shared_create.shmat:" );
  52.         return EXIT_FAILURE;
  53.     }
  54.     memset(ptr, 0, size);
  55.     if (pval != NULL)
  56.     {
  57.         memcpy(ptr, pval, len);
  58.     }
  59.     if (ppshm == NULL)
  60.     {
  61.         if (shmdt(ptr) == -1)
  62.         {
  63.             perror("ipctool_shared_create.shmdt:" );
  64.             return EXIT_FAILURE;
  65.         }
  66.     }
  67.     else
  68.     {
  69.         *ppshm = ptr;
  70.     }
  71.     return EXIT_SUCCESS;
  72. }
 

Si j'execute ce code, aucune erreur ne se produit, alors que pourtant cela devrait être le cas lors du dernier appel à ipctool_shared_get (aucun segment de mémoire partagé correspondant à la clé SHM_WATCH_OFFSET + 1080 n'a été crée)

 

Si je réexecute ce code en changeant la valeur de SHM_WATCH_OFFSET de 0x02200000 à 0x00200000, cette fois l'erreur se produit bien. Pourquoi ? Aucune idée :-S La valeur de la clé est pourtant bien dans les 2 cas unique et stockable dans la taille de key_t.

 

Si quelqu'un a une piste pour éclairer ma lanterne je suis preneur ^^.


Message édité par sigmatador le 06-12-2007 à 22:49:25
Reply

Marsh Posté le 06-12-2007 à 22:46:23   

Reply

Marsh Posté le 07-12-2007 à 00:03:27    

Est-ce que tu es sûr que tu n'as pas de shared mem avec la clée SHM_WATCH_OFFSET + 1080 ? Fait un ipcs, et regarde si par hasard (ça serait pas de bol) tu n'aurais pas une clée 0x02200438.

Reply

Marsh Posté le 07-12-2007 à 01:10:19    

et bien si justement (merci pour la commande ipcs, je ne connaissais pas), probablement un reste de précedente execution (les valeur 80, 8080, 1080, etc... correspondent à des ports, le programme a fonctionné sur un paquet de ports différents)
 
vu que mon programme (le vrai) envoie une commande IPC_RMID via shmctl avant de quitter, normalement ca n'aurait pas du se produire...  dans le doute j'ai fait un reboot (~ $ uptime 01:02:41 up 150 days, 11:25,  1 user,  load average: 0.16, 0.04, 0.01 tout de même ^^),  tout à l'air d'être rentré dans l'ordre. Merci ^^
 
Juste une question, pour libérer un segment de mémoire partagée que l'on ne souhaite plus utiliser, c'est bien la commande IPC_RMID via shmctl ou j'ai loupé quelques chose ? ^^;;


Message édité par sigmatador le 07-12-2007 à 01:13:00
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed