Является ли segfault всегда ошибкой программиста?

Является ли segfault (индекс массива за пределами границ) всегда ошибкой программиста или может быть неправильное использование от пользователя?

6 голосов | спросил Niklas Rosencrantz 28 J0000006Europe/Moscow 2017, 09:52:57

10 ответов


24

Если часть спецификации не указана «В таком-то обстоятельстве, вызовите неопределенное поведение» (C /C ++) или «trigger a IndexOutOfBoundsException ", это всегда ошибка программиста.

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

ответил Kilian Foth 28 J0000006Europe/Moscow 2017, 10:03:16
17

Нет, иногда аппаратное обеспечение попадает в космический луч.

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

Этот документ НАСА имеет более подробную информацию о программных методах для смягчения этого явления, и вы всегда можете посмотреть в wikipedia для электроники, упрощающей радиацию . В этой статье обсуждается влияние исправления ошибок при моделировании на графическом процессоре - я не могу вспомнить, что основной причиной ошибок в ранних графических процессорах является радиация или другие мягкие ошибки .

ответил Pete Kirkham 28 J0000006Europe/Moscow 2017, 11:32:34
6

Как утверждают другие, это ошибка программиста, но поскольку вы просили Java и C, я хотел бы объяснить различия:

В C

Ваша программа должна предотвращать такую ​​ситуацию при любых обстоятельствах, везде, где она использует массивы. Убедитесь, что индексные переменные не исчерпывают границы массива. В противном случае это приведет к неопределенному, непредсказуемому поведению и, возможно, проблемам безопасности.

Такое непредсказуемое поведение должно сделать очевидным, почему, очевидно, ответственность программиста не допускать этого.

В Java

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

Если это не так, ваша среда выполнения Java выйдет из программы более или менее изящно, с техническим сообщением об ошибке, которое, скорее всего, не очень полезно с точки зрения пользователя. Там могут быть редкие случаи, когда это приемлемое поведение. Однако для большинства программ, как пользователя, если «массив вне границ» был вызван каким-то неожиданным параметром ввода, я бы ожидал, что программа сообщит мне, что , что входной параметр, вероятно, был неправильным. И это не происходит автоматически. Нужно реализовать это.

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

ответил Doc Brown 28 J0000006Europe/Moscow 2017, 13:59:04
4

Да, это всегда ошибка программиста. Либо он перепутал свои расчеты по длине, либо не правильно дезинформировал ввод пользователя.

ответил Bart van Ingen Schenau 28 J0000006Europe/Moscow 2017, 09:56:56
0

Почти всегда.

Случаи, когда это не ошибка программиста:

  1. , когда он преднамерен (например, как получить segfault)
  2. , когда это аппаратная неисправность.
  3. , когда кто-то искал программу или ее среду (меняя источник питания, обменивая компьютер, меняя данные в памяти, меняя исполняемые файлы (но это оригинальная программа? кто является программистом))

  4. это может быть неправильное использование пользователем, если контракт конкретно говорит о том, что программист не может оплачивать часы для работы с неожиданным вводом и что происходит с неопределенным поведением.

ответил user470365 28 J0000006Europe/Moscow 2017, 18:40:56
0
  

может ли это быть неправильное использование от пользователя?

Да.

Существует множество способов, которыми пользователь может злоупотреблять приложением. Некоторые из которых не могут защищать разумное приложение, например, поставлять неправильные библиотеки, загружать несовместимый плагин.

ответил Peter Green 28 J0000006Europe/Moscow 2017, 20:41:36
0
  

Является ли segfault ... всегда ошибкой программиста ...?

Нет.

  

Является ли segfault ... иногда ошибкой программиста ...?

Да.
Все могут ошибаться.

  

Является segfault ... иногда ошибкой пользователя em ...?

Не напрямую.

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

Моя мантра:

Bad Code breaks.  Period.  
Good Code gets broken by Bad Data. 

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

Если код в основном правильный, но разработчик, скажем, пропустил край, тогда код будет все еще ломаться, но просто знание где not достаточно, чтобы исправить это. Вам также необходимо знать входные данные, которые вызвали поломку, которую StackTraces редко, если она когда-либо предоставлялась.

