所以我有一些来自我运行的 MUD 的非常旧的 C 代码,我试图在使用 64 位编译器而不是 32 位编译器编译后让它运行。作为参考,我成功使用的当前编译器是 gcc 32 3.2.3(来自 2003 年),64 位编译器是 gcc 7.3.1。
当我运行游戏时,当游戏启动并将游戏的各个部分加载到内存中时,当前堆栈中的变量突然变得不可读。
这是有问题的功能的一部分:
void reset_zone(int zone) {
ACMD(do_wear);
bool items_loaded;
int cmd_no, last_cmd = 0;
int mob_load = FALSE; /* ### */
int obj_load = FALSE; /* ### */
struct char_data *mob = NULL;
struct obj_data *obj, *obj_to;
room_num r;
struct char_data *tmob = NULL; /* for trigger assignment */
struct obj_data *tobj = NULL; /* for trigger assignment */
int num_items, j;
bool found;
register struct char_data *i;
int player_count;
int object_max_load;
int force_load;
// Set Player Count used for determing item max load values, go no lower than 100 players
if (top_of_p_table < 100)
player_count = 100;
else
player_count = top_of_p_table;
for (cmd_no = 0; ZCMD.command != 'S'; cmd_no++) {
if (ZCMD.if_flag && !last_cmd && !mob_load && !obj_load)
continue;
if (!ZCMD.if_flag) { /* ### */
mob_load = FALSE;
obj_load = FALSE;
}
// sprintf(buf, "SYSERR: Debugging %c %d %d ", ZCMD.command, ZCMD.line, cmd_no);
// mudlog(buf, NRM, LVL_GOVERNOR, TRUE);
switch (ZCMD.command) {
case '*': /* ignore command */
last_cmd = 0;
break;
case 'M': /* read a mobile ###, check mob max, % load, and zone faction */
if ((mob_index[ZCMD.arg1].number < ZCMD.arg2) && //Limit
(number(1, 100) >= ZCMD.arg4) && //Percent
((zone_table[zone].faction >= ZCMD.arg5 && //Within range
zone_table[zone].faction <= ZCMD.arg6))) {
items_loaded = FALSE;
mob = read_mobile(ZCMD.arg1, REAL);
/* Random eq 1 in 5 mobs, if not flagged !random */
if (mob && !MOB_FLAGGED(mob, MOB_NO_RANDOM) && number(1, 5) == 3) {
num_items = 1;
/* Higher level mobs can load multiple items (1-4) */
if (GET_LEVEL(mob) >= 30 && number(1, 3) == 3) num_items++;
if (GET_LEVEL(mob) >= 60 && number(1, 3) == 3) num_items++;
if (GET_LEVEL(mob) >= 100 && number(1, 3) == 3) num_items++;
while (num_items > 0) {
switch (GET_MOB_CLASS(mob)) {
case CLASS_MOB_SMALLSHIP:
case CLASS_MOB_MEDSHIP:
case CLASS_MOB_CAPSHIP:
case CLASS_MOB_SPACE_BEAST:
case CLASS_MOB_SPACE_ENGINE:
case CLASS_MOB_FIGHTER_PIL:
case CLASS_MOB_SPACE_PIRATE:
case CLASS_MOB_NAVAL_OFFICER:
obj = load_space_random(GET_LEVEL(mob), FALSE, FALSE);
//obj = NULL;
break;
default:
obj = load_random(GET_LEVEL(mob), FALSE, FALSE, FALSE);
//obj = NULL;
break;
}
if (obj) {
obj_to_char(obj, mob);
items_loaded = TRUE;
}
num_items--;
}
}
char_to_room(mob, zone, ZCMD.arg3);
load_mtrigger(mob);
load_actions(mob);
if (items_loaded) do_wear(mob, "all", 0, 0);
tmob = mob;
一旦它调用load_actions(mob)
,从函数返回后,突然堆栈中的所有变量都超出范围,我Cannot access memory at address 0x7f00656371fb>
几乎得到了所有东西。
作为参考,这load_actions()
看起来像:
void load_actions(struct char_data *ch) {
struct char_data *vict, *victim;
bool found = FALSE;
char name[20];
if (MOB2_FLAGGED(ch, MOB2_FOLLOWER)) {
for (vict = zone_table[IN_ZONE(ch)].rooms[ch->in_room].people; vict && !found; vict = vict->next_in_room) {
if (vict && IS_NPC(vict) && MOB2_FLAGGED(vict, MOB2_LEADER) && GET_LEVEL(vict) > GET_LEVEL(ch) &&
are_friends(ch, vict) == TRUE) {
found = TRUE;
victim = vict;
continue;
}
}
if (found == TRUE) {
sprintf(name, "%s", victim->player.name);
do_follow(ch, name, 0, 0);
}
}
switch (GET_MOB_CLASS(ch)) {
case CLASS_MOB_JEDI:
break;
default:
break;
}//end class switch
}
我已经使用 GDB 逐步完成了这个,一旦我退出,load_actions()
一切都变得无法访问,知道为什么吗?
任何帮助将不胜感激,我意识到有些样式很可怕,这个源代码来自 20 多年前。