[linux][valgrind] Au secours :{ Je comprends pas bien ce que je peux faire pour améliorer la situation :{
Je me prends la tête à utiliser valgrind qui semble être un bon outil pour détecter des soucis "taquins" dans des instructions écrites en C.
J'observe des bizarreries lors de l'exécution de mon programme qui met en oeuvre le multi-threading: ce sont des "artefacts" affichés à l'écran qui me font dire qu'il doit y avoir "des effets de bord" liés à des crasses
laissées en mémoire et qui sont lues et affichées de manière toute à fait "aléatoires" sans forcémment faire planter mon application.
J'ai réussi à virer toutes les erreurs liées à des "invalid write/read" ce qui est déjà très sympa... par contre...
Là où je bloque ce sont les messages de ce type:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| ==8566== Conditional jump or move depends on uninitialised value(s)
==8566== at 0x5599DA5: lc_add (linkedlist.c:283)
==8566== by 0x408B45: giveItemToPlayer (rpg_functions.c:224)
==8566== by 0x402BCE: main (rpg2014.c:461)
==8566==
{
<insert_a_suppression_name_here>
Memcheck:Cond
fun:lc_add
fun:giveItemToPlayer
fun:main
}
==8566== Conditional jump or move depends on uninitialised value(s)
==8566== at 0x5599DA5: lc_add (linkedlist.c:283)
==8566== by 0x408B83: giveSpellToPlayer (rpg_functions.c:232)
==8566== by 0x402E7B: main (rpg2014.c:471)
==8566==
{
<insert_a_suppression_name_here>
Memcheck:Cond
fun:lc_add
fun:giveSpellToPlayer
fun:main
}
==8566== Conditional jump or move depends on uninitialised value(s)
==8566== at 0x4C319B8: strcpy (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==8566== by 0x409A11: LoadMap (rpg_functions.c:680)
==8566== by 0x403146: main (rpg2014.c:499)
==8566==
{
<insert_a_suppression_name_here>
Memcheck:Cond
fun:strcpy
fun:LoadMap
fun:main
} |
Bon je sais je suis assez "lenient" concernant l'initialisation de pointeurs dont je sais qu'ils vont prendre une valeur qqs instructions plus loin dans le programme.
Voici les extraits de la "librairie" linkedlist qui est censée faire la gestion de listes doublement chaînées... c'est lc_add() qui pose soucis, en général (80% des erreurs du type Conditional jump or move gna gna gna value(s) sont liées à la fonction lc_add() )
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
//*****************************************************************************
// lc_init
//
// Permet d'initialiser une liste chaînée
//
// ENTREES:
// pListe: pointeur sur un élément de type ListeChainee
// SORTIE:
// néant
//*****************************************************************************
LinkedList* lc_init(void)
{
LinkedList *pListe=malloc(sizeof(LinkedList));
if(pListe!=NULL)
{
pListe->NbElem=0;
pListe->pHead=NULL;
pListe->pTail=NULL; // au départ j'avais mis pListe->pHead=pListe->pTail=NULL mais ça n'a rien changé :{
}
return pListe;
} |
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| //*****************************************************************************
// lc_add (ajout en fin de liste)
//
// pData: pointeur sur un élément de type void
// pListe: pointeur sur un élément de type ListeChainee
// type: représente le type de la donnée ajoutée
// taille représente la taille de la donnée ajoutée (en bytes)
//
// SORTIE:
//
// -1: en cas d'erreur
// Le numéro d'enregistrement du nouvel élément
//*****************************************************************************
int lc_add(void *pData,ListeChainee *pListe,short type,short taille)
{
lc_Datas *lc_new=(lc_Datas*)malloc(sizeof(lc_Datas));
lc_Datas *seekFirst=NULL; // dec2017 puis juillet 2020
if(lc_new==NULL || pListe==NULL) return -1; // juillet 2020
// Avril 2018
lc_new->pFree=NULL;
lc_new->pDisplay=NULL;
// l'ajout se fera toujours en queue...
if(pListe->pTail!=NULL) // <-- valgrind pas content :{
{
// Il y a un élément dans la liste
lc_new->dataSize=taille;
lc_new->dataType=type;
//lc_new->value=(void*)malloc(taille); dec2017
lc_new->value=pData;
lc_new->item_Number=gen_Number++;
pListe->NbElem++;
// chainage
// le dernier élément ne pointe plus sur NULL mais sur le nouvel élément créé
lc_new->pNext=NULL;
lc_new->pPrevious=pListe->pTail; // indiquer que l'élément qui précède celui-ci était pointé par pTail
pListe->pTail->pNext=lc_new; // indiquer que l'élément qui suit le dernier élément est maintenant le nouvel élément
pListe->pTail=lc_new; // indiquer que le dernier élément inséré est celui qui est inséré maintenant
// mettre à jour le pointeur pHead (tête de la liste)
seekFirst=pListe->pTail;
while(seekFirst!=NULL)
{
if(seekFirst->pPrevious==NULL) pListe->pHead=seekFirst;
seekFirst=seekFirst->pPrevious;
}
}
else
{
// La liste est vide
lc_new->pPrevious=NULL;
lc_new->pNext=NULL;
lc_new->dataSize=taille;
lc_new->dataType=type;
//lc_new->value=(void*)malloc(taille); dec2017
lc_new->value=pData;
lc_new->item_Number=gen_Number++;
pListe->NbElem++;
pListe->pHead=lc_new;
pListe->pTail=lc_new;
}
return lc_new->item_Number;
} |
Je me demande pourquoi valgrind m'indique que les "branchements conditionnels dépendent d'une valeur non initialisée" alors que normalement, et quand je débugge je le vérifie, les branchements conditionnels
comparent des valeurs qui ont été initialisées en amont dans le programme (???) et elles sont quasiment jamais à NULL sauf quand j'oublie d'utiliser lc_init() ou un initialisateur particulier...