He was running the compiler when the bug report came across his desk. The compiler, the program that translates a programmer’s code into machine-readable bits — Ethan Levin had laid his code before its merciless gaze, and now he stared into his screen to see its verdict. Was he aware of the tester passing behind him? Did he take any notice of how carefully she slipped between his whiteboard and his chair, holding in her stomach so as not even to brush against him? No, of course not. Oh, all right: perhaps peripherally. Literally in his peripheral vision he might have seen her, and the thought “tester” might have formed in his brain, which would have led to the automatically accompanying idea that testers only bring news of trouble, and so why bother with whatever trouble she was bringing him now?
He was occupied by other troubles. Warning messages were scrolling up his screen, the compiler’s responses, notices that this and that little thing in his code might not be legal, might not parse according to the rules, might prevent the compiler from turning his routine into an “object file,” a little file full of ones and zeros, ready to be linked up with other object files to create the executable program. He wasn’t getting fatal errors — no, not on this pass. There was nothing yet that caused the compiler to issue the awful message that began, “Fatal error,” and then, abruptly, stop. But such fatalities had already befallen him many times this morning, how many times, he’d lost track — twenty, fifty, a hundred? On each occasion, he had fixed whatever little thing wasn’t legal, didn’t parse, prevented his code from becoming machine-readable bits; and then he ran the compiler again.
Warning. Warning. Warning. Fatal error. Stop.
Fix the little thing in the code that wasn’t legal. Run the compiler again.
Warning. Warning. Fatal error. Stop.
Fix the next little thing.
“It’ll compile this time,” was the only thought Ethan Levin kept steadily in mind, over and over, on that morning of March 5th, 1984. Even the phone had to go on ringing — once, twice, three times — until it reached him, three rings to get inside his window of attention so tuned to the nervous refresh rate of the screen: Warning. Warning.
“What! Are you still there?” said the voice on the phone. “You’re supposed to be here!”
He sat confused for a moment. Yes, he knew the voice was Joanna’s, but the words “there” and “here”: what exactly did they mean? Then, all at once, his attention snapped into focus: it was Joanna, he was supposed to take her to the airport, and he was late.
“I’m leaving!” he said.
“I mean now. Are you leaving now?”
“I’m leaving, I’m leaving,” he said again, but vacantly, automatically, because despite himself, his eyes had been drawn back to the screen, to the irregular pulse of the messages as they appeared: Warning. Warning.
“Hello? Are you there?”
“Yeah, yeah. I’m here,” he said, just as the compiler suddenly displayed the message, “Fatal error: MAXWINSIZE not defined,” and came to a stop.
“Shit!” Ethan Levin muttered under his breath.
“Ethan! You’re compiling! I know it!”
“Yeah, yeah, sorry,” he said to Joanna McCarthy, who, as his girlfriend of four years, knew all too well the sort of exclamations he made when he was programming and compiling. “Sorry,” he repeated, but again automatically, because — though he knew better than to do this now — his mind immediately began ranging over the places where MAXWINSIZE should have been defined. On one side of his attention was Joanna, the month-long trip to India she was taking with Paul Ostrick, husband of her best friend Marsha Ostrick, and the promise Ethan had made to take them to the airport — and be on time! he swore! But on the other was this sudden and unexpected problem of MAXWINSIZE, this branching trail of questions that led off in many directions, curious and puzzling, down which his mind involuntarily started traveling …
“It’s an airplane, Ethan! It’s not going to wait for a compile!”
“Shit! Yes! I’m leaving now.”
“That’s like now now, right? Not like a one-more-compile now?”
“Now now,” he repeated, as much to himself as to Joanna. “Now now.”
Still, even after he’d stood up and grabbed his jacket from the back of his chair, the face of the screen drew him back. He sat down again, reread the messages on the monitor, typed a command to the system that set it searching through the entire code library for all occurrences of MAXWINSIZE. Yes, much better now. The system would tell him where the problem was. Then, tomorrow, he’d fix it.
- – - – - – - – - – - -
Days open: 32
Debugging: what an odd word. As if “bugging” were the job of putting in bugs, and debugging the task of removing them. But no. The job of putting in bugs is called programming. A programmer writes some code and inevitably makes the mistakes that result in the malfunctions called bugs. Then, for some period of time, normally longer than the time it takes to design and write the code in the first place, the programmer tries to remove the mistakes. One by one: find a bug, fix it. Bug: supposedly named for an actual moth that found its way into an early computer, an insect invader attracted to the light of glowing vacuum tubes, a moth that flapped about in the circuitry and brought down a machine. But the term surely has an older, deeper origin. Fly in the ointment, shoo fly, bug-infested, bug-ridden, buggin’ out, don’t bug me — the whole human uneasiness with the vast, separate branch of evolution that produced the teeming creatures who outnumber us, plague us, and will likely survive our disappearance from the earth. Their mindless success humbles us. A parallel universe without reason. From the Welsh: a hobgoblin, a specter.
Ethan Levin had never encountered a bug that was anything like a specter. In his twelve years as a programmer, he had come to understand that the process of programming was more or less equivalent to the process of debugging. Bugs were inevitable, everywhere, part of the job. So it was that, in the early afternoon of April 6, 1984, despite the fact that he had declared UI-1017 to be “fixed” and it had now certainly reappeared as not fixed, he reached over for the bug report with a sense of utter normalcy. And more: with the certainty that, while there would always be bugs in general, the cause of this particular bug would surely be found. For a bug always begins its life that way: as a creature of the programmer. It was a mistake, yes, a miscue, a slip of the mind; but the programmer’s mistake, his slip, of his mind. If Ethan had taken any particular notice of what was going through his mind that day, he would have heard his usual internal conversation in which he told himself that this was merely the one-thousand seventeenth bug in the user interface; one-thousand sixteen of which had already been fixed; some untold number yet to come, each in turn to be fixed in good order.
He reached for the bug report and reread the summary. And immediately the underlying code came to him — the pyramid of routines, code calling code, all finally resolving down to the operating system and the routines that managed the mouse, the disk, the peripherals, the network. He decided that the problem had to be in the code that supported the screens — the routines responsible for the menus and the mouse, most of it his own. Funny. That code had been out there for a long time, working. So what had changed? Code works for months and then suddenly stops working: something must have changed.
The answer came to him in a huge, head-clearing Of course! The cause was simple, ridiculously simple. He’d been working on those routines that night he was late to dinner and rushed home. He must have closed up everything too quickly, put the wrong versions back into the library. He could have confirmed this theory; he might have looked at the current version in the source-code control system. But his certainty swept him away. The bug had come back right then, on the very next day. Of course. All he had to do now was rebuild the user-interface library. Then retest the two screens. Which he did: Perfect. Working. Fixed.
Some part of Ethan’s mind knew that not encountering the bug right then was no assurance that the bug was indeed fixed. That tester could never reproduce the bug, and he himself couldn’t make it appear at will. It came and went, might come back again. And he knew that rebuilding a library was superstitious programmer behavior. Everyone did it. Have a problem you can’t find? Recompile and relink the code, and hope the problem goes away. Like a ballplayer in a slump who crosses himself before stepping into the batter’s box, it was a ritualized compulsion, a set of things you do over and over, things that may not work but you never know.
But he pushed these thoughts away. Ethan was still in the first phase of debugging. He may have accepted the second report of UI-1017, since he’d had no choice, but deep inside him he was still convinced there was no bug. It was user error, something wrong in the network, a glitch on the line, an out-of-date library, something else, but not a bug in his code. The stage every programmer with an unsolved bug clings to as long as possible: denial.
Days open: 91
The bug hid from the debugger. Ethan went back to his office, his debugger, his bug, but the system never crashed while the debugger was watching it. A quantum effect? Something in UI-1017 that was like an electron whose path is altered by the presence of an observer?
Ethan was certain — at each step — that the next one would bring on the crash. I’ll put in a breakpoint here, he thought; the program will pause; I’ll step to a line of code here, and certainly there it will be: the crash, the exact point where some mislogic had wound its way through the layers of code, finally percolating into functional absurdity. Some pointer would be NULL when it should have the value of an address in memory. Some Boolean variable would evaluate to FALSE when it should be TRUE. Some return code would show an error condition that was not checked by the program. And then all he had to do was think his way back through the layers, discover why it was NULL, FALSE, unchecked.
Step, he typed.
Line of code, the debugger answered.
Step, he typed.
Line of code, the debugger answered.
He ran his hands through his hair. Stared at the screen. Entered a new breakpoint.
Line of code.
The afternoon wore away, then the evening. His two officemates left, one then the other. The windows faded to black; the lights blinked off in office after office across the floor. Step, step, step, he went, walking through the code one programming statement at a time. It must be here, he thought. No, here. It will crash the next time. Okay, then the next time.
There was a roar at the door. The lights flashed on.
“Lo siento,” said the office cleaner.
She ignored him, he her. He lifted his feet, she vacuumed around him, turned off the lights, and moved on.
The moment the room went dark again, Ethan felt a surge of panic. What time was it?
Eleven. He should call Joanna.
The phone rang and rang. No answer. He dialed again. Again no answer. Where was she? Where was she?
Better fix that bug, his boss had said. The company president is acting like he never saw a bug before. The VCs are watching. Tomorrow he was supposed to meet with Harry about the schedule. He could not stop and simply leave a note for himself. No, the only note he could leave himself could be the bug report itself, with its message to the testers saying, “Fixed.”
Step, step, step.
Some part of him knew that he should get away from the debugger. He should get away from the machine, stop and think on a yellow pad, a white board. He wasn’t making headway this way. He kept beating against the same certainties — here, else here, else here. Writing and sketching might break his thinking patterns, force him into other channels. But there was something seductive about the debugger: the way it answered him, tirelessly, consistently. Such a tight loop: Step, he said. Line of code, it answered. Step, line of code; step, line of code. It was like the compulsion of playing solitaire: simple, repetitive, working toward a goal that was sure to be attained in just one more hand, just one more, and then one more again.
And so the paradox: The more the debugger remained the tireless binary companion it was designed to be — answering, answering, answering without hesitation or effort late into the night — the more exhausted and hesitant the human, Ethan Levin, found himself to be. He was sinking to the debugger’s level. Thinking like it. Asking only the questions it could answer. All the while he suffered what the debugger did not have to endure: the pains of the body, the tingling wrists and fingers, the stiffness in the neck, the aching back, the numb legs. And worse, the messy wet chemistry of the emotions, the waves of anxiety that washed across him, and then, without warning, the sudden electric spikes of panic.