保護されたメモリの前にどのようにセグメンテーションフォールトをデバッグしましたか?


20

さて、Cのポインターでプログラミングの間違いを犯すと、いいセグメンテーションフォールトが発生し、プログラムがクラッシュし、デバッガーはどこが間違っているのかを教えてくれます。

メモリ保護が利用できなかったとき、彼らはどうやってそれをしましたか?DOSプログラマーが、ミスをしたときにOS全体をいじり、クラッシュさせるのを見ることができます。仮想化は利用できなかったため、再起動して再試行するだけでした。それは本当にそのように行きましたか?


4
うん、そういう風になった。ランダムなコンピューターの再起動が発生し、頻繁に発生しました。メモリ保護は素晴らしいことです:)
ロックラン

7
保護されたメモリがない場合、セグメンテーションフォールトなどはありません。もちろん、メモリを保護していても、自分のスペースを壊すことはできます。OSはそれを気にしません。
Blrfl

3
現在でも、多くのポインターのミスは、素晴らしいセグメンテーション違反を引き起こしません。
CodesInChaos

1
DOSの時点では、保護されたメモリは他のOSにすでに存在していました。
mouviciel

回答:


36

DOSプログラマーが、ミスをしたときにOS全体をいじり、クラッシュさせるのを見ることができます。

ええ、それはほとんど起こったことです。メモリマップを備えたほとんどのシステムでは、位置0が無効とマークされていたため、最も一般的なケースであるため、nullポインターを簡単に検出できました。しかし、他にも多くのケースがあり、それらは大混乱を引き起こしました。

ギーザーのように聞こえる危険性がありますが、デバッグの現在の焦点は過去のものではないことを指摘する必要があります。以前は、誤ったプログラムからバグを削除するのではなく、正しいプログラムを作成するためにさらに多くの努力が払われていました。それのいくつかはそれが私たちの目標だったからでしたが、多くはツールが物事を難しくしたからです。IDEでなく、対話型デバッガーの利点を使用せずに、紙またはパンチカードでプログラムを作成してみてください。それはあなたに正しさの味を与えます。


3
実際、「古いギーザー」が私の質問に答えることを望んでいました。直接体験に勝るものはありません。ありがとう。
バートフリーデリ

6
もちろん、同僚がデバッグセッションのためにそれを予約していなかったと仮定して、ハードウェアが02:00から06:00まで毎晩デバッグに利用できるときにコードを書いてみてください。
–MSalters

@MSalters確かに!私の最初の仕事では、我々はまた、0700から1900に日曜日にスロットを予約することができ-実質の御馳走を、レムはあなたを教え:-)
ロス・パターソン

2
大学から家に帰る紙に最初のプログラム書いたことを覚えています。翌日、私はそれを打ち込んで実行することができましたが、完璧でした;-)
Jan Doggen

1
@JanDoggen、私も同じ。あなたが1つしか試していないとき、あなたはそれを本当に数えます。
おおざっぱに

23

当時、私たちにはメモリ保護機能がなく、そのすべてがおしゃれなビジネスでした!printfを使用して、プログラムのどこにいるかを判断しました

真面目な話ですが、それは通常、私たちがもっと注意深くなったことを意味します。mallocが呼び出される場所では、プログラム内のどこかに空きが必要でした。また、問題の場合、明確に指摘したように、セグメンテーションフォールトは有用なエラーではないため、このようなチェックは厳密でした。

そのようなエラーの場合、最善の方法はそのようなセグメンテーション違反がいつ発生するかを理解(printfを使用)、コードを見て、その時点でメモリへのアクセスが無効であった理由を特定し、そこから逆方向に作業することです。

本質的には、デバッガーを使用してエラーがいつ発生するかを判断することを除いて、同じことが今日起こりますが、エラーが発生した理由を理解する必要があり、エラーが発生した行を見つけることは必ずしも簡単ではありません。エラーは連鎖反応のようなエラーを引き起こします。また、当時Cプログラマーだった場合、コーディングの時間の20%を費やし、残りの時間はバグの修正に費やしていました。


2
Mallocを解放してください!
クリス

1
たまに、今日でも、コールスタックと変数の状態でさえ、一体何が間違っていたのか、どのようにそれを修正するのかを判断するのにまったく役に立ちません。特に、多数の可能な状態を持つ複雑なソフトウェアがあり、その一部は相互依存的で、一部は相互に排他的である場合に当てはまります。どこでも単一の迷走書き込みと保証された前提条件の省略されたアサーションは、あなたをそこに連れてくることができます。
CVn

1
@MichaelKjörling、私は、プログラムのエラーの発見に関する懸念については、エラートリガーの発見に関する懸念についてのみ進めてきましたが、これらのエラーの原因を明らかにするためのマイルはまだ残っていると思います。確かに、アサーションは正気を保つのに役立ちます。:)
ニール

6

まあ..

セグメンテーション違反は、何かが間違っていることを示す素晴らしい指標ですが、それでも根本的な原因を見つける必要があります。したがって、今日の質問よりも根本的な原因をどのように見つけることができるのかという質問をした場合、その答えは当時とそれほど変わりません。もちろん、言語とツールは使いやすくなりましたが、一般的なタクティックは同じです:

  • ロギングは、問題のある領域を見つけるのに役立ちます。バイナリ検索printfはその形式です。
  • デバッグ、ステップバイステップ、ブレークポイントおよびウォッチ
  • より良い理解を得るためのリファクタリング
  • コードをじっと見つめる
  • メモリ/コアダンプを見てください
  • 異なるデータでそれを供給
  • 他の人に見せて
  • ポインターのない言語(および新しい問題のセット)への切り替え...

より抽象的なレベルでは、次の3つのアプローチがあります。1.コードを操作する2.実行中にプログラムを確認する

ところで、ポインターエラーはセグメンテーション違反を作成する必要はありません。

Amigaプログラマーとして、私はほとんどすべてを使いました。そして、はいは一般的な慣習で再起動します。


4

Fortranバッチジョブを実行しているIBM 360では、以前は16進数のコアダンプを取得していました。このようなダンプは、厚さ1インチのファンフォールドの緑と白のプリンター用紙です。それはレジスタが何であるかを伝え、そこからバックトラックしてプログラムが何をしていたかを把握することができました。各サブルーチンを見つけて、リターンアドレスが格納されている場所を特定できるため、コンテキストを確認できます。プログラムのリストをアセンブラーにしておくと役立ちます。


2

かつては有名なWindows 3.1プレゼンテーションソフトウェアのバグ修正に取り組んでいました。

バグが発生すると、ブルースクリーンオブデスが発生しました。

このバグは、特定のループが1000回以上実行された場合にのみ発生しました。デバッガーの高度な機能を使用して、ブレークポイントを1000回通過させてから、プログラムを慎重にステップスルーしました。Windows Blue Screenedのバグを含む関数呼び出しをやりすぎたりスキップしたりするたびに。

最後に、数日間の作業の後、メモリが不足している機能に絞り込み、エラーメッセージを表示する代わりに、エラーメッセージをバッファに追加しました。後続のすべての繰り返しで、重要なものが上書きされ、Windowsが破棄されるまで、より多くのメモリが破棄されました。

デバッグのスキルと忍耐力が解決策でした。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.