Як вони налагоджували помилки сегментації перед захищеною пам'яттю?


20

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

Як вони зробили це в той час, коли захист пам’яті був недоступний? Я бачу, як програміст DOS ухиляється і розбиває всю ОС, коли він помилився. Віртуалізація була недоступна, тому все, що він міг зробити, - це перезапустити та повторити спробу. Невже так було?


4
Так, так і пішло. Випадкове перезавантаження комп'ютера траплялося, і траплялося часто. Захист пам’яті - чудова річ :)
Rocklan

7
Якщо у вас немає захищеної пам'яті, немає такої речі, як помилка сегментації. Звичайно, навіть якщо у вас є захищена пам’ять, ви все одно можете сковувати власний простір; ОС просто не переймається цим.
Blrfl

3
Навіть зараз багато помилок вказівника не викликають приємного сегментації.
CodesInChaos

1
За часів DOS захищена пам'ять вже існувала в інших ОС.
mouviciel

Відповіді:


36

Я бачу, як програміст DOS ухиляється і розбиває всю ОС, коли він помилився.

Так, саме так і сталося. У більшості систем, які мали карти пам'яті, розташування 0 було позначено недійсним, так що нульові вказівники можна було легко виявити, оскільки це був найпоширеніший випадок. Але було багато інших випадків, і вони спричинили хаос.

Загрожуючи звучати як гейзер, я повинен зазначити, що нинішній фокус на налагодженні - це не шлях минулого. Набагато більше зусиль раніше було докладено для написання правильних програм, а не для видалення помилок із неправильних програм. Дещо це було тому, що це було нашою метою, але багато було через те, що інструменти ускладнювали справи. Спробуйте написати свої програми на папері або на перфокартах, а не в IDE і без переваги інтерактивного налагоджувача. Це дає смак правильності.


3
Насправді я сподівався, що "старі джизери" відповідуть на моє запитання. Ніщо не перемагає досвід з перших рук. Спасибі.
Барт Фрідеріхс

6
Спробуйте написати код, коли обладнання доступне для налагодження щовечора з 02:00 до 06:00, припускаючи, звичайно, що ваш колега не зарезервував його для своєї сесії налагодження.
MSalters

@MSalters Дійсно! На моїй першій роботі ми також могли забронювати слоти в неділю з 07:00 до 1900 року - справжнє частування, лемме вам скажу :-)
Росс Паттерсон

2
Я пам’ятаю, як писав свою першу програму на папері, їдучи додому з університету. Наступного дня, коли я міг вдарити його та запустити, він був бездоганним ;-)
Ян Догген

1
@JanDoggen, те ж саме для мене. Коли у вас є лише одна спроба, ви робите цю спробу по-справжньому.
nalply

23

Ще в той час у нас не було захисту пам’яті та всього цього неприємного бізнесу! Ми використовували printf, щоб визначити, де ми знаходимося в програмі, і нам це сподобалось !

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

У випадку таких помилок найкраще, що ви могли зробити, - спробувати зрозуміти, коли виникають такі помилки сегментації (використовуючи printf), і, переглянувши код, визначити, чому доступ до пам’яті в той момент не був дійсним і працює назад звідти.

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


2
Звільніть мальків!
Кріс

1
Час від часу, навіть сьогодні, навіть стек викликів та стан змінної вкрай марні для визначення того, що, до біса, пішло не так і як це виправити. Так відбувається, особливо якщо у вас є складне програмне забезпечення з великою кількістю можливих станів, деякі з яких взаємозалежні, а інші взаємовиключні. Одноразове написання в будь-якому місці і пропущене твердження про гарантовану передумову може привести вас прямо туди.
CVn

1
@ MichaelKjörling, я думаю, що, що стосується виявлення помилок у програмах, ми просунулися лише щодо того, що стосується пошуку тригера помилок, але у нас ще є милі, щоб розкрити причину цих помилок. Твердження, безумовно, допомагають зберегти мене здоровим. :)
Ніл

6

добре ..

segfault - це дійсно приємний показник того, що щось не так, але ви все одно повинні знайти першопричину. Тож якщо ви задаєте питання, як знайти першопричину, то відповідь сьогодні не сильно відрізняється, ніж тоді. Звичайно, з мовами та інструментами стало простіше працювати, але загальний тактик такий же:

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

На більш абстрактному рівні у вас є три підходи: 1. працюйте з кодом 2. дивіться програму, поки вона працює; дивіться результати після того, як вона зробила щось дурне

btw помилка вказівника не повинна створювати segfault.

Як програміст Amiga я майже все це використав. І так, перезапускається там, де поширена практика.


4

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


2

Колись я працював над виправленням помилок у відомому тоді програмному забезпеченні Windows 3.1 Presentation.

У мене була помилка, яка, коли це сталося, спричинила Синій екран смерті.

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

Нарешті, після декількох днів роботи, я звузив його до функції, у якої не вистачало пам'яті, і замість того, щоб відображати повідомлення про помилку, додав повідомлення про помилку до буфера. З кожною наступною ітерацією воно втрачало більше пам’яті, поки щось критичне не було перезаписано і Windows не пошкоджено.

Налагодження навичок та наполегливості було рішенням.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.