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
etargv
comme arguments demain
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.
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, 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.
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.
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.
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.
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.
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
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.