程序员最可怕的噩梦是什么

【来源龙腾网】

评论原创翻译:

500

Mick Stute

This was mine:

I was hired by a psychologist to fix a program that seemed to have "strange output" written by one of his ex-grad students. It was a program that reads a data file, asks about 50 questions, does some calculations, and comes up with some score based on this PhD's research. It's on a research 3B2 at the university. He demonstrates the program and sure enough there seemed to be strange flashing words on the screen when it moves from question to question, and they don't seem nice. I agree to do it, should be pretty straightforward, so he'll pay me by the hour to determine how big the fix is and then we'll agree to a fee.

我先来说说我的噩梦:

一个心理学家雇我去修复一个程序,这个程序是他以前的一个研究生写的,这个程序最后输出来的结果有点奇怪。这是一个会读取数据文件、能提出大约 50 个问题、并进行一些计算,然后会根据这个博士的研究得出分数的程序。这是3B2的一项研究。他向我演示了这个程序,果然当它从一个问题移动到另一个问题的时候,屏幕上会闪烁一些奇怪的词,而且这次词看起来不太友好。最后我同意为他进行修复,因为我觉得这个问题应该很简单。他说先按小时计费,然后再根据修复的大小,最后再跟我商定具体的费用。

Day 1

I sit down at the 3B2 and login to the ex-grad student's account that has been given to me. This is where the code resides. I examine the C code. It is written to be hard to read. All the code is squished on one line. It's spread over 15 files with about 3 functions per file -- all on one line. All variable names are just three, seemingly random, letters. I talk to the guy and agree to go with hourly on this (great decision). I untangle all the code and format it nicely so I can see it.

It was done on purpose. It used the curses library to move to a point on the screen, print a question and the answers, and wait for a response. But it first went to the first line of the question, printed some white supremacy message, waited 1/2 a second, and then overwrote it with the question. This ought to be simple. There are only about five places it could output anything, and all of them had this subliminal flash of a message. dexe the offending mvprintw() and all is well. Or should be. I compile, thinking I'm done. But when I ran it, there it is again -- the subliminal messages. This time with different text still the same subject, just different messages.

I check my code and believe it or not it's back to the initial state I found it. 15 files, mangled, 3-letter variables -- the whole thing right back where I started. I want shoot myself for not making a copy of my code. I unmangle again, this time putting it in three files, named differently. I make a copy of the whole directory, and I mark the files readable only. I compiled it. All looks good. I run the program. There's now a copy of the original 15 files in the directory along with mine and the subliminal messages are back.

Okay, so somewhere on the disk is the source code necessary to keep doing this and he's set the program up to pull in that code when you compile it. I do a full disk search in the include areas (/usr/include) and since this is a research version we have source for just about everything but the kernel itself. That's a lot of header files and this takes some time on the 3B2, so that's day 1.

第1天:

我打开了3B2 ,然后登录了他给我的以前研究生的帐户。这就是代码所在的位置。我检查了 C 代码,这个代码写得难以读懂,所有的代码都压缩到了一行里。它分布在 15 个文件中,每个文件大约有 3 个函数,而且这些函数还都在一行。所有的变量名都只是三个看起来很随机的字母。然后我和那个心理学家谈过了,同意在这个问题上按小时计费(这个决定做得非常好)。我解开了所有的代码,并把他们全部格式化了,这样方便我查看。

这个程序是使用curses库移动到屏幕上的某个点,再输入问题和答案,然后等待响应。但它是先到了问题的第一行,输入了一些关于白人至上的不实信息,然后等了 1/2 秒之后,又用问题覆盖了这个信息。当我发现这一点的时候,觉得这应该挺简单的,因为它可以输出内容的地方只有五个,而且这五个地方都有这种信息闪现。所以我删掉有问题的 mvprintw()以后,一切正常,或者说应该是一切正常,我以为我完成了修复。但是当我再运行它的时候,它又出现了那些不实的信息。这次虽然是不同的文字,但主题还是相同的,只是信息不同而已。

