Ce que je fais c'est:

shmget(shm_key, shm_size, 0666 | IPC_CREAT); (et bien sûr y attacher)

Et j'ai déjà défini la taille à exactement 12 octets, mais lorsque j'essaye quelque chose comme:

sprintf(shm_ptr, "Imagine about 200-300 characters here\n");

Il semble fonctionner normalement sans aucun problème ni avertissement, et pour vérifier cela , j'ai essayé de le lire à partir d'un processus complètement différent (je fourre et exécute le premier) et bien sûr

printf("%s", shm_ptr);

Imprime le message qui était dans ce segment, qui est censé être 12 octets. Est-ce que System V IPC est censé être comme ça, et il n'y a pas de solution de contournement pour ce problème? Si oui, pourquoi définir une taille en premier lieu?

Merci pour votre temps et vos réponses à l'avance.

1
Angelino Mehmeti 24 nov. 2017 à 22:56

3 réponses

Meilleure réponse

Rien ne vous arrête, mais la spécification ne garantit aucun comportement spécifique pour ce cas.

En pratique, la taille réelle d'une région mémoire sera arrondie à une taille de page spécifique au système. Cela permet d'accéder à plus de mémoire que ce qui a été demandé, mais il peut y avoir des conséquences. Par exemple, les nettoyeurs de mémoire peuvent traiter cela comme une erreur.

Cela est vrai pour tous les mappages de mémoire, y compris ceux créés avec mmap.

Maintenant, pourquoi avez-vous besoin d'accéder à la mémoire au-delà de la région demandée? Si vous avez besoin de plus de mémoire, demandez simplement plus. Avoir des désinfectants de mémoire qui ne deviennent pas fous en raison d'un comportement inattendu est une chose très utile. À part cela, je ne pense pas qu'il y ait de conséquences à cela, du moins je ne peux rien trouver.

ÉDITER: Si vous voulez trouver des erreurs d'accès dans votre code, vous pouvez mettre une seule «page de garde» à la fin de votre bloc mémoire. Allouez simplement une page supplémentaire de mémoire et utilisez mprotect pour changer ses droits d'accès en PROT_NONE. De cette façon, vous obtiendrez segfault si vous allez au-delà de votre cartographie (mais pas plus d'une page).

2
usr 24 nov. 2017 à 20:24

Le matériel MMU corrige la taille de la page, votre espace d'adressage virtuel est donc organisé en pages de 4 Ko. .

Tout segment d'adresse virtuelle (même celui de SysV IPCMEM) est un multiple de cette taille de page. Utilisez sysconf (3) avec PAGESIZE ou getpagesize (2) pour l'obtenir.

(et Linux a aussi des "pages énormes" par exemple de 1 Mo sur x86).

BTW, lisez proc (5) et envisagez d'utiliser {{ X0}} ou /proc/1234/maps pour le processus du pid 1234 à interroger l 'espace d'adressage virtuel de ce processus ....

PS. Préférez utiliser shm_overview (7).

1
Basile Starynkevitch 24 nov. 2017 à 20:08

Rien ne vous empêche d'essayer d'utiliser des adresses en dehors de la région. Mais rien ne vous protège non plus des conséquences possibles.

Cela pourrait simplement se comporter comme si la région était plus grande. Cela peut segfault (ou tout autre équivalent sur votre plateforme). Cela pourrait écraser la mémoire de tas aléatoire, provoquant un mauvais comportement de votre programme de manière imprévisible. Il peut faire n'importe quoi .

C ne fournit pas de tuteur garantissant que vous respectez les règles. Les tuteurs coûtent cher et si vous en voulez un, vous devrez le payer vous-même (en écrivant le code de garde, et en l'exécutant au besoin).

1
rici 24 nov. 2017 à 20:05
47479323