运行非常旧的C代码时遇到分段错误

时间:2019-04-20 10:48:55

标签: c unix cmake artificial-intelligence path-finding

作为人工智能课程的一部分,我正在研究游戏 我发现了解决机器人(滚石) here。这段代码 是在1999年(可能在HP UNIX工作站上)编写的。我似乎无法运行它 在我的平台上(Ubuntu Linux 18.10 x64)。我遇到细分错误 (SIGSEGV,SIGBUS等)

代码使用自定义的书面数据结构,例如指针使用的位字符串 算术和引用调用。例如,在一种情况下,我们获得了 index = t->Array[index][square];

进行的某种类型的屏蔽

我们检查看玩家进入哪个可能的状态,有空的方块或墙。

do {
        p = pos + xofs*t->Sup[i].x_ofs + yofs*t->Sup[i].y_ofs;
        /* test if goal is in the pattern, if yes, no deadlock  or
         * test the mirror pattern to see if that finds a deadlock */

        /* check for pattern overflow first */
        if (p<0 || p>XSIZE*YSIZE) 
            square = WallSquare;
        else {
            if (maze->Phys[p].goal >= 0) {
                goto TEST_MIRROR;
            }
            if (IsBitSetBS(maze->out,p)) square = WallSquare;
            else if (maze->PHYSstone[p]>=0) square = StoneSquare;
            else square = BlancSquare;
        }
        index = t->Array[index][square];
        i++;
       } while (index>0);

但是,数组是 空,所以我们得到了一个分割错误Here are the code in question

我已将代码移植到GitHub。您可以检查它here

注意:我也曾尝试在Ubuntu 16.04.06 X86和Visual Studio 2019中运行此代码,但是没有运气。

1 个答案:

答案 0 :(得分:2)

在我的测试中,第一次通过此代码(当index=0时),我们发现t->Array[0]包含一些巨大的数字。因此,index被发送到一个巨大的对象,并且在下一次循环中,它超过了t->Array的大小,您便崩溃了。

t->Array的内容最初是从函数LoadTree中的文件DL.1加载的:

        t->Next[0] = fread(t->Array,sizeof(DLENTRY),
                t->CurrentLength,fp);

很不幸,作者选择了以机器的本机二进制格式存储此数据,这可能与您当前的机器不一致。

现在DLENTRYint[3]的typedef。快速浏览DL.1,表明它似乎是32位大端整数。如果您是在x86上运行此程序,则您的int是32位little-endian。因此,读入数据后,您需要对这些数据进行字节交换(例如,通过用ntohl()对其进行循环。)

如果这表明其余代码具有可移植性,那么我认为将其移植到当前计算机上可能是一个艰巨的项目。