运行 非常旧的 C 代码时遇到分段错误
Encountering Segmentation Faults while running very old C code
作为人工智能课程的一部分,我正在研究一款游戏
解决机器人(滚石)我发现
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);
但是,数组是
空所以我们得到一个分段错误。 代码如下
问题
我已将代码移植到 GitHub。你可以看看here
注意:我也曾尝试 运行 Ubuntu 16.04.06 X86 和 Visual Studio 2019 中的此代码,但没有成功。
在我的测试中,第一次通过这段代码(当index=0
时)我们发现t->Array[0]
包含一些巨大的数字。所以 index
被发送到一个巨大的东西,下一次循环,它超过了 t->Array
的大小,你崩溃了。
t->Array
的内容最初从文件 DL.1
中加载到函数 LoadTree
:
t->Next[0] = fread(t->Array,sizeof(DLENTRY),
t->CurrentLength,fp);
很遗憾,作者选择以他们机器的本机二进制格式存储此数据,这可能与您当前的机器不一致。
现在 DLENTRY
是 int[3]
的类型定义。快速浏览 DL.1
表明它似乎是大端 32 位整数。如果您在 x86 上 运行 this,那么您的 int
是 32 位小端。因此,您需要在读入数据后对其进行字节交换(例如,通过使用 ntohl()
.)
对其进行循环
如果这是其余代码的可移植性的任何迹象,那么我认为将它移植到您当前的计算机可能是一个重要的项目。
作为人工智能课程的一部分,我正在研究一款游戏 解决机器人(滚石)我发现 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);
但是,数组是 空所以我们得到一个分段错误。 代码如下 问题
我已将代码移植到 GitHub。你可以看看here
注意:我也曾尝试 运行 Ubuntu 16.04.06 X86 和 Visual Studio 2019 中的此代码,但没有成功。
在我的测试中,第一次通过这段代码(当index=0
时)我们发现t->Array[0]
包含一些巨大的数字。所以 index
被发送到一个巨大的东西,下一次循环,它超过了 t->Array
的大小,你崩溃了。
t->Array
的内容最初从文件 DL.1
中加载到函数 LoadTree
:
t->Next[0] = fread(t->Array,sizeof(DLENTRY),
t->CurrentLength,fp);
很遗憾,作者选择以他们机器的本机二进制格式存储此数据,这可能与您当前的机器不一致。
现在 DLENTRY
是 int[3]
的类型定义。快速浏览 DL.1
表明它似乎是大端 32 位整数。如果您在 x86 上 运行 this,那么您的 int
是 32 位小端。因此,您需要在读入数据后对其进行字节交换(例如,通过使用 ntohl()
.)
如果这是其余代码的可移植性的任何迹象,那么我认为将它移植到您当前的计算机可能是一个重要的项目。