值得庆幸,我们大多数人永远不必在 1.5 亿英里之外调试软件。前美国宇航局(NASA)程序员、软件工程师罗恩·加雷特(Ron Garret)在亚当·戈登·贝尔(Adam Gordon Bell)的Corecursive播客的最近一期节目中,分享了他在深空飞船任务中诊断 Lisp 软件故障的经验。
加雷特分享了在深空调试的非凡故事——以及早期编程的回忆,在这个过程中,加雷特对编程世界发生的变与不变提出了令人耳目一新的视角,还探讨了为航天器编写代码的独特经验。
他想起了在 Lisp 历史上一个真正辉煌的时刻所扮演的角色。
超能力用户
从 1988 年到 2000 年,加雷特一直在 NASA 的喷气推进实验室担任研究科学家,在 2001 年到 2004 年间又担任了一次。加雷特的专长是自主移动机器人,他帮助开创了当今自主移动机器人控制架构的标准。
加雷特的团队致力于火星探测车“旅居者”(Sojourner)的机器人原型。
在播客中,加雷特描述了在 1988 年非常有限的编程选项——那时候还没有 Java、Python、JavaScript,甚至是 C++。“就流行的语言来说,有 Pascal、C、Basic 和机器码,用这些语言中的任何一个完成任何事情都非常、非常困难。”大多数航天器的代码最终都是用汇编语言编写的。
后来出现了 Lisp——一种将问题清晰地抽象为列表和函数的语言,虽然 C 程序员担心悬空指针这类的事情,但 Lisp 有自动内存管理。“当你使用的语言提供了一些高层次的抽象概念时,完成工作要快得多,也更容易。”加雷特道,“在一个只有 Lisp 语言具备这种能力的世界里,掌握 Lisp 真的就像一种超能力。“
使用 Lisp,“每个问题都变成了编译器的问题”
“在那个年代,它简直把其它东西都比下去了。”
但那时 Lisp 并没有被 NASA 广泛使用。
“对 Lisp 有相当多的偏见,因为它很奇怪,也不熟悉,还有奇怪的垃圾回收技术,你永远不知道它什么时候把你的进程停止了。” 加雷特道。
加雷特的团队发现它对于内存受限的硬件很管用,Lisp 可以对问题专门设计一种定制语言,然后针对机器人的硬件来编译它。正如贝尔所说,“每个问题都变成了编译器的问题。”加雷特的团队在机器人模拟器(在一台 Macintosh 电脑上)上煞费苦心地编写和测试了他们的代码,然后将其安装在实际的探测器上,并在阿罗约号(Arroyo)上进行了一次耗时的试驾。
尽管团队开发好了,但是当旅居者(Sojourner)探测器到达火星时,它使用的还是 C 代码。
后来,在 1998 年,NASA 的一位新主管启动了 “新千年项目”——通过一系列深空探索任务尝试不同(更便宜)技术的试点项目。
这意味着他们的 Lisp 代码获得了第二次生命,加雷特回忆道,团队为探测器开发的自主技术将被重新使用,它的新使命是飞行控制器。
加雷特的团队开发了一种新型决策软件——用 Lisp 专门设计的定制语言来避免可怕的“竞争条件”(即两个并发运行的线程争夺相同的内存空间)出现的可能性。“经过大量反复的测试”——用的是和进入太空完全相同的硬件,“所以我们非常有信心它会成功。 ”
“然而没有成功……”
深空故障
加雷特解释说,在他们为期三天的飞行控制中,“它正常运行了一段时间,做了应该做的,后来突然失效了,警钟响起…...”
“现在,这段证明没有死锁的代码似乎在离家 1.5 亿英里的地方被冻结了。“
局势很紧张,“我们不知道发生了什么……能做的就是当决定下来尽其所能,我们坐等了一小时。”在会议室里,团队达成了共识,他们的命令“经过了多级管理层的审查,所有人都必须在上面签字”。
在获得批准后,指令通过专用线路发送到深空网络一个 70 米宽的天线上,再以光速在太空中飞行……”
首先,他们请求了一个回溯——常见的操作,生成当前所有活动进程的列表(正如加雷特所述,“它们正在等待什么”)。
“实际上,几乎是立即看出了问题,因为有一个进程在等待本应该要发生的事……“
罗恩翻出了这些非常酷的照片:
“问题在于,这个竞争条件原本是不可能存在的。”然而加雷特团队的一位程序员调用了一个较低级别的 Lisp 函数——无意中为他们精心定制的语言创建了“安全保障的终端”(加雷特责怪自己没有向程序员解释清楚) 。
团队决定“手动”触发事件——让软件重新运行。
“我们没有失去航天器,也完成了所有任务——从技术上说,这是一次成功。” 加雷特在播客上道,“但过程是如此的艰辛,困难重重——而且,还有政治。尽管我们确实让它工作了,但之后自治项目被取消了,它再也没有飞行过。”
2002年加雷特个人网站上的一篇文章认为“Lisp 在喷气推进实验室(JPL)的消亡是一个悲剧,该语言特别适合于常见的软件开发:必须在非常紧张的预算和计划下开发独一无二、高度动态的应用程序。”
但是 Lisp 在 C++、Java 中被忽略了,究其原因是试图遵循“最佳实践”,加雷特认为,“我们混淆了最佳实践和标准实践,两者是不同的。”除此之外,“最终最好”并不是一个一成不变的标准,应取决于当前项目的具体情况。
在 Hacker News 的一次讨论中,一位称自己是 NASA 工程师的评论者,曾在 2009 年探索月球南极任务中担任有效载荷软件工程师,并表示他们使用Lisp编写了自己的定制语言,用于仪器命令序列(以及模拟计算机)。“Lisp 简单、灵活的语法和宏使表达命令和计时模式变得更容易 。“
他们消除了加雷特的疑虑:“我认为 Lisp 仍在 NASA 的各个角落中使用。”
评论