1

いくつかのセグメンテーション違反の例を試していますが、エラーの原因となっているものはありません。

ソースコード: http://www.unknownroad.com/rtfm/gdbtut/gdbsegfault.html

例は次のとおりです。

1 : #include <stdio.h>
2 : #include <stdlib.h>

3 : int main(int argc, char **argv)
4 : {
5 :   char *buf;
6 :
7 :   buf = malloc(1<<31);
8 :
9 :   fgets(buf, 1024, stdin);
10:   printf("%s\n", buf);
11:
12:   return 1;
13: }

最初のステップは、デバッグ フラグを使用してプログラムをコンパイルすることです。

prompt> gcc -g segfault.c

次に、プログラムを実行します。

prompt > ./a.out
Hello World!
Segmentation fault
prompt > 

ただし、上記の例は、Ubuntu で segfault なしで実行されています。gccのオプションが関係していると思いますが、何が原因なのかわかりませんでした。別のディストリビューションで実行すると、問題が発生します。

これは私のgccの出力です:

$ gcc -v
Using built-in specs.
Target: i486-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.4.3-4ubuntu5.1' 
    --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs 
    --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared 
    --enable-multiarch --enable-linker-build-id --with-system-zlib 
    --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix 
    --with-gxx-include-dir=/usr/include/c++/4.4 --program-suffix=-4.4 --enable-nls 
    --enable-clocale=gnu --enable-libstdcxx-debug --enable-plugin --enable-objc-gc
    --enable-targets=all --disable-werror --with-arch-32=i486 --with-tune=generic
    --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu
    --target=i486-linux-gnu
Thread model: posix
gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5.1) 

私のgccは変数も自動的に初期化しています。無効にしたい。

誰かが同様の問題に直面したか、解決策について何か考えがありましたか?

4

1 に答える 1

2

サンプル コードは segfaults のみで、malloc(1<<31)失敗した場合は NULL を返します。ただし、malloc(1<<31)システムが失敗せずに 2 ギガのメモリを割り当てることができる場合は成功します。その segfault のサンプル コード スニペットは、システムが通常その量のメモリを割り当てることができなかった時代のものです。それが成功するかどうかは、物理メモリの量、他のプロセスによって使用されるメモリの量、カーネルのメモリ オーバーコミット戦略、およびおそらく使用される (libc と) カーネルのバージョンに依存します。したがって、表示される動作の違いは、オーバーコミット sysctl の設定の違い、実行中のプロセスのセットの違い、または明らかに物理メモリの量の違いの結果である可能性があります。

から/usr/src/linux/Documentation/vm/overcommit-accounting:

The Linux kernel supports the following overcommit handling modes

0   -   Heuristic overcommit handling. Obvious overcommits of
        address space are refused. Used for a typical system. It
        ensures a seriously wild allocation fails while allowing
        overcommit to reduce swap usage.  root is allowed to 
        allocate slightly more memory in this mode. This is the 
        default.

1   -   Always overcommit. Appropriate for some scientific
        applications.

2   -   Don't overcommit. The total address space commit
        for the system is not permitted to exceed swap + a
        configurable percentage (default is 50) of physical RAM.
        Depending on the percentage you use, in most situations
        this means a process will not be killed while accessing
        pages but will receive errors on memory allocation as
        appropriate.

The overcommit policy is set via the sysctl `vm.overcommit_memory'.

The overcommit percentage is set via `vm.overcommit_ratio'.
于 2012-04-21T18:13:51.133 に答える