Frage Kann argc Überlauf?


Ich bin in SO herumgewandert und habe gesehen diese Frage. Dann habe ich mich gefragt, ob ich argc überlaufen kann.

Standard sagt das argv[argc] muss ein Nullzeiger sein, aber dies ist falsch, wenn argc überläuft.

(ICH schrieb ein kleines C-Programm und ein Python-Skript, um es zu testen, aber bekam ein MemoryError.)

Vielen Dank!


Begründung für den Internationalen Standard - Programmiersprachen - C §5.1.2.2.1 Programmstart

Die Spezifikation von argc und argv als Argumente zu main erkennt umfangreiche vorherige Praxis an. argv[argc] Es muss ein Nullzeiger sein, um eine redundante Überprüfung für das Ende der Liste bereitzustellen, auch auf der Grundlage der üblichen Praxis.


75
2018-01-21 19:32


Ursprung


Antworten:


Gemäß dem Standard

Also, von deinem Zitat:

argv[argc] muss ein Nullzeiger sein

Deshalb, argc kann nicht überlaufen, weil dann die obige Aussage nicht wahr wäre.

In der Praxis

In der Praxis ist die Gesamtgröße der an ein Programm übergebenen Argumente begrenzt.

Auf meinem Linux / x64-System:

$ getconf ARG_MAX
2097152

Daher beträgt die Gesamtgröße des Arguments etwa 2 Megabyte argc kann nicht überlaufen. Ich glaube, diese Grenze misst eine Kombination der gesamten Daten in argv und die Umwelt. Wenn Sie dieses Limit überschreiten, wenn Sie versuchen, einen Befehl auszuführen, exec() wird mit scheitern E2BIG. Von man 2 execve:

E2BIG Die Gesamtzahl der Bytes in der Umgebung (envp) und im Argument
       Liste (argv) ist zu groß.

Ich glaube, dass die Grenze von ~ 2 Megabyte auf meinem System im Vergleich zu anderen Systemen relativ großzügig ist. Mein OS X-System meldet ein Limit von ~ 260 KB.

Aber was wenn ARG_MAX Waren wirklich groß?

Okay, nehmen wir an, Sie sind auf einem alten / seltsamen System, also int ist 16 Bits und ARG_MAX ist weit über 215, was sonst ganz vernünftig ist. Angenommen, Sie rufen auf execve() mit mehr als 215 Argumente. Die Implementierung hat zwei Optionen.

  1. Es kann erlauben argc Überlaufen ... im Grunde, indem Sie Ihre Daten wegwerfen und sicherstellen, dass das Programm, das Sie ausführen, auf unerwartete und wahrscheinlich fehlerhafte Weise ausgeführt wird und gegen den C-Standard verstößt. Am schlimmsten ist, dass der Fehler stumm ist, so dass Sie vielleicht nie wissen werden.

  2. Oder es kann einfach zurückkehren EOVERFLOW von execve()Sie werden darauf hingewiesen, dass ein Bild mit so vielen Parametern nicht ausgeführt werden kann. Nun erwähnen die POSIX / SUS-Standards nichts über dieses Fehlerergebnis ... aber ich vermute, dass dies einfach deshalb ist, weil die Standardschreiber niemals erwartet haben ARG_MAX größer sein als INT_MAX.

Option # 2 ist die nur vernünftige Option. Wenn Ihr System irgendwie Option 1 wählt, dann ist es das gebrochen und Sie sollten einen Fehlerbericht einreichen.

Alternativ könnten Sie versuchen, ein altes Programm auszuführen, das für ein 16-Bit-System kompiliert wurde, aber Sie führen es durch eine Art von Emulator oder Kompatibilitätsebene. Ich würde erwarten, dass der Emulator oder die Kompatibilitätsebene eine Fehlermeldung ausgeben würde, wenn Sie versuchen, mehr als 2 zu übergeben15Parameter zu einem Programm.


78
2018-01-21 19:38



In der Praxis, nein, das kannst du nicht. Die meisten Systeme legen eine relativ niedrige Grenze für die Gesamtgröße von argv und envp. Limits in den Zehner- bis zu low-Hunderten von KB sind nicht ungewöhnlich; sehen http://www.in-ulm.de/~mascheck/various/argmax/ für eine einigermaßen umfassende Auflistung der Beschränkungen für verschiedene Betriebssysteme.


17
2018-01-21 19:38



Ich habe es versucht:

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;
}

Dann habe ich eine große Zip-Datei verwendet

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

Lesen Sie dann die Datei als Parameter zum Testprogramm:

  ./test $(more bigfile)

Ergebnis:

5 minutes nothing happend, then everything froze

Dann habe ich eine kleinere Datei ausprobiert:

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

Und:

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

10
2018-01-22 15:07



Wie vom Standard angegeben, muss argv [argc] ein gültiger Wert sein.

Wenn sich die Laufzeitumgebung in einer Situation befindet, in der dies nicht garantiert werden kann, sollte das Programm nicht gestartet werden.


2
2018-01-28 14:12