2017-01-13 2 views
3

В Java будет стек, который говорит StackOverflowError, и вся система не будет разбиваться, только программа.Что обычно происходит в C из-за переполнения стека?

В C Я знаю, что индекс массива за пределами границ вызовет ошибку сегментации. Это то же самое для переполнения стека в C, и также будет ошибка сегментации, например, такой же тип ошибки для аналогичной проблемы?

Я не тестирую сознательное бесконечное спасение на C, чтобы видеть, что происходит, потому что я не знаю последствий.

Или иногда что-то гораздо хуже, и переполнение стека в C может привести к сбою операционной системы и принудительному возврату энергии в цикл? Или, что еще хуже, привести к необратимому повреждению аппаратного обеспечения? Как плохие эффекты могут иметь ошибку переполнения стека?

Кажется очевидным, что защита лучше на Java, чем на C. Насколько она лучше в C, чем в коде сборки/машины, или это практически такая же (отсутствие) защита в C как сборка?

+1

Что заставляет вас думать, что защиты нет? Вы когда-нибудь испытывали ошибку сегментации? Что вы видели? – Kayaman

+3

Нет, ничего плохого не должно произойти с ОС. Современные процессоры и ОС не позволяют программе случайно повлиять на ОС или другие программы. – alain

+1

В типичной современной операционной системе (Linux, Windows, другие Unix и т. Д.) Программа C (или любая другая программа на любом языке) обычно не может привести к сбою операционной системы. Процесс fautling просто сбой, и все. –

ответ

6

В C Я знаю, что индекс массива за пределами границ вызовет ошибку сегментации. Это то же самое для переполнения стека в C, и также будет ошибка сегментации, например, такой же тип ошибки для аналогичной проблемы?

Там нет никакой гарантии в том, что C будет ошибки сегментации. Стандарт C говорит, что это undefined behaviour и оставьте это на этом. Как это может проявиться, вообще-то, зависит от реализации/платформы.

Или это иногда что-то намного хуже, а переполнение стека в C может привести к сбою операционной системы и заставить вас снова задействовать цикл питания, чтобы вернуться? Или, что еще хуже, привести к необратимому повреждению аппаратного обеспечения? Как плохие эффекты могут иметь ошибку переполнения стека?

В современных операционных системах довольно редко случается, что с системой произойдет что-либо неблагоприятное; как правило, только сбой программы. В современных операционных системах используется various memory protection techniques.

Кажется очевидным, что защита лучше на Java, чем на C. Является ли она лучше в C, чем в коде сборки/машины, или это практически такая же (отсутствие) защита в C как сборка?

Это потому, что в Java память «управляется». В C он оставлен программисту; это по дизайну. Компилятор C в конечном итоге генерирует машинный код; так что это не может быть лучше или хуже. Очевидно, что хороший компилятор мог обнаружить некоторые из этих проблем и предупредить вас, что является преимуществом на C по сравнению с сборкой.

3

Это не проблема C, по крайней мере, то, что происходит, не указано C. C будет говорить только о том, что это неопределенное поведение. Таким образом, эффект - это вопрос времени выполнения. На любой разумной ОС это приведет к некоторой ошибке, которая будет улавливаться, а в * nixes создаст ошибку сегментации для вашего процесса. Даже экзотические небольшие ОС защитят себя от вашего неисправного процесса. Как бы то ни было, это никогда не разрушит ОС. Java не лучше чем C, они разные языки и имеют разное время выполнения. Java по своей конструкции более безопасна в том смысле, что она защитит вас от многих проблем (среди прочих). C дает вам более тонкий контроль над машиной, и да, это более или менее своего рода язык ассемблера.

3

Каждый исполняемый поток имеет свой стек, выделенный во время создания потока во время выполнения. Если во время выполнения программы обнаруживается переполнение стека (скомпилирована собственная программа), будет затронута только ваша программа (процесс), а не ОС.

+0

есть большой IF в начале вашего второго предложения –

+0

@KamiKaze - o/Управление памятью обеспечивает обнаружение переполнения. Обычно программа пытается получить доступ к немаркированному адресу, а код сопоставления отказывается расширять стек. –

+1

Я полностью согласен. Я положил «If», потому что это ответственность управления памятью o/s для обнаружения и управления такой проблемой. Некоторые handmade o/s, по определенным причинам, могут не применять такой контроль. –

4

Ну, обработка отказа памяти, как и отказ системного ресурса, в основном обрабатывается ОС, а не самим языком.

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

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

По умолчанию, по какой-либо причине, чрезмерное использование стека или повреждение, выполнение пытается получить доступ к памяти за пределами выделенного пространства стека, ОС запускает структурированное исключение. Java, как и во время выполнения C, обычно обрабатывают это исключение и также предоставляют некоторый способ передать их в код пользователя для возможного восстановления (то есть через сигнал или SEH). Если обработчик не был связан с пользовательским кодом, элемент управления передается во время выполнения, которое по умолчанию будет управлять отключением контролируемой задачи (прекрасное завершение работы).

Если никакая обработка не доступна, даже от времени выполнения, ОС закроет задачу и будет оперативно восстанавливать ресурсы (т. Е. Обрезать файлы, закрыть порты и т. Д.).

В любом случае операционная система Виль защитить систему, если ОС, если дефект один ...

В C это нормально зарегистрировать обработчик, который защитить фрагмент кода, который может потерпеть неудачу. Способ обработки исключения зависит от вашей ОС (то есть под окнами вы можете обернуть код, который может завершиться с ошибкой в ​​обработчике исключений __try __except).

+3

Ваш комментарий «нормально» может быть правильным для Windows; это неверно для Unix, не в последнюю очередь потому, что используемая функция расширения языка обычно недоступна в Unix. –

+0

@JonathanLeffleryes ты прав, лучше, чем я указываю. –

Смежные вопросы