Можно ли получить ошибку сегментации, обратившись к выделенным, но неинициализированным данным в старом обычном c? Я не вижу как - PullRequest
0 голосов
/ 14 июля 2020

Думаю, это простой вопрос, но на всякий случай я добавлю некоторую информацию ниже: pthread_mutex_unlock (блокировка); вызов. Я вообще не реализую pthreads в своем коде, и вызывающей функции теоретически невозможно создать ошибку сегментации из того, что я вижу:

bool IsValidTeam(Team4v4Data* td)//pthread_mutex_unlock(mutex* lock) segfaulted here on the log
{
    if (!td)
        return false;
    else if (strncmp (td->captain, "INVALID_CAPTAIN", NAMESIZE) == 0)
        return false;

    //we checked for a null pointer and for the struct w/name  that should be passed during an error,
    //"INVALID_CAPTAIN", as the name, could get a non-null bad pointer but calling function 
    //should handle that in 100% of cases

    //if we did receive bad data though, we never got to the end of this function to the caller
    return true;
}

Вызывающая функция никогда не должна возвращать ничего, кроме достоверных данных для вызова IsValidTeam:

Team4v4Data* GetCaptainsTeam(Player* p)
{
    MyArenaData* mad = P_ARENA_DATA(arena4v4, arenaKey); //not mine and always works
    
    FOR_EACH_TEAM(t)//#defined as: for (int t = 0; t < MAXTEAMS; t++)
    {
        if (strncmp(mad->team[t].captain, p->name, NAMESIZE) == 0)
        {
            return &mad->team[t];
        }
    }
    //if we got here, none of the teams matched the players name
    //possible returns: a valid team object that matches the players name,
    //or this invalid team object containing td->captain is "INVALID_CAPTAIN"        
    return &mad->INVALID_TEAM;
}

И вызывающий абонент:

void Cready(Player* p, params* par, Target* targ, Arena* arena)//unsure of parameters, should be right
{
    Team4v4Data* td = GetCaptainsTeam(p);
    if (!IsValidTeam(td))//segmentation fault here
    {
        td->ready = true;
    }
    //else
        //notify players an error occurred and re-initialize/return the module 
        //to prevent further ones
    
    //do some processing, never got here
}

И приблизительный набросок структур:

typedef struct MyArenaData
{
    Team4v4Data team[MAXTEAMS];
    Team4v4Data INVALID_TEAM;//used for error checking in function returns instead of null pointer
//other random bools and data
} MyArenaData;

typedef struct Team4v4Data
{
    char captain[20];//normally initialized to "", but failed to initialize due to bug
    Player4v4Data slots[MAXPLAYERS];//has its own initializers, not used during our error though

//other random bools and data
} Team4v4Data;

typedef struct Player4v4Data
{
    char name[20];//normally initialized to "", but failed to initialize due to bug
    //other player stats
}

Итак, когда произошла ошибка , мы обнаружили данные в локациях для команды, и данные арены были неинициализированы из-за неправильной маркировки функции . Однако я не думаю, что данные, к которым осуществляется доступ, могут вызвать ошибку сегментации, потому что, даже если он не инициализирован, он все равно должен быть «правильным» местом в памяти для этих данных - любое чтение или запись операции могут вызвать «непреднамеренное поведение», но программа никогда не должна проходить мимо своего буфера или читать / записывать случайные ячейки памяти, потому что указатели всегда должны указывать на допустимую область данных, по замыслу.

Мой вопрос: : Правильно ли я думаю? Возможно ли, что эта ошибка сегмента возникла из моего кода, или это «должно быть что-то еще» в обработчике модуля из-за того, что существующие механизмы безопасности не могут получить доступ к внешней памяти в этом случае?

Кроме того, любой приветствуются предложения о безопасности нулевого указателя или лучшие идеи проверки данных. Спасибо за внимание.

EDIT: cra sh log:

Program received signal SIGSEGV, Segmentation fault.
__pthread_mutex_unlock_usercnt (mutex=0xffffffff, decr=1) at pthread_mutex_unlock.c:41 41      pthread_mutex_unlock.c: No such file
or directory. (gdb) bt
#0  __pthread_mutex_unlock_usercnt (mutex=0xffffffff, decr=1) at pthread_mutex_unlock.c:41
#1  0xf3a0465a in Cready (command=0xffffce3c "ready", params=0x82b3aa8 "\003", p=0xffffd084, target=0x0) at 4v4mod/4v4mod.c:327
#2  0x0807b5bf in run_commands (text=0x8380adf "", p=0x82b3aa8, target=0xffffd084, sound=0) at core/chat.c:366
#3  0x0807b9fd in handle_pub (p=0x82b3aa8, msg=0x8380ad9 "?ready", ismacro=0, isallcmd=0, sound=0) at core/chat.c:448
#4  0x0807c5c9 in PChat (p=0x82b3aa8, pkt=0x8380ad4 "\006\002", len=12) at core/chat.c:667

(gdb) frame 1
#1  0xf3a0465a in Cready (command=0xffffce3c "ready", params=0x82b3aa8 "\003", p=0xffffd084, target=0x0) at 4v4mod/4v4mod.c:327 327          
if (!IsValidTeam(td)) //player was not a captain, do nothing (gdb)
info locals td = 0xffffffff mad = 0xdfd7c300 (gdb) info args command =
0xffffce3c "ready" params = 0x82b3aa8 "\003" p = 0xffffd084 target =
0x0
...