Proc аварийно завершает работу, даже если он выделяет меньше памяти, чем ограничено ulimit

Я установил размер стека на 2000 КБ с помощью ulimit -s 2000 и ulimit -Ss 2000 для жесткого ограничения. И в приведенной ниже программе я выделил около 2040000 (510000 x 4) байтов, что меньше, чем я ограничен, т.е. 2048000(2000*4) байт, но я вижу, что моя программа вылетает! Кто-нибудь может подсказать, почему это происходит.

#include <stdio.h>
#include <malloc.h>
int main()
{
    int a[510000] = {0};
    a[510000] = 1;
    printf("%d", a[510000]);
    fflush(stdout);
    sleep(70);
}

РЕДАКТИРОВАТЬ 1: сбой не из-за того, что индекс массива выходит за пределы, поскольку я пробовал более низкий индекс и все еще падает. Это происходит только тогда, когда я ограничиваю ulimit.


person Pavan    schedule 07.07.2015    source источник
comment
зачем тебе #include <malloc.h>?   -  person Sourav Ghosh    schedule 07.07.2015
comment
Эти строки a[510000] = 1; printf("%d", a[510000]);.........Ой!   -  person haccks    schedule 07.07.2015


Ответы (3)


int a[510000] будет массивом с индексом от 0 до 509999. a[510000] находится за пределами диапазона массива.

person LPs    schedule 07.07.2015
comment
Привет, пожалуйста, проверьте РЕДАКТИРОВАТЬ 1 в описании. - person Pavan; 08.07.2015
comment
@Coder Вы пытались изменить размер стека? Думаю до 4000кбайт. - person LPs; 08.07.2015
comment
Да, я обнаружил, что с ограничением в 4000 КБ он не падает, а с 1000 КБ он падает каждый раз, но с 2000 КБ он вылетает случайным образом. Итак, я думаю, что что-то добавляется помимо того, что я выделяю, чтобы доказать это, есть ли способ увидеть текущее использование стека моей программой? - person Pavan; 08.07.2015
comment
Что вы можете сделать, так это инициализировать весь стек с фиксированным значением и посмотреть, не поврежден ли ваш стек чем-то. - person LPs; 08.07.2015
comment
@Coder Я попробовал твой код и вижу то же самое. Но если я запускаю его как su, он всегда работает правильно. - person LPs; 08.07.2015
comment
Ok. Я пытаюсь опубликовать еще один пример переполнения стека, чтобы узнать, есть ли у кого-то идея. Мммм очень странно. - person LPs; 08.07.2015
comment
@Coder Взгляните на ЭТО - person LPs; 08.07.2015
comment
Привет, LP, использование su подавляет ulimit, я думаю, плюс спасибо за ссылку, в которой у меня есть сомнения (надеюсь, я не слишком вас беспокою;)), добавление точки останова непосредственно перед main и проверка регистра стека (?) Как мне это сделать? я имею в виду, как я могу проверить статус реестра? Если это так, могу ли я также увидеть текущее общее использование стека моего приложения? - person Pavan; 08.07.2015
comment
@Coder Если вы запускаете свое приложение с помощью gdb, вы можете распечатать все регистры по регистрам информации о команде. - person LPs; 08.07.2015
comment
я пытаюсь увидеть текущий размер стека, установив точку останова в GDB, я смотрю на разницу значений регистров ebp и esp, это правильный способ? Если нет, пожалуйста, дайте мне знать. - person Pavan; 08.07.2015
comment
Да, это так. Обычно ebp устанавливается в esp в начале функции. - person LPs; 09.07.2015

Проблема здесь в том, что в приведенных ниже утверждениях

  a[510000] = 1;
  printf("%d", a[510000]);

у вас есть индекс off-by-one . Приведенные выше операторы обращаются к массиву за пределами границ. Это, в свою очередь, вызывает неопределенное поведение. Одним из побочных эффектов УБ, кроме назального демона, является ошибка сегментации («Сбой !!»).

Помните, что C использует индексацию массива на основе 0.

person Sourav Ghosh    schedule 07.07.2015
comment
Привет, я знаю об этом. поэтому я попробовал это #include ‹stdio.h› int main() { int a[510000] = {0}; а[51000] = 1; printf(%d, а[51000]); сбросить (стандартный вывод); сон(70); } и он вылетает. Примечание: не происходит сбой, если не ограничивать ulimit! - person Pavan; 08.07.2015

Вы портите стек в

a[510000] = 1;

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

person Alexander Balabin    schedule 07.07.2015
comment
Привет, пожалуйста, проверьте РЕДАКТИРОВАТЬ 1 в описании. - person Pavan; 08.07.2015