6. 当好事者遭遇倒霉事

当然我们无法涵盖所有可能发生的倒霉事,但我会概述一些常识性的项目。

倒霉事有两种类型:随机的和可重复的。诊断或修复你无法控制其发生与否的随机问题非常困难。但是,如果问题是可重复的,“当我按两次向左箭头键时就会发生”,那么你就走上正轨了。

6.1. RTFM!

阅读友好的手册。 “手册”可以有几种形式。对于开源游戏,有游戏附带的 readme 文件。商业游戏将有印刷的手册,也许游戏 CD 上还有一些 readme 文件。别忘了浏览你的游戏 CD,寻找有用的提示和建议。

别忘了游戏的网站。游戏的作者可能已经见过很多人遇到和你完全相同的问题,并且可能会在网站上发布特定于该游戏的信息。一个典型的例子是 Loki Software 的在线 FAQ,网址为 http://faqs.lokigames.com

6.2. 查找更新和补丁

如果你正在玩你编译的开源游戏,请通过查看游戏网站确保你拥有最新版本。如果你的游戏来自发行版,请确保该游戏没有更新的 rpm/deb 包。

像 Loki 这样的商业游戏公司会发布游戏的补丁。通常一个游戏会有很多补丁(Myth2),有些游戏没有补丁就无法玩(Heretic2)。无论你是否在运行游戏时遇到问题,都要查看游戏网站上的补丁;可能存在你甚至没有意识到的安全问题的更新。

顺便说一句,Loki 现在有一个实用程序,可以搜索你硬盘上的 Loki Software 并自动更新它们。请查看 http://updates.lokigames.com

6.3. 新闻组

如果你不知道什么是 netnews (Usenet),那么绝对值得花 30 分钟时间来了解一下。安装一个新闻阅读器。我更喜欢控制台工具,所以我使用 tin,但 slrn 也很流行。 Netscape 也有一个不错的图形化“点击式”新闻阅读器。

例如,我可以使用 tin -g news.lokigames.com 浏览 Loki Software 的新闻服务器。你还可以使用$NNTP环境变量或文件/etc/nntpserver.

6.4. Google 群组搜索

发布到 Usenet 的每篇文章都会被存档到 Google 的数据库中,网址为 http://groups.google.com。这个存档以前在 http://www.deja.com,但被 Google 收购了。很多人仍然将这个存档称为“deja”。

几乎可以肯定的是,无论你在 Linux 上遇到什么问题,无论是游戏相关的还是不相关的,都已经有人在 Usenet 上提问并回答过了。不止一次,不止两次,而是很多次。如果你不理解你看到的第一条回复(或者它不起作用),那么尝试其他许多回复中的一条。如果页面不是你能够理解的语言,有很多翻译网站可以将文本转换为你喜欢的任何语言,包括 http://www.freetranslation.comhttp://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,这几乎无关紧要。

6.5. 调试:调用跟踪和核心文件

这通常不是你为商业游戏做的事情。对于开源游戏,你可以通过提供核心文件或堆栈跟踪来帮助作者。简而言之,核心文件(也称为核心转储)是一个文件,其中包含程序崩溃瞬间的“状态”。它为程序员提供了关于崩溃性质的宝贵线索——是什么原因导致了崩溃,以及程序在崩溃时正在做什么。如果你想了解更多关于核心文件的信息,我在 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
			

它可能很长,但使用你的鼠标剪切并粘贴此信息到一个文件中。给作者发邮件并告诉他

  1. 游戏的名称

  2. 游戏崩溃时屏幕上出现的任何错误消息。

  3. 导致崩溃的原因以及它是可重复的崩溃还是非可重复的崩溃。

  4. 调用堆栈

如果你有良好的带宽,请询问作者是否想要他的程序转储的核心文件。如果他说要,那就发送它。记住先询问,因为核心文件可能非常非常大。

6.6. 保存的游戏

如果你的游戏允许保存游戏,那么向作者发送一份保存的游戏副本很有用,因为它有助于技术人员重现任何错误。对于商业游戏,此选项比发送核心文件或调用堆栈更有成效,因为商业游戏无法重新编译以包含调试信息。你绝对应该在发送保存游戏文件之前询问,因为它们往往很大,但游戏公司通常有很多带宽。 Mike Phillips(前 Loki Software 员工)提到,向 Loki 发送保存的游戏绝对是一件好事。

不用说,这只适用于你的游戏在特定点可重复崩溃的情况。如果游戏每次运行时都发生段错误,或者速度慢得令人难以置信,那么保存的游戏文件就没什么帮助了。

6.7. 当文件或库未被找到时该怎么办(通过 strace 更好地生活)

有时你会看到错误消息,指示找不到文件。该文件可能是一个库

 % ./exult 
 ./exult: error while loading shared library: libSDL-1.2.so.0: cannot load shared object
 file: No such file or directory
			

或者它可能是一些数据文件,例如wadmap文件

 % 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 查找库文件的位置创建一个符号链接。

strace 是一个非常强大的实用程序。在诊断为什么找不到东西时,它是你最好的盟友,甚至比查看源代码更快。最后一点,你无法查找 Lokisoft 或 Tribsoft 商业游戏的源代码中的信息。但是你仍然可以对它们使用 strace!

6.8. 损坏的控制台

最令人遗憾的选择是重启。如果可以,最好有序关机;使用“halt”或“shutdown”。如果不能,请从另一台机器 ssh 登录。当你的控制台严重损坏时,有时这会起作用。在最坏的情况下,按下复位或电源开关。

请注意,如果你使用诸如 ext3、reiserfs 或 xfs 之类的日志文件系统,则按下电源开关并没有那么糟糕。你仍然应该以有序的方式关机,但文件系统完整性将得到维护。你通常不会看到使用日志文件系统的分区的 fsck。

6.9. 系统锁定

以获得非常简洁的帮助屏幕。要使用魔术 SysRq 键,你的内核需要已编译魔术 SysRq 支持。你会在“内核入侵 | 内核调试 | 魔术 SysRq 键