2015-12-28 16 views
7

私は65KBにデータサイズを制限し、それを確認する簡単なプログラムを書いています。私は65KB以上のダミーメモリを割り当てています。失敗するはずですね。setrlimitによって制限されていないプロセスリソース

The soft limit is 4294967295 
The hard limit is 4294967295 
The soft limit is 66560 
The hard limit is 66560 
core file size   (blocks, -c) 0 
data seg size   (kbytes, -d) 65 
scheduling priority    (-e) 0 
file size    (blocks, -f) unlimited 
pending signals     (-i) 14895 
max locked memory  (kbytes, -l) 64 
max memory size   (kbytes, -m) unlimited 
open files      (-n) 1024 
pipe size   (512 bytes, -p) 8 
POSIX message queues  (bytes, -q) 819200 
real-time priority    (-r) 0 
stack size    (kbytes, -s) 8192 
cpu time    (seconds, -t) unlimited 
max user processes    (-u) 14895 
virtual memory   (kbytes, -v) unlimited 
file locks      (-x) unlimited 
success 

は、私がどのような方法で間違ってやっている -

#include <sys/resource.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <errno.h> 

int main (int argc, char *argv[]) 
{ 
    struct rlimit limit; 


    /* Get max data size . */ 
    if (getrlimit(RLIMIT_DATA, &limit) != 0) { 
    printf("getrlimit() failed with errno=%d\n", errno); 
    return 1; 
    } 

    printf("The soft limit is %lu\n", limit.rlim_cur); 
    printf("The hard limit is %lu\n", limit.rlim_max); 

    limit.rlim_cur = 65 * 1024; 
    limit.rlim_max = 65 * 1024; 

    if (setrlimit(RLIMIT_DATA, &limit) != 0) { 
    printf("setrlimit() failed with errno=%d\n", errno); 
    return 1; 
    } 

    if (getrlimit(RLIMIT_DATA, &limit) != 0) { 
    printf("getrlimit() failed with errno=%d\n", errno); 
    return 1; 
    } 

    printf("The soft limit is %lu\n", limit.rlim_cur); 
    printf("The hard limit is %lu\n", limit.rlim_max); 
    system("bash -c 'ulimit -a'"); 
    int *new2 = NULL; 
    new2 = malloc(66666666); 
    if (new2 == NULL) 
    { 
     printf("malloc failed\n"); 
     return; 
    } 
    else 
    { 
     printf("success\n"); 
    } 

    return 0; 
} 

驚くべきことに、出力に含まはこのようなものでしょうか? 入力を削除してください。 ありがとう!

+1

「mallocが失敗しました」メッセージの後のベアリターンは、1(またはゼロ以外の値)を返すように固定する必要があります。 –

+1

私はubntu linux 14を実行しています。04 amd64で8ギガのRAMを使用し、gccを使ってコンパイルするには-Wall -Wextra -pedantic -std-c99というパラメータを使用します。これにより、コンパイラは次の3つの警告を出力します。 1)行41:9:警告:戻り値なしの戻り値、戻り値なしvoid 2)未使用パラメーターargc 3)未使用パラメーターargv。実行時の問題について質問するときは、常にきれいにコンパイルするコードを投稿してください。 – user3629249

答えて

3

プロセスのデータセグメントの最大サイズ

RLIMIT_DATA( データ、未初期化データ、およびヒープを初期化します)。この制限は のbrk(2)とsbrk(2)へのコールに影響し、 のエラーENOMEMでこのリソースのソフト制限に遭遇すると失敗します。

具体的には、リソースはmmapで取得したメモリには適用されません。内部的には、mallocは、新しいメモリを取得するためのさまざまなメカニズムを使用します。この場合、それはまたはbrkではなくmmapであることがわかります。これはプログラムからのシステムコールをダンプすることで確認できます。strace

代わりにRLIMIT_ASリソースを使用してください。

+0

明らかに、これに対処するためのLinuxカーネルパッチがありますが、明らかにまだカーネルには入っていません(少なくとも、OPが実行中でなく、実行中でもありません)。 [RLIMIT_DATA patch](http://lkml.iu.edu/hypermail/linux/kernel/0707.1/0675.html) –

+0

@kaylum正確に何が必要なのですか?はい、この場合、メモリは 'mmap'によって割り当てられます。私はこれをmalloc_stats()lib呼び出しで確認しました。使用バイト= 66670592の 最大のmmap領域= 1 に システムバイト= 66670592 :使用バイト= 0 合計(税込MMAP。)で システムバイト= 0 : アリーナ0 - 同じの出力は次のようなものでしたmax mmap bytes = 66670592 mmapについて知りたいのですが、同じ入力やリンクについて知りたいですか? :) – Coder

