Как они отлаживали ошибки сегментации перед защищенной памятью?

20

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

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

Барт Фридрихс
источник
4
Да, вот как все прошло. Произошла случайная перезагрузка компьютера, и случалась часто. Защита памяти - замечательная вещь :)
Rocklan
7
Когда у вас нет защищенной памяти, нет такой вещи, как ошибка сегментации. Конечно, даже если у вас есть защищенная память, вы все равно можете забить свое собственное пространство; ОС просто не заботится об этом.
Blrfl
3
Даже сейчас многие ошибки указателей не вызывают симпатичных ошибок.
CodesInChaos
1
Во времена DOS защищенная память уже существовала в других ОС.
Mouviciel

Ответы:

36

Я вижу, как программист DOS суетится и рушит всю ОС, когда совершает ошибку.

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

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

Росс Паттерсон
источник
3
На самом деле, я надеялся, что «старые чудики» ответят на мой вопрос. Ничто не сравнится с опытом из первых рук. Благодарю.
Барт Фридрихс
6
Попробуйте писать код, когда оборудование доступно для отладки каждую ночь с 02:00 до 06:00, при условии, конечно, что ваш коллега не зарезервировал его для своего сеанса отладки.
MSalters
@MSalters Действительно! На моей первой работе мы могли бы также забронировать слоты в воскресенье с 07:00 до 19:00 - настоящее удовольствие, позвольте вам сказать :-)
Росс Паттерсон,
2
Я помню, как писал свою первую программу на бумаге, возвращаясь домой из университета. На следующий день, когда я смог его запустить и запустить, это было безупречно ;-)
Jan Doggen
1
@JanDoggen, то же самое для меня. Когда у вас есть только одна попытка, вы действительно пытаетесь считать.
Вскоре
23

В свое время у нас не было защиты памяти и всего этого шикарного бизнеса! Мы использовали printf, чтобы определить, где мы были в программе, и нам понравилось !

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

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

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

Нил
источник
2
Освободи Малоки!
Крис
1
Время от времени, даже сегодня, даже стек вызовов и состояние переменных совершенно бесполезны для определения того, что, черт возьми, пошло не так и как это исправить. Это особенно актуально, если у вас сложное программное обеспечение с большим количеством возможных состояний, некоторые из которых взаимозависимы, а некоторые взаимоисключающие. Одна случайная запись в любом месте и пропущенное утверждение для гарантированной предпосылки может привести вас прямо здесь.
CVn
1
@ MichaelKjörling, я думаю, что в том, что касается обнаружения ошибок в программах, мы продвинулись только в том, что касается поиска триггера ошибок, но у нас еще есть много миль, чтобы выявить причину этих ошибок. Утверждения помогают держать меня в здравом уме, конечно. :)
Нил
6

Что ж ..

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

  • регистрация помогает найти область, где ваша проблема. Бинарный поиск printf является его формой.
  • отладка, шаг за шагом, точки останова и часы
  • рефакторинг, чтобы лучше понять
  • пристально глядя на код
  • посмотрите на дамп памяти / ядра
  • кормить его разными данными
  • показывая это другим людям
  • переключиться на язык без указателей (и новый набор проблем) ...

На более абстрактном уровне у вас есть три подхода: 1. работать с кодом 2. смотреть на программу во время ее работы 3. смотреть результаты после того, как она сделала что-то глупое

Между прочим, ошибка указателя не должна создавать segfault.

Как программист Amiga, я использовал почти все это. И да перезапускается там, где обычная практика.

openCage
источник
4

На IBM 360, выполняющем пакетные задания Fortran, мы получали дампы шестнадцатеричного ядра. Такая свалка может быть толщиной с дюймовую зеленовато-белую бумагу для принтера. Это скажет, что такое регистры, и оттуда мы сможем отследить и выяснить, что делает программа. Мы могли бы найти каждую подпрограмму и выяснить, где она хранит свой обратный адрес, чтобы мы могли видеть контекст. Было бы полезно иметь список ассемблера программы.

Майк Данлавей
источник
2

Однажды я работал над исправлением ошибок в тогдашнем известном программном обеспечении для Windows 3.1 Presentation.

У меня была ошибка, которая, когда она произошла, вызвала синий экран смерти.

Ошибка возникала только тогда, когда определенный цикл был выполнен более 1000 раз. Я использовал расширенные возможности отладчика, чтобы 1000 раз проходить точку останова, а затем тщательно прошел программу. Каждый раз я заходил слишком далеко или пропускал вызов функции, в котором содержалась ошибка Windows Blue Screened.

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

Навыки отладки и настойчивость были решением.

Стюарт Вудворд
источник