web-dev-qa-db-ja.com

argcはオーバーフローできますか?

私はSOでさまよっていました この質問 を見ました。それから、argcをオーバーフローできるかどうか疑問に思い始めました。

スタンダードは、argv[argc]はnullポインターでなければなりませんが、argcがオーバーフローした場合はfalseになります。

(私は 書きました 小さなCプログラムとpythonスクリプトですが、MemoryErrorを取得しました。)

ありがとう!


国際標準の根拠—プログラミング言語— C §5.1.2.2.1プログラムの起動

argcへの引数としてのargvおよびmainの指定は、広範な従来の慣行を認識しています。 argv[argc]は、これも一般的な慣行に基づいて、リストの最後の冗長チェックを提供するためにnullポインターである必要があります。

75
Bora M. Alper

標準によると

だから、あなたの引用から:

_argv[argc]_はnullポインターである必要があります

したがって、argcはオーバーフローできません。これは、上記のステートメントが真ではないためです。

実際には

実際には、プログラムに渡される引数の合計サイズは制限されています。

Linux/x64システムの場合:

 $ getconf ARG_MAX 
 2097152 

したがって、引数の合計サイズは約2メガバイトであり、argcはオーバーフローできません。この制限は、argvの合計データと環境の組み合わせを測定していると思います。コマンドを実行しようとしたときにこの制限を超えると、exec()は_E2BIG_で失敗します。から _man 2 execve_

 E2BIG環境(envp)および引数
リスト(argv)の合計バイト数が大きすぎます。

私のシステムの最大2メガバイトの制限は、他のシステムに比べて比較的寛大だと思います。私のOS Xシステムは約260KBの制限を報告しています。

しかし、_ARG_MAX_が本当に大きい場合はどうなりますか?

さて、あなたが古い/奇妙なシステムを使っているとしましょう、それでintは16ビットであり、ARG_MAXは2をはるかに超えています15、それ以外の場合はかなり合理的です。ここで、2つ以上でexecve()を呼び出すとします。15 引数。実装には2つのオプションがあります。

  1. argcがオーバーフローする可能性があります...基本的に、データを破棄し、実行中のプログラムが予期しない、おそらく誤った方法で実行されることを保証し、C標準に違反します。最悪の場合、エラーはサイレントであるため、あなたは決して知ることができません。

  2. または、単純にexecve()からEOVERFLOWを返し、それだけの数のパラメータを使用してイメージを実行できないことを通知します。さて、POSIX/SUS標準はこのエラー結果について何も言及していません...しかし、これは単に標準の作家が_ARG_MAX_が_INT_MAX_。

オプション#2はonlyの合理的なオプションです。システムが何らかの方法でオプション#1を選択した場合、それはbrokenであり、バグレポートを提出する必要があります。

または、16ビットシステム用にコンパイルされた古いプログラムを実行しようとしている可能性がありますが、それをある種のエミュレーターまたは互換性レイヤーで実行しています。 2つ以上渡そうとした場合、エミュレーターまたは互換性レイヤーがエラーメッセージを表示すると思います15 プログラムへのパラメータ。

78
Dietrich Epp

実際には、できません。ほとんどのシステムでは、argvenvpの合計サイズに比較的低い制限を設けています。数十から数百KBの制限は珍しくありません。さまざまなOSの制限の合理的に包括的なリストについては、 http://www.in-ulm.de/~mascheck/various/argmax/ を参照してください。

17
duskwuff

私はこれを試しました:

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

次に、大きなzipファイルを使用しました

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

次に、ファイルをパラメーターとしてテストプログラムに読み込みます。

⚡⚡⚡  ./test $(more bigfile)

結果:

5 minutes nothing happend, then everything froze

次に、小さいファイルを試しました。

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

そして:

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

標準で示されているように、argv [argc]は有効な値である必要があります。

したがって、ランタイム環境がそれを保証できない状況にある場合、プログラムを開始しないでください。

2
Yves Daoust