+0

@Coderあなたが 'mmap'について知りたいことに依存します。しかし、確かに[mmapのマニュアルページ](http://linux.die.net/man/2/mmap)はまだ読んでいなければ開始する場所です。 – kaylum

1

コードのコンパイルに関する問題を修正した後。

この

コードです:

#include <sys/resource.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <errno.h> 

int main (void) 
{ 
    struct rlimit limit; 


    /* Get max data size . */ 
    if (getrlimit(RLIMIT_DATA, &limit) != 0) { 
    printf("getrlimit() failed with errno=%d\n", errno); 
    exit(EXIT_FAILURE); 
    } 

    printf("The soft limit is %lu\n", limit.rlim_cur); 
    printf("The hard limit is %lu\n", limit.rlim_max); 

    limit.rlim_cur = 65 * 1024; 
    limit.rlim_max = 65 * 1024; 

    if (setrlimit(RLIMIT_DATA, &limit) != 0) 
    { 
    printf("setrlimit() failed with errno=%d\n", errno); 
    exit(EXIT_FAILURE); 
    } 

    if (getrlimit(RLIMIT_DATA, &limit) != 0) 
    { 
    printf("getrlimit() failed with errno=%d\n", errno); 
    exit(EXIT_FAILURE); 
    } 

    printf("The soft limit is %lu\n", limit.rlim_cur); 
    printf("The hard limit is %lu\n", limit.rlim_max); 
    system("bash -c 'ulimit -a'"); 

    int *new2 = NULL; 
    new2 = malloc(66666666); 

    if (new2 == NULL) 
    { 
     printf("malloc failed\n"); 
     exit(EXIT_FAILURE); 
    } 
    else 
    { 
     printf("success\n"); 
    } 

    return 0; 
} 

、ここで出力されます:RLIMIT作品への変更を示し

The soft limit is 18446744073709551615 
The hard limit is 18446744073709551615 
The soft limit is 66560 
The hard limit is 66560 
bash: xmalloc: .././variables.c:2307: cannot allocate 48 bytes (16384 bytes allocated) 
success 

system呼び出しが成功した、bashコマンドが失敗し、 mallocは成功しました。したがって、正確に同じ値次いで、未だにbashコマンドを実行して、開いた各端末のウィンドウを残したまま、上記のコードを数回実行した後RLIMIT値

に永続的変化常に出力同じコードの

複数の実行別の端末ウィンドウは、次を生じ:

core file size   (blocks, -c) 0 
data seg size   (kbytes, -d) unlimited 
scheduling priority    (-e) 0 
file size    (blocks, -f) unlimited 
pending signals     (-i) 54511 
max locked memory  (kbytes, -l) 64 
max memory size   (kbytes, -m) unlimited 
open files      (-n) 1024 
pipe size   (512 bytes, -p) 8 
POSIX message queues  (bytes, -q) 819200 
real-time priority    (-r) 0 
stack size    (kbytes, -s) 8192 
cpu time    (seconds, -t) unlimited 
max user processes    (-u) 54511 
virtual memory   (kbytes, -v) unlimited 
file locks      (-x) unlimited 

次いで同じ端末出力全く同じ出力値にbashコマンドを実行するさらに別の端末でコードを実行しています。

したがって、私はコードが利用可能なメモリの量を制限するために間違ったアプローチを取っていると思われます。 setrlimit man pageから

+1

これは、RLIMIT_DATAの設定がデータセグメントサイズの制限に失敗する理由です。動作していれば、mallocは失敗するでしょう。これはOPが期待していたものです。 –

+0

それは、1)変化が永続的ではなく一時的であること2)間違ったアプローチがとられていることを指摘している。 3) '仮想メモリ'と 'メモリページング'のために、実際に利用可能なRAMをプログラムに減らすと、利用可能なメモリが小さいほどページ違反イベントが多くなるため、プログラムの実行速度が低下します。そうでなければほとんど関心がありません。 4) 'malloc'は、実際に使用されているとき、実際にアクセスされている間だけページが割り当てられるまで、割り当てられたメモリを実際にRAMに割り当てる必要はありません。 – user3629249

+0

RLIMIT_DATAは望ましい効果がない現在のLinuxカーネルでは、OPはRLIMIT_ASを代わりに使用する必要があります。 keylumの答えと説明を参照してください。 –

関連する問題