Pertanyaan Bisakah argc meluap?


Saya berkeliaran di SO dan melihat pertanyaan ini. Lalu saya mulai bertanya-tanya apakah saya bisa meluap argc.

Standar mengatakan itu argv[argc] harus berupa null pointer tetapi ini akan salah jika argc overflow.

(SAYA menulis program C kecil dan skrip python untuk mengujinya tetapi mendapat MemoryError.)

Terima kasih!


Dasar Pemikiran untuk Standar Internasional - Bahasa Pemrograman - C §5.1.2.2.1 Program startup

Spesifikasi argc dan argv sebagai argumen untuk main mengakui praktik sebelumnya yang ekstensif. argv[argc] diperlukan untuk menjadi pointer null untuk memberikan pemeriksaan yang berlebihan untuk akhir daftar, juga atas dasar praktik umum.


75
2018-01-21 19:32


asal


Jawaban:


Menurut standar

Jadi, dari kutipan Anda:

argv[argc] diperlukan untuk menjadi pointer null

Karena itu, argc tidak dapat melimpah, karena pernyataan di atas tidak akan benar.

Dalam praktek

Dalam prakteknya, ukuran total argumen yang dilewatkan ke program terbatas.

Pada sistem Linux / x64 saya:

$ getconf ARG_MAX
2097152

Oleh karena itu, ukuran argumen total adalah sekitar 2 megabyte, dan argc tidak bisa meluap. Saya yakin batas ini mengukur kombinasi dari total data dalam argv dan lingkungan. Jika Anda melebihi batas ini saat Anda mencoba menjalankan perintah, exec() akan gagal E2BIG. Dari man 2 execve:

E2BIG Jumlah total byte dalam lingkungan (envp) dan argumen
       daftar (argv) terlalu besar.

Saya percaya batas ~ 2 megabyte pada sistem saya relatif murah dibandingkan dengan sistem lain. Sistem OS X saya melaporkan batas ~ 260KB.

Tetapi bagaimana jika ARG_MAX sangat besar?

Oke, anggap saja Anda berada di sistem lama / aneh, jadi int adalah 16 bit, dan ARG_MAX lebih dari 215, yang sebaliknya cukup masuk akal. Sekarang, seandainya Anda memohon execve() dengan lebih dari 215 argumen. Implementasinya memiliki dua opsi.

  1. Itu bisa memungkinkan argc meluap ... pada dasarnya, membuang data Anda, memastikan bahwa program yang Anda jalankan mengeksekusi dengan cara yang tidak terduga dan mungkin keliru, dan melanggar standar C. Yang terburuk dari semuanya, kesalahannya diam, jadi Anda mungkin tidak akan pernah tahu.

  2. Atau, itu bisa kembali begitu saja EOVERFLOW dari execve(), memberi tahu Anda bahwa itu tidak dapat menjalankan gambar dengan banyak parameter. Sekarang, standar POSIX / SUS tidak menyebutkan apa pun tentang hasil kesalahan ini ... tapi, saya menduga ini hanya karena penulis standar tidak pernah mengira ARG_MAX menjadi lebih besar dari INT_MAX.

Opsi # 2 adalah hanya pilihan yang masuk akal. Jika sistem Anda entah bagaimana memilih opsi # 1, maka itu rusak dan Anda harus mengajukan laporan bug.

Sebagai alternatif, Anda bisa mencoba menjalankan program lama yang dikompilasi untuk sistem 16-bit, tetapi Anda menjalankannya melalui semacam emulator atau lapisan kompatibilitas. Saya berharap bahwa emulator atau lapisan kompatibilitas akan memberikan pesan kesalahan jika Anda mencoba melewati lebih dari 215parameter ke program.


78
2018-01-21 19:38



Dalam prakteknya, tidak, Anda tidak bisa. Sebagian besar sistem menempatkan batas yang relatif rendah pada total ukuran gabungan argv dan envp. Batas dalam puluhan hingga rendah ratusan KB tidak biasa; Lihat http://www.in-ulm.de/~mascheck/various/argmax/ untuk daftar batasan yang cukup komprehensif di berbagai OS.


17
2018-01-21 19:38



Saya mencoba ini:

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

Kemudian menggunakan zipfile besar

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

Kemudian baca file sebagai parameter ke program uji:

  ./test $(more bigfile)

Hasil:

5 minutes nothing happend, then everything froze

Lalu saya mencoba file yang lebih kecil:

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

Dan:

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

10
2018-01-22 15:07



Sebagaimana ditunjukkan oleh standar, argv [argc] harus merupakan nilai yang valid.

Jadi jika lingkungan run-time dalam situasi seperti itu tidak dapat menjamin itu, seharusnya tidak memulai program.


2
2018-01-28 14:12