Подтвердить что ты не робот

Искусственное ограничение использования C/С++

Есть ли способ легко ограничить приложение C/С++ на определенный объем памяти (30 мб или около того)? Например: если мое приложение пытается загрузить файл 50 МБ в память, оно умрет/распечатает сообщение и закроет/и т.д.

По общему признанию, я могу постоянно проверять использование памяти для приложения, но было бы немного легче, если бы он просто умер с ошибкой, если бы я пошел выше.

Любые идеи?

Платформа не является большой проблемой, windows/linux/любой компилятор.

4b9b3361

Ответ 1

Прочтите страницу руководства для ulimit в системах unix. Существует встроенная оболочка, которую вы можете вызвать перед запуском исполняемого файла или (в разделе 3 руководства) вызов API с тем же именем.

Ответ 2

В Windows вы не можете установить квоту для использования памяти процесса напрямую. Однако вы можете создать объект задания Windows, установить квоту для объекта задания и затем назначить процесс этому объекту задания.

Ответ 3

В bash используйте ulimit builtin:

bash$ ulimit -v 30000
bash$ ./my_program

-v принимает 1K блоков.

Update:

Если вы хотите установить это из своего приложения, используйте setrlimit. Обратите внимание, что man-страница для ulimit(3) явно указывает, что она устарела.

Ответ 4

Переопределите все API-интерфейсы malloc и предоставите обработчики для нового/удаления, чтобы вы могли хранить память и генерировать исключения, когда это необходимо.

Не уверен, что это еще проще и экономит, чем просто контролировать память через API-интерфейсы, предоставленные операционной системой.

Ответ 5

Вы можете ограничить размер виртуальной памяти вашего процесса, используя системные ограничения. Если вы обрабатываете это количество, оно будет убито сигналом (думаю, SIGBUS).

Вы можете использовать что-то вроде:

#include <sys/resource.h>
#include <iostream>

using namespace std;

class RLimit {
public:
    RLimit(int cmd) : mCmd(cmd) {
    }

    void set(rlim_t value) {
        clog << "Setting " << mCmd << " to " << value << endl;
        struct rlimit rlim;
        rlim.rlim_cur = value;
        rlim.rlim_max = value;
        int ret = setrlimit(mCmd, &rlim);
        if (ret) {
            clog << "Error setting rlimit" << endl;
        }
    }

    rlim_t getCurrent() {
        struct rlimit rlim = {0, 0};
        if (getrlimit(mCmd, &rlim)) {
            clog << "Error in getrlimit" << endl;
            return 0;
        }
        return rlim.rlim_cur;
    }
    rlim_t getMax() {
        struct rlimit rlim = {0, 0};
        if (getrlimit(mCmd, &rlim)) {
            clog << "Error in getrlimit" << endl;
            return 0;
        }
        return rlim.rlim_max;
    }

private:
    int mCmd;
};

И затем используйте его так:

RLimit dataLimit(RLIMIT_DATA);
dataLimit.set(128 * 1024 );  // in kB
clog << "soft: " << dataLimit.getCurrent() << " hard: " << dataLimit.getMax() << endl;

Эта реализация кажется немного многословной, но она позволяет вам легко и чисто устанавливать разные пределы (см. ulimit -a).