ответил Phill W. 29 J0000006Europe/Moscow 2017, 14:39:50
0

Вообще говоря, если пользователь может сбой программы, просто введя плохие данные в приглашении (или в диалоговом окне), тогда программист будет определенно по ошибке. Люди делают ошибки (иногда сознательно), и программист, который не учитывает это при реализации своего кода, небрежен. Это особенно true в C, поскольку он не будет генерировать исключение IndexOutOfBounds для индексации за конец массива или что-то в этом роде.

Некоторые ошибки - это неудачи воображения (no way , каждый может ввести более 128 символов для одного входа), некоторые просто не рассматривают случаи ребер (числовое переполнение, деление на ноль и т. д.). ). Некоторые из них являются результатом взаимодействия между различными частями кода, которые хорошо работают изолированно, но каким-то образом накладывают друг на друга данные. Мы часто страдаем от туннельного зрения при разработке нашего кода (особенно когда он спешил), поэтому мы недостаточно эффективно его используем с плохими исходными данными.

К сожалению, проверка правильности входа и дезинфекция в C - это боль в заднице . Bulletproofing scanf часто является бесполезным упражнением, поэтому многие из нас читают все в виде текста с помощью fgets, а затем проанализировать и преобразовать по мере необходимости, что приводит к созданию баллона в размере ( этот ответ показывает, насколько он может быть смешным).

Теперь, если пользователь делает что-то, что не просто вводит ввод в подсказке (скажем, запуская его под gdb и возиться с вещами под капотом), то это не что-то программист может обязательно защититься.

ответил John Bode 29 J0000006Europe/Moscow 2017, 18:05:38
0

Это, очевидно, зависит от приложения.

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

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

ответил juhist 29 J0000006Europe/Moscow 2017, 22:26:21
0

Для C я бы сказал «нет». Это может быть ошибка пользователя /клиента. Например, не все функции, которые принимают указатель, должны обязательно поддерживать работоспособность кода и вычислительную эффективность, проверяя, является ли указатель null, если функция задокументированы таким образом, что очевидно, что вы не должны передавать ему нулевые или висячие указатели. Это может даже затмевать ошибки в других местах.

Если вы считаете это ошибкой людей, реализующих функции, то основная часть стандартной библиотеки C ломается и работает неправильно и нуждается в эпической перезаписи, поскольку вы можете выполнить многие функции в стандартной библиотеке C, просто пройдя их недействительные входы (например: qsort за конец буфера). Или вы можете просто сказать, что любой, кто передает недействительные указатели на такие функции, как qsort, использует его неправильно, и это гораздо более практичный вид.

Вы даже не можете эффективно проверить последний случай (оборванный указатель) в любом случае в функции. Функции C могут быть бесконечно неправильно использованы теми, кто использует /вызывает их, если они передают входы, недействительные для функции, поэтому есть много случаев, когда неправильное использование интерфейса C может быть результатом «ошибки пользователя» способами, которые приводят к segfaults и другие сбои.

Если вы хотите писать функции, которые обнаруживают ошибки программиста и ошибки тех, кто использует интерфейс, C обычно является неправильным языком для задания. На самом деле большая часть обращения ко мне о C заключается в том, что она имеет тенденцию к segfault и потрясающе проявляется при неправильном использовании. Я предпочитаю, чтобы трудно обнаружить ошибки, которые могут легко летать под радаром тестирования.

Теперь я предполагаю «пользователь», вы имеете в виду кого-то, вызывающего функцию. Не «конечный пользователь» приложения, а «пользователь» функции или библиотеки. Если вы говорите о конечных пользователях, тогда программа никогда не должна терпеть крах в результате неправильного использования, если только они, скажем, разработчики плагинов не пишут плагины C для вашего API. Программное обеспечение для производства не должно представлять, скажем, поля ввода пользователю в графическом интерфейсе, где они могут вводить слишком большие значения и segfault для программного обеспечения. Программное обеспечение не должно допускать такого злоупотребления.

ответил 10 SunEurope/Moscow2017-12-10T17:14:59+03:00Europe/Moscow12bEurope/MoscowSun, 10 Dec 2017 17:14:59 +0300 2017, 17:14:59

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132