Почему программа не будет аварийно завершена и все еще может выполнить After Access Violation? [Дубликат]

Просто добавьте эту функцию bash в ваш bash файла .zshrc.

# Squash last X commits with a Commit message.
# Usage: squash X 'COMMIT_MSG'
# where X= Number of last commits.
# where COMMIT_MSG= New commit msg.
function squash() {
    if [ -z "${1}" -o -z "${2}" ]; then
        echo "Usage: \`squash X COMMIT_MSG\`"
        echo "X= Number of last commits."
        echo "COMMIT_MSG= New commit msg."
        return 1
    fi

    git reset --soft HEAD~"$1"
    git add . && git ci -m "$2" # With 100 emoji
    git push --force
}

Затем просто запустите

squash X 'New Commit Message'

И все готово.

3
задан StackedCrooked 22 February 2012 в 14:19
поделиться

9 ответов

Поскольку большинство программ работают в пользовательском режиме, а ОС работает в режиме ядра. Режим ядра близок к физическому оборудованию (они говорят близко к металлу ). Программы режима ядра (ОС, некоторые службы, драйверы и т. Д.) Работают в кольце 0 процессора. Программы пользовательского режима работают на более высоком кольце. Программы пользовательского режима, работающие на кольце N процессора, не могут получить доступ к программам или памяти, работающим на чем-либо меньшем N. Если они попытаются, они не будут разрешены!

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

Если процесс, который он не отлаживает (зависит от Windows) и какой-то отладчик, OS может позволить пользователю отлаживать его.

Если программа режима ядра делает что-то неприятное, это приведет к отключению ОС. Я не парень Linux, поэтому не знаю поведения Linux. Но, в случае Windows, BSOD украсит ваш монитор синим цветом!

1
ответ дан Ajay 26 August 2018 в 22:02
поделиться

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

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

И прежде чем вы скажете, что «неопределенное поведение не определено, пусть пользователь плохого кода разрушает то, что он хочет ", представьте себе, что проблемы безопасности одного случайного переполнения буфера могут segfault для всего сервера.

2
ответ дан Chris Lutz 26 August 2018 в 22:02
поделиться

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

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

Если сам ядро ​​ОС разыскивает нулевой указатель, он обычно останавливается при попытке сделать это. Вы получите синий экран, ядро ​​или т. П. Если это продолжается, это может привести к «неопределенному поведению».

Обратите внимание, что термин «неопределенное поведение» точно определен только на языках C или аналогичных языках, на самом деле, происходит, если вы пытаетесь получить доступ к области памяти, для которой у вас недостаточно прав, очень хорошо определены в контексте архитектуры.

1
ответ дан Gunther Piez 26 August 2018 в 22:02
поделиться

Доступ к памяти защищен во всех основных ОС. Вы не можете просто написать программу, которая управляет памятью, которая не была выделена для него (при условии, что указатель не инициализирован, например, это может быть ЛЮБОЙ адрес). Таким образом, каждый раз, когда программа пытается получить доступ к некоторому адресному пространству, которое ей не принадлежит, ОС отправит сигнал для завершения программы (в результате получится известная «ошибка сегментации», знакомая любому программисту на C / C ++).

3
ответ дан jlemos 26 August 2018 в 22:02
поделиться

Нет правил логической транзитивности, когда дело касается UB. Ваше предположение неверно.

UB означает, что что-то может случиться, поэтому на плохо написанной ОС ваша программа может фактически свернуть ОС. Не исключайте этого.

Кроме того, ваша программа не сбой, потому что вы разыскиваете указатель NULL. Он вылетает из-за сбоя операционной системы.

1
ответ дан Luchian Grigore 26 August 2018 в 22:02
поделиться

Стандарт C ++ не определяет поведение, чтобы гарантировать сбой или сделать что-либо еще. Это не мешает ОС определять поведение - это не C ++-программа, поэтому она не должна соблюдать «правила» [1] программ на C ++. Тем не менее, ОС не будет разыменовывать сам указатель.

На большинстве современных платформ доступ к объекту разыменованного указателя заставит аппаратное обеспечение управления памятью вызвать исключение (часто называемое «ошибкой сегментации» "или" ошибка защиты "). Это поймано ядром, которое может определить, какой процесс это сделал, и либо убить процесс, либо отправить ему сигнал.

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

[1] Под этим я подразумеваю неформальные «правила», что программа должна быть хорошо сформирована и избегать неопределенного поведения - не путать с формальные «правила» для реализаций C ++, заданные стандартом языка.

11
ответ дан Mike Seymour 26 August 2018 в 22:02
поделиться

Потому что, если моя программа разыгрывает нулевой указатель, а моя программа управляется ОС, то, согласно правилам логической транзитивности, это означает, что ОС пыталась разыменовать нулевой указатель. Почему ОС не входит в состояние «неопределенного поведения»?

Это неправильно. Есть что-то, что называется защитой памяти, и это ПОЧЕМУ ваша программа прекращена. Является ли ОС, которая сама защищает себя (в терминах использования памяти).

0
ответ дан Sebastian 26 August 2018 в 22:02
поделиться

Прежде всего, UB означает «все может случиться». На практике, однако, современные ОС предлагают защиту памяти - когда программа пытается разыменовать нулевой указатель, который пытается инициировать прерывание внутри ЦП, которое поймано и обрабатывается ОС и Затем ОС останавливает программу, а затем продолжает работать, как будто ничего плохого не произошло.

2
ответ дан sharptooth 26 August 2018 в 22:02
поделиться

Извините, какие правила «логической транзитивности»? Одна из вещей, которую предназначена операционная система, - это защитить программы от неправильного поведения других программ. В частности, O / S не должен вылетать из строя только потому, что ваша программа пытается сделать что-то глупо.

В операционных системах без защиты памяти доступ через нулевой (или любой недействительный) указатель действительно может привести к тому, что O / S, чтобы сбой (если O / S случайно использовал местоположение 0 для чего-то интересного).

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

0
ответ дан Tom Tanner 26 August 2018 в 22:02
поделиться
Другие вопросы по тегам:

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