21

Now, when I make a programming mistake with pointers in C, I get a nice segmentation fault, my program crashes and the debugger can even tell me where it went wrong.

How did they do that in the time when memory protection wasn't available? I can see a DOS programmer fiddling away and crashing the entire OS when he made a mistake. Virtualization wasn't available, so all he could do was restart and retry. Did it really go like that?

4
  • 4
    Yep, that's how it went. A random computer reboot happened, and happened often. Memory protection is a wonderful thing :)
    – Rocklan
    Commented Apr 29, 2013 at 11:06
  • 8
    When you don't have protected memory, there's no such thing as a segmentation fault. Of course, even if you do have protected memory, you can still clobber your own space; the OS just doesn't care about it.
    – Blrfl
    Commented Apr 29, 2013 at 11:36
  • 4
    Even now many pointer mistakes don't cause a nice segfault. Commented Apr 29, 2013 at 12:36
  • 1
    At the time of DOS, protected memory already existed in other OSes.
    – mouviciel
    Commented Apr 30, 2013 at 7:48

5 Answers 5

37

I can see a DOS programmer fiddling away and crashing the entire OS when he made a mistake.

Yeah, that's pretty much what happened. On most systems that had memory maps, location 0 was marked invalid, so that null pointers could be easily detected, because that was the most common case. But there were lots of other cases, and they caused havoc.

At the risk of sounding like a geezer, I should point out that the current focus on debugging is not the way of the past. Much more effort was previously made to write correct programs, rather than to remove bugs from incorrect programs. Some of that was because that was our goal, but a lot was because the tools made things hard. Try writing your programs on paper or on punched cards, not in an IDE, and without the benefit of an interactive debugger. It gives you a taste for correctness.

6
  • 3
    In fact, I was hoping "old geezers" would answer my question. Nothing beats first hand experience. Thanks. Commented Apr 29, 2013 at 11:30
  • 6
    Try writing code when the hardware is available for debugging every night from 02:00 to 06:00, assuming of course that your colleague hadn't reserved it for his debug session.
    – MSalters
    Commented Apr 29, 2013 at 12:38
  • @MSalters Indeed! At my first job, we could also book slots on Sunday from 0700 to 1900 - a real treat, lemme tell you :-) Commented Apr 29, 2013 at 21:43
  • 2
    I remember writing my first program on paper traveling home from university. Next day when I could punch it in and run it, it was flawless ;-)
    – Jan Doggen
    Commented May 2, 2013 at 12:26
  • 1
    @JanDoggen, same for me. When you have only one try you make that try really count.
    – nalply
    Commented May 2, 2013 at 19:59
23

Back in my day, we didn't have memory protection and all that snazzy business! We used printf to determine where we were in the program, and we liked it!

Though in all seriousness, it usually meant we were just more careful. Where malloc is called, there had to be a free somewhere else in the program, and such checking was rigorous because in the case of a problem, as you've clearly pointed out, segmentation faults are not helpful errors.

In the case of such errors, the best you could do is try to understand when such segmentation faults occur (using printf) and, looking at the code, determine why access to memory at that point was not valid and work backwards from there.

In essence, the same thing happens today, except we use debuggers to determine when errors occur, but you still have to understand why it happened, and it isn't always as simple as finding the line in which the error occurred. Errors cause errors like a chain reaction, and if you were a C programmer in those days, you spent 20% of your time coding and the rest of the time pulling your hair out fixing bugs.

3
  • 2
    Free the Mallocs!
    – CLo
    Commented Apr 29, 2013 at 12:20
  • 1
    Every once in a while, even today, even the call stack and variable state are utterly useless for determining just what the heck went wrong and how to fix it. That is the case particularly if you have complex software with a large number of possible states, some of which interdependent and some mutually exclusive. A single stray write anywhere and an omitted assertion for the guaranteed precondition can bring you right there.
    – user
    Commented Apr 29, 2013 at 14:45
  • 1
    @MichaelKjörling, I think that for what concerns discovering errors in programs, we've progressed only for what concerns finding the error trigger, but we've still got miles to go for uncovering the cause for these errors. Assertions help to keep me sane, for sure. :)
    – Neil
    Commented Apr 29, 2013 at 15:01
6

well ..

a segfault is a really nice indicator that something is wrong but you still have to find the root cause. So if you ask the question how do you find the root cause than the answer is not much different today than it was then. Of course the languages and tools became easier to work with but the general taktik is the same:

  • logging helps to find the area where your problem is. Binary search printf is a form of it.
  • debugging, step by step, break points and watches
  • refactoring to get a better understanding
  • staring hard at the code
  • look at the memory / core dump
  • feeding it with different data
  • showing it to other people
  • switch to a language without pointers (and a new set of problems) ...

On a more abstract level you have three approaches: 1. work with the code 2. look at the program while it runs 3. look the results after it did something stupid

btw a pointer error does not have to create a segfault.

As a Amiga programmer I used pretty much all of it. And yes restarts where common practise.

4

On the IBM 360, running Fortran batch jobs, we used to get hex core dumps. Such a dump could be as much as an inch thick of fan-fold green-and-white printer paper. It would tell what the registers were, and from there we could backtrack and figure out what the program was doing. We could find each subroutine and figure out where it stored its return address, so we could see the context. It would help to have an assembler listing of the program.

2

Once I was working on bugfixing on a then famous Windows 3.1 Presentation software.

I had a bug which, when it occurred, caused the Blue Screen of Death.

The bug only occurred when a certain loop had been executed over 1000 times. I used the advanced features of the debugger to let a break point pass 1000 times and then I carefully stepped through the program. Every time I went too far or skipped over a function call which contained the bug Windows Blue Screened.

Finally, after several days of work, I narrowed it down to a function that was running out of memory and instead of displaying an error message, appended the error message to a buffer. With every subsequent iteration it trashed more memory until something crucial was overwritten and Windows was trashed.

Debugging skills and perseverance was the solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.