我又重新检查了我的代码,不管你信不信,这个程序又回到了它的初始状态。 15 个损坏的文件,3 个字母的变量,一切又回到了我刚开始的地方。我当时特别后悔没有把我的代码复制过来,我只能把代码再重新解开一次。我这次把它放在了三个文件中,并给它们编了不同的名字。我复制了整个目录,并将文件标记为只读。我开始修复这个程序,一切看起来都不错。现在在我的目录里有15个原始文件的副本,然后我继续运行程序,那些不当的信息又出现了。

所以说,在这个磁盘上有一个地方有继续执行此操作的源代码,并且他已经将这个程序设置为在编译时就引入该代码。所以我不得不将这个程序所包含的区域全都进行了完整的磁盘搜索,因为这是一个研究版本,所以我们拥有除了内核本身之外的所有源代码。这是一个很大的母文件,所以需要在3B2上花费一些时间,但这才第一天。

Day 2

The disk search showed up nothing. The strings were apparently either encrypted or they are buried in a library somewhere. I decide to search all libraries for the text. This is even longer than before, so day two is over.

Day 3

No results. The strings are encrypted. That means I'm going to have to follow all the header files from each #include and each one they #include to find where this is. And that will, take some time. We do alx the campus computing department that we believe someone has gained root level access to Dr. Phelps research computer, which is just a shared lab computer in the science building. They're understandably not convinced.

I start unwinding the #include files. I do that, nowhere do I find the code. So now I know it's compiled in a library.Why not just recompile all those libraries, we do have the source after all.

第 2 天:

我们在磁盘搜索中一无所获。这些字符串要么是被加密了,要么是被藏在某个角落里。所以我决定搜索所有库中的文本。这比第一天还要花费更多的时间,所以第二天就这么结束了。

第 3 天:

还是没有结果。字符串被加密了,这意味着我将不得不跟踪每个 #include 和每个 #include 中的所有母文件,来找到它的位置。这需要一些时间。我们提醒校园的计算机部门,我们认为有人获取了菲尔普斯博士研究计算机的根级访问权限,因为这个计算机只是科学楼里的一台共享计算机。但是他们并不相信我说的话,但这也是可以理解的。

我开始跟踪#include 文件。即使我这么做了,我还是找不到代码。但现在我知道了它是在库里编译的。所以我们为什么不重新编译这些库呢,毕竟我们有源代码。

Days 4-6

The hardest part, convincing the campus nerds they have an issue. But we finally do and Mark, the Unix admin who was hired because he married the Dean's daughter, gets busy learning how to do this. In the end, he agrees to allow me to handle it, because he just doesn't really know how to get all that stuff compiled. End of Day 6, all standard libraries are recompiled. Woo hoo!

I whip out my modified, cleaned up source and start the compile. All looks good. I run it. O M G. It did it again. 15 messed up source files and the subliminal messages are back. This is suddenly like magic. I investigate very very carefully though I am stumped. This code doesn't exist in source code. I think I might be beaten. Dr. Phelps isn't happy with the hours involved and thinks maybe we ought to just rewrite the program from scratch. "Sure", I say staring at the terminal like a lost puppy too deep in my thoughts to put out of my thinking mode, "I think you're right. That will be quicker." "Good," he says, "we can start tomorrow."

Day 7

To hell with that. This guy isn't beating me. We are compiling it from his stinking code or not at all! "You don't have to pay me anymore, Dr. Phelps, I just want lab time." This is nerd war.

Days 8-14

I get smart, I'm thinking he somehow modified the curses library.I start learning. I read manuals for 6 days, piecing together that assembly code. Waste of time, nothing seems unusual.

第 4-6 天:

但最难的部分是,要如何说服校园里宅男们相信这个库是有问题的。但我们最终还是做到了,因为马克娶了院长的女儿,所以他被聘用为Unix的管理员,他一直在学习怎么编程。所以他最后同意让我来处理这个问题了,因为他真的不知道如何编译这些东西。等到第 6 天结束的时候,所有的标准库都会被重新编译。真是太棒了!

