2

所以我有一些来自我运行的 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 多年前。

4

0 回答 0