web-dev-qa-db-fra.com

L'argc peut-il déborder?

Je me promenais dans SO et j'ai vu cette question . Puis j'ai commencé à me demander si je pouvais déborder argc.

Standard dit que argv[argc] doit être un pointeur nul mais ce sera faux si l'argc déborde.

(I écrit un petit programme C et un script python pour le tester mais a obtenu un MemoryError.))

Merci!


Justification de la norme internationale - Langages de programmation - C §5.1.2.2.1 Démarrage du programme

La spécification de argc et argv comme arguments de main reconnaît une pratique antérieure étendue. argv[argc] doit être un pointeur nul pour fournir un contrôle redondant pour la fin de la liste, également sur la base d'une pratique courante.

75
Bora M. Alper

Selon la norme

Donc, à partir de votre citation:

argv[argc] Doit être un pointeur nul

Par conséquent, argc ne peut pas déborder, car alors l'instruction ci-dessus ne serait pas vraie.

En pratique

En pratique, la taille totale des arguments passés à un programme est limitée.

Sur mon système Linux/x64:

 $ getconf ARG_MAX 
 2097152 

Par conséquent, la taille totale des arguments est d'environ 2 mégaoctets et argc ne peut pas déborder. Je crois que cette limite mesure une combinaison des données totales dans argv et l'environnement. Si vous dépassez cette limite lorsque vous essayez d'exécuter une commande, exec() échouera avec E2BIG. De man 2 execve :

 E2BIG Le nombre total d'octets dans l'environnement (envp) et l'argument 
 List (argv) est trop grand. 

Je crois que la limite de ~ 2 mégaoctets sur mon système est relativement généreuse par rapport à d'autres systèmes. Mon système OS X signale une limite de ~ 260 Ko.

Mais que faire si ARG_MAX Était vraiment gros?

D'accord, supposons que vous êtes sur un ancien système/étrange, donc int est 16 bits, et ARG_MAX est bien plus de 215, ce qui est par ailleurs tout à fait raisonnable. Supposons maintenant que vous appelez execve() avec plus de 215 arguments. La mise en œuvre a deux options.

  1. Il peut permettre à argc de déborder ... en gros, en jetant vos données, en vous assurant que le programme que vous exécutez s'exécute de manière inattendue et probablement erronée, et en violant la norme C. Pire encore, l'erreur est silencieuse, vous ne le saurez peut-être jamais.

  2. Ou, il peut simplement retourner EOVERFLOW à partir de execve(), vous informant qu'il ne peut tout simplement pas exécuter une image avec autant de paramètres. Maintenant, les normes POSIX/SUS ne mentionnent rien à propos de ce résultat d'erreur ... mais, je suppose que c'est simplement parce que les rédacteurs standard ne s'attendaient pas à ce que ARG_MAX Soit plus grand que INT_MAX.

L'option n ° 2 est l'option uniquement raisonnable. Si votre système choisit en quelque sorte l'option # 1, alors elle est cassée et vous devez déposer un rapport de bogue.

Vous pouvez également essayer d'exécuter un ancien programme compilé pour un système 16 bits, mais vous l'exécutez via une sorte d'émulateur ou de couche de compatibilité. Je suppose que l'émulateur ou la couche de compatibilité donnerait un message d'erreur si vous tentiez de passer plus de 215 paramètres à un programme.

78
Dietrich Epp

En pratique, non, vous ne pouvez pas. La plupart des systèmes imposent une limite relativement faible à la taille totale combinée de argv et envp. Les limites dans les dizaines à des centaines de Ko faibles ne sont pas rares; voir http://www.in-ulm.de/~mascheck/various/argmax/ pour une liste raisonnablement complète des limites sur divers OS.

17
duskwuff

J'ai essayé ceci:

test.c:

 ⚡⚡⚡  more test.c 
#include <stdio.h>
int main(int argc, char **argv)
{
    printf("argc = %d\n", argc);
    printf("Size of argc = %d\n", sizeof(argc));
    return 0;
}

Puis utilisé un gros fichier zip

 ⚡⚡⚡  ls -h bigfile 
-rw-r--r-- 1 ehwas ehwas 355M Jan 22 16:54 bigfile

Ensuite, lisez le fichier en tant que paramètres du programme de test:

⚡⚡⚡  ./test $(more bigfile)

Résultat:

5 minutes nothing happend, then everything froze

J'ai ensuite essayé un fichier plus petit:

 ⚡⚡⚡  ls -h notsobigfile 
-rw-r--r-- 1 ehwas ehwas 6.7M Jan 22 17:04 notsobigfile

Et:

 ⚡⚡⚡  ./test $(more notsobigfile)
bash: ./test: Argument list too long
10
ehwas

Comme indiqué par la norme, argv [argc] doit être une valeur valide.

Donc, si l'environnement d'exécution se trouve dans une situation telle qu'il ne peut pas garantir cela, il ne doit pas démarrer le programme.

2
Yves Daoust