当然我们无法涵盖所有可能发生的倒霉事,但我会概述一些常识性的项目。
倒霉事有两种类型:随机的和可重复的。诊断或修复你无法控制其发生与否的随机问题非常困难。但是,如果问题是可重复的,“当我按两次向左箭头键时就会发生”,那么你就走上正轨了。
阅读友好的手册。 “手册”可以有几种形式。对于开源游戏,有游戏附带的 readme 文件。商业游戏将有印刷的手册,也许游戏 CD 上还有一些 readme 文件。别忘了浏览你的游戏 CD,寻找有用的提示和建议。
别忘了游戏的网站。游戏的作者可能已经见过很多人遇到和你完全相同的问题,并且可能会在网站上发布特定于该游戏的信息。一个典型的例子是 Loki Software 的在线 FAQ,网址为 http://faqs.lokigames.com。
如果你正在玩你编译的开源游戏,请通过查看游戏网站确保你拥有最新版本。如果你的游戏来自发行版,请确保该游戏没有更新的 rpm/deb 包。
像 Loki 这样的商业游戏公司会发布游戏的补丁。通常一个游戏会有很多补丁(Myth2),有些游戏没有补丁就无法玩(Heretic2)。无论你是否在运行游戏时遇到问题,都要查看游戏网站上的补丁;可能存在你甚至没有意识到的安全问题的更新。
顺便说一句,Loki 现在有一个实用程序,可以搜索你硬盘上的 Loki Software 并自动更新它们。请查看 http://updates.lokigames.com。
如果你不知道什么是 netnews (Usenet),那么绝对值得花 30 分钟时间来了解一下。安装一个新闻阅读器。我更喜欢控制台工具,所以我使用 tin,但 slrn 也很流行。 Netscape 也有一个不错的图形化“点击式”新闻阅读器。
例如,我可以使用 tin -g news.lokigames.com 浏览 Loki Software 的新闻服务器。你还可以使用$NNTP环境变量或文件/etc/nntpserver.
发布到 Usenet 的每篇文章都会被存档到 Google 的数据库中,网址为 http://groups.google.com。这个存档以前在 http://www.deja.com,但被 Google 收购了。很多人仍然将这个存档称为“deja”。
几乎可以肯定的是,无论你在 Linux 上遇到什么问题,无论是游戏相关的还是不相关的,都已经有人在 Usenet 上提问并回答过了。不止一次,不止两次,而是很多次。如果你不理解你看到的第一条回复(或者它不起作用),那么尝试其他许多回复中的一条。如果页面不是你能够理解的语言,有很多翻译网站可以将文本转换为你喜欢的任何语言,包括 http://www.freetranslation.com 和 http://translation.lycos.com。我选择的网页浏览器 Opera(可在 http://www.opera.com 获取)允许你使用鼠标右键选择部分文本,然后左键单击选择将其翻译成另一种语言。当 Google 群组搜索结果中出现一个看起来有用的德语页面,而我的妻子(她德语很好)又不在身边时,这非常有用。
Google 群组搜索有基本搜索和高级搜索页面。不要费心使用简单搜索。高级搜索位于 http://groups.google.com/advanced_group_search。
它很容易使用。例如,如果我的问题是 Quake III 每次 Lucy 跳跃时都会崩溃,我会在“查找包含所有这些词语的消息”文本框中输入“linux quake3 crash lucy jumps”。
有一些字段可以让你缩小搜索范围到特定的新闻组。花时间阅读并理解每个字段的含义。我向你保证。你不会对这项服务感到失望的。使用它,你会成为一个更快乐的人。请注意,他们不存档私有新闻组,例如 Loki Software 的新闻服务器。但是,由于太多人使用 Usenet,这几乎无关紧要。
这通常不是你为商业游戏做的事情。对于开源游戏,你可以通过提供核心文件或堆栈跟踪来帮助作者。简而言之,核心文件(也称为核心转储)是一个文件,其中包含程序崩溃瞬间的“状态”。它为程序员提供了关于崩溃性质的宝贵线索——是什么原因导致了崩溃,以及程序在崩溃时正在做什么。如果你想了解更多关于核心文件的信息,我在 http://www.dirac.org/linux 上有一个很棒的 gdb 教程。
至少,作者会对游戏崩溃时的调用堆栈感兴趣。以下是如何在崩溃时获取调用堆栈的方法
有时发行版会设置他们的操作系统,以便不生成核心文件(这主要对程序员有用)。第一步是让你的系统允许无限的核心大小
ulimit -c unlimited |
现在,你必须重新编译程序,并将 -g 选项传递给 gcc(解释这一点超出了本文档的范围)。现在,运行游戏并执行你用来使程序崩溃的操作,再次转储核心。使用核心文件作为第二个参数运行调试器
$ gdb CoolGameExecutable core |
在 (gdb) 提示符下,键入“backtrace”。你会看到类似这样的内容
#0 printf (format=0x80484a4 "z is %d.\n") at printf.c:30 #1 0x8048431 in display (z=5) at try1.c:11 #2 0x8048406 in main () at try1.c:6 |
它可能很长,但使用你的鼠标剪切并粘贴此信息到一个文件中。给作者发邮件并告诉他
游戏的名称
游戏崩溃时屏幕上出现的任何错误消息。
导致崩溃的原因以及它是可重复的崩溃还是非可重复的崩溃。
调用堆栈
如果你有良好的带宽,请询问作者是否想要他的程序转储的核心文件。如果他说要,那就发送它。记住先询问,因为核心文件可能非常非常大。
如果你的游戏允许保存游戏,那么向作者发送一份保存的游戏副本很有用,因为它有助于技术人员重现任何错误。对于商业游戏,此选项比发送核心文件或调用堆栈更有成效,因为商业游戏无法重新编译以包含调试信息。你绝对应该在发送保存游戏文件之前询问,因为它们往往很大,但游戏公司通常有很多带宽。 Mike Phillips(前 Loki Software 员工)提到,向 Loki 发送保存的游戏绝对是一件好事。
不用说,这只适用于你的游戏在特定点可重复崩溃的情况。如果游戏每次运行时都发生段错误,或者速度慢得令人难以置信,那么保存的游戏文件就没什么帮助了。
有时你会看到错误消息,指示找不到文件。该文件可能是一个库
% ./exult ./exult: error while loading shared library: libSDL-1.2.so.0: cannot load shared object file: No such file or directory |
或者它可能是一些数据文件,例如wad或map文件
% qf-client-sdl IP address 192.168.0.2:27001 UDP Initialize Error: W_LoadWadFile: couldn't load gfx.wad |
假设gfx.wad已经在我的系统上,但由于它不在正确的目录中而无法找到。那么正确的目录在哪里呢?如果知道这些程序在哪里查找丢失的文件,不是很有帮助吗?
这就是 strace 的闪光点。 strace 告诉你正在进行哪些系统调用,使用了哪些参数,以及它们的返回值是什么。在我的《内核模块编程指南》(即将发布到 LDP)中,我概述了你可能想知道的关于 strace 的一切。但这里有一个简要概述,使用了 strace 样子的典型示例。给出命令
strace -o ./LS_LOG /bin/ls |
-o 选项将 strace 的输出发送到一个文件;这里是 LS_LOG。 strace 的最后一个参数是我们正在检查的程序,这里是“ls”。查看 LS_LOG 的内容。相当令人印象深刻,不是吗?这是一条典型的行
open(".", O_RDONLY|O_NONBLOCK|0x18000) = 4 |
我们使用了open()系统调用来打开“.”,使用了各种参数,调用的返回值是 4。这与文件未被找到有什么关系呢?
假设我想观看 StateOfMind 演示,因为我似乎永远也看不够。有一天我尝试运行它,但发生了一些不好的事情
% ./mind.i86_linux.glibc2.1 Loading & massaging... Error:Can't open data file 'mind.dat'. |
让我们使用 strace 来找出程序在哪里查找数据文件。
strace ./mind.i86_linux.glibc2.1 2> ./StateOfMind_LOG |
拉出 vim 并搜索所有出现的mind.dat,我找到以下几行
open("/usr/share/mind.dat",O_RDONLY) = -1 ENOENT (No such file) write(2, "Error:", 6Error:) = 6 write(2, "Can\'t open data file \'mind.dat\'."..., ) = 33 |
它只在mind.dat一个目录中查找。mind.dat显然,/usr/share中没有mind.dat。现在我们可以尝试定位/usr/share并将它移动到
,或者更好的是,创建一个符号链接。这种方法也适用于库。假设库libmp3.so.2在/usr/local/include中,但你的新游戏“Kill-Metallica”找不到它。你可以使用 strace 来确定 Kill-Metallica 在哪里查找库,并从/usr/local/include/libmp3.so.2
到 Kill-Metallica 查找库文件的位置创建一个符号链接。
有时游戏会异常退出,你的控制台会变得“损坏”。对损坏的控制台有几种定义。文本字符可能看起来像乱码。你通常漂亮的黑色屏幕可能看起来像一个准图形屏幕。当你按下 ENTER 时,换行符不会回显到屏幕上。有时,键盘的某些键不会响应。注销并重新登录并不总是有效,但有一些方法可能会有效
如果你在键入时没有在屏幕上看到任何字符,则你的终端设置可能不正确。尝试“stty echo”。这应该让输入的字符再次回显。
在提示符下,键入“reset”。这应该可以解决许多问题,包括被基于 SVGAlib 或 ncurses 的游戏损坏的控制台。
再次正常尝试运行游戏。有一次我不得不匆忙杀死 Quake III,所以我执行了 Ctl-Alt-Backspace。控制台被准图形屏幕损坏了。运行 Quake III 并正常退出解决了问题。命令 deallocvt 和 openvt 将解决你将遇到的大多数其他问题。 deallocvt N 完全杀死终端N,以至于Alt-FN
甚至不再起作用。 openvt -c N 重新启动它。
如果键盘上的某些键不起作用,请发挥创造力。如果你想重启但“o”键不起作用,请尝试使用 halt。我想出的一个方法是在提示符下键入命令,并使用屏幕上的字符进行鼠标剪切/粘贴。例如,你可以键入“ps ax”,你肯定会在屏幕上的某个地方找到“h”、“a”、“l”和“t”。你可以使用鼠标剪切并粘贴单词“halt”。
最令人遗憾的选择是重启。如果可以,最好有序关机;使用“halt”或“shutdown”。如果不能,请从另一台机器 ssh 登录。当你的控制台严重损坏时,有时这会起作用。在最坏的情况下,按下复位或电源开关。
当计算机“锁定”(也称为“挂起”)时,键盘和鼠标变得完全没有响应。这是 Linux 内核中 bug 的直接后果。虽然 Linux 以稳定性而闻名,但这些事情确实会发生,特别是对于游戏而言,游戏需要高度同步的硬件事件,这些事件发生得非常快,即使对于计算机而言也是如此。当计算机锁定时,它可能是“硬锁定”,这意味着内核已完全停止运行。这通常表明硬件行为不当或存在故障。除了按下复位或电源按钮外,无法从此类锁定中恢复。锁定也可能是“软锁定”,这意味着内核仍在某种程度上运行。可以优雅地从此状态恢复。你应该尝试的第一件事是按control-alt-backspace
,这将杀死 X。如果你重新获得对系统的控制,则内核从一开始就不是真正锁定的。如果几秒钟后这仍然不起作用,你肯定需要使用以下说明重启系统。使用control-alt-delete
重启系统。如果几秒钟后你听到计算机发出哔哔声(这是 BIOS 在开机循环期间说“我没事”),你就知道这起作用了。
登录到另一个系统并通过 ssh 连接到挂起的系统。如果你可以 ssh 连接,请重启或停止系统。如果你无法 ssh 连接到系统,你需要使用“魔术 SysRq 键”,该键记录在/usr/src/linux/Documentation/sysrq.txt
中。这是 x86 架构的摘要(有关其他架构,请参阅文档)。请注意,如果你的键盘没有 SysRq 键,请使用 PrintScreen 键按alt-SysRq-s
。这将尝试同步你挂载的文件系统,以便将对文件的更改刷新到磁盘。你可能会听到磁盘活动。如果你正在查看控制台,系统应该会打印出已刷新的设备。几秒钟后,按alt-SysRq-u
。这将尝试将所有已挂载的文件系统重新挂载为只读)。你应该听到磁盘活动。如果你正在查看控制台,系统将打印出已重新挂载的设备。几秒钟后,使用alt-SysRq-b
重启系统。你可以按alt-SysRq-h
以获得非常简洁的帮助屏幕。要使用魔术 SysRq 键,你的内核需要已编译魔术 SysRq 支持。你会在“内核入侵 | 内核调试 | 魔术 SysRq 键