我拿出我修改过、清理过的源代码并开始重新编译,所有的进展都很顺利。然后我又重新运行了一下程序。结果,我的天呐,又变成那样了, 15 个混乱的源文件和不实的信息就像变魔术一样又出现了。尽管我被难住了,但我还是非常仔细地继续调查。源代码中并不存在此代码。我想这次的任务我可能要失败了。菲尔普斯博士对我花了那么多时间还没解决问题很不满意,他觉得我们应该从头开始重新写程序。我此时在这个问题中陷得很深,以至于无法摆脱我的思维模式,我像一只迷路的小狗一样盯着终端机说, “当然,我认为你说的对,那样做会更快。”他说, “很好,那我们明天就可以重新开始了。”

第 7 天:

让这个程序滚蛋吧,我不会被他打败的。我们正在根据他这个恶心的代码重新编写程序,或者根本就不编了! “菲尔普斯博士,你不用再给我付钱了,我现在只想要在实验室里继续编程。”这是两个程序员之间的战争。

第 8-14 天:

我变聪明了,我觉得他是在以某种方式修改了这个程序的库。我花了6天的时间去阅读操作手册,并把这些代码拼在了一起。我在继续消耗时间,这一切看起来并没有什么不寻常的。

Day 15

I suddenly realize it's in the compiler. It was the compiler. And every time you compile the original code and run it puts in the subliminal message code into the source code. I'd heard of this before.

Ah ah! I've got him!!!! We have the source code for the compiler as well. I search through it looking for a reference. Lo and behold, I find it. Indeed. There is source code in the compiler/lixer that does this:

1) it examines any call to fopen(), searches the file opened looking for Dr. Phelp's questions; if it finds them then

2) it rewrites the 15 files to the current directory when compiling that specific program.

3) It then compiles Dr. Phelps program using the 15 files and outputs to the -o name in the lix phase.

第 15 天:

我这天突然意识到它可能是在编译器中。原来是编译器!每次编译并运行原始代码时,它都会将不实的信息代码放入源代码中。我以前就听说过这个。

我忽然想起我们也有编译器的源代码。我去找找看有没有参考资料,果然,我找到了。确实,在编译器或链接器中有执行此操作的源代码:

1.首先,它检查了所有对 fopen() 的调用,如果发现有这些调用的话,它就会搜索打开的文件,来查找菲尔普斯博士的问题。

2.当你开始编写该特定程序时,它就会将 15 个文件重新写到了当前的目录中。

3.然后用这15个文件编写菲尔普斯博士的程序,并在链接阶段输出不好的言论。

The compiler was modified to put that code in Dr. Phelps program was written by the man that modified the compiler.

Several days later, an AT&T tech shows up with a disk and loads the proper compile and lixer source and we recompile the compiler from the source. That solves it. All the bad source in the compiler is gone and we've got a new clean copy of the compiler.

that source code, that now existed only in the executable compiler, put those changes back into the compiler source before it compiled it. But this time it didn't modify the /usr/src copy, it copied it to a hidden directory, modified the compiler source, compiled itself from there, and dexed the hidden directory. It took an AT&T tech to find this. The ex-grad student had poisoned the compiler to poison itself when it was recompiled. We had to put a new binary version of the compiler on disk from another 3B2 running the same revision before the problem went away.

We also found that if /sbin/login is compiled it puts in a backdoor allowing anyone who uses a specific password to login in as the root user. This computer is accessible by modem and Tymnet. Finally, this gets the computing center's attention.

编译器被修改为,将该代码放入菲尔普斯博士的程序里。这个程序是由修改编译器的人编写的。 

几天后,AT&T 的技术人员带着磁盘出现在我们的面前并加载了正确的编译器和链接器的源代码,我们从源代码中重新编译了编译器。这样问题就解决了,编译器中所有的错误源代码都消失了,我们得到了一个全新的编译器副本。

那个源代码,现在只存在于可执行的编译器中,在编译之前将那些更改重新放回编译器源代码中。但这一次它并没有修改/usr/src 副本,而是将其复制到一个隐藏目录,修改了编译器源代码,从那里编译,并删除了隐藏目录。 AT&T的技术人员找到了这个问题的来源。这位前研究生在编译器重新编译时毒害了编译器。在这个问题解决之前,我们不得不把一个新的编译器的二进制版本放在另一个相同版本的3b2的磁盘上。

我们还发现,如果编译了/sbin/login,它就会设置一个后门,允许任何使用特定密码的人以 root 用户身份登录。这台计算机可以通过调制解调器和 Tymnet 访问。最后,这件事引起了计算中心的注意。

Anonymous

After an 11-hour work day I was greeted by my father and he announced he had promised his "future boss" that his son was going to program a "small" application for him. For free. But maybe the boss would "give a gift" to me after I complete it. His exact words.

This "small" application by any estimates would take me 1.5 months minimum, IF I didn't work 60 hours a week already. That one and a half months is an extremely conservative estimate since the guy handed him a post-it note with a 6-7 vague things as requirements.

I'm getting angry again so I'll get to the point instead of rambling on. The point is, a coder's nightmare is not made of code, bugs, programming languages, computers, tools etc. It's made of people. There's a reason coders become coders. I love computers, but man, fuck people.

当我工作了 11 个小时回到家后,我的父亲在门口迎接我,并向我宣布,他已经向他的“未来老板”承诺了,他的儿子将会为他免费编写一个“小”的应用程序。也许这个老板会在我完成这个程序之后,会送给我一份礼物。 这就是他的原话。

就算我每周工作 60个小时,这个“小”的应用程序至少也要一个半月的时间才能完成。而且这一个半月还是一个非常保守的估计,因为那个老板给他递了一张便利贴,上面写着 6-7 条模糊的要求。

我真的是要生气了,所以这次我要开门见山的跟我的父亲说,而不是跟他东拉西扯。关键是,程序员的噩梦不是由代码、错误、编程语言、计算机、工具等组成的,而是由人组成的。程序员之所以成为程序员是有原因的。我喜欢电脑,但是我真的不喜欢和人打交道。

Aladin Bensassi

Code works perfectly after the first try. I mean, what kind of sorcery is this? The stars are not even aligned today.

A call from a relative. I could be in a hospital and they’d still ask if I can fix the “Internet” for them.

Favorite coffee shop is closed. What am I supposed to drink? Water?

Clients from hell.

“Hey bro, I have this awesome idea that can change the world, you can code it for me, and I’ll even give you 30% of the company. No, really hear me out, it’s like Facebook, but instead of sending full text messages, only 140 characters. Isn’t this revolutionary?”

Clients who ask for changes that could take me days to implement, but want them at the end of the day.

“This is the computer genius I told you about. He can totally fix your printer that fell from the fourth floor.”

代码在我第一次尝试后就完美的运行了。 我的意思是,这是哪门子的魔法啊? 今天的星星甚至都没有对齐呢。

一个亲戚给我打电话,问我能不能帮他们修好“网络”。 就算我在医院,他们还是会问我能不能帮他们修。

我最喜欢的咖啡店关门了。所以我应该喝什么呢?喝水吗?

我还有来自地狱的客户。

“嘿,兄弟,我有一个可以改变世界的很棒的想法,你可以帮我写代码,我甚至可以给你公司30%的股份。 不,你听我说完,它就像 Facebook一样,但不是发送短信,它只有 140 个字符。 这难道不是革命性的变化吗?”

客户提的要求我可能要花好几天的时间才能完成,但是他们想要我一天就能完成。

“这就是我跟你说过的那个计算机天才。 他甚至可以把你从四楼掉下去的打印机都能修好。”

全部专栏