EDIT: Problème résolu. C'était (encore une autre) situation où le problème n'était pas vraiment là où il semblait que c'était. L'indice était l'utilisation de @ 0xfeeefefe comme pointeur sur un objet. Il s'agit d'une adresse renvoyée par une fonction de l'API Windows lors de la libération de la mémoire ... indiquant que l'objet en cours d'exécution avait été supprimé.Problème lors de la recherche de la source de mon erreur de segmentation
Je reçois une erreur de segmentation en essayant d'effacer une valeur d'une carte std :: map, mais je ne peux pas comprendre pourquoi. Depuis le débogueur (GDB) Je vois:
Program received signal SIGSEGV, Segmentation fault.
0x0048785f in std::less<irr::gui::IGUIWindow*>::operator()(irr::gui::IGUIWindow* const&, irr::gui::IGUIWindow* const&) const (this=0x258ab04, [email protected], [email protected])
at C:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_function.h:227
227 { return __x < __y; }
Mais la partie bizarre est l'examen suivant de ces deux valeurs d'entrée:
(gdb) x 0x22f778
0x22f778: 0x025e1ef8
(gdb) x 0xfeeefefe
0xfeeefefe: 0x025e1ef8
Un peu d'histoire: La carte est une application de pointeurs vers des pointeurs . Plus précisément, la clé est un pointeur vers une fenêtre dans un système graphique, et la valeur est un pointeur vers un objet qui peut envoyer des informations à imprimer à cette fenêtre. Il existe également une correspondance inverse entre l'objet débogable et la fenêtre. La raison en est que si la fenêtre est fermée, l'objet débogable doit être informé pour ne pas perdre de temps en essayant d'envoyer des données. Le mappage inverse est tel que lorsque le gestionnaire (la classe dont ce code est l'intérieur) reçoit un paquet d'un objet débogable, il sait dans quelle fenêtre imprimer l'information.
Donc la question est de savoir pourquoi une comparaison de deux valeurs de pointeur, return(0x025e1ef8 < 0x025e1ef8)
cause une erreur?
J'essaye seulement d'effacer des choses à un point dans mon code, et ce n'est pas dans une boucle donc il n'y a pas d'itérateurs à corrompre. J'insère aussi des choses sur cette carte à un autre endroit et j'ai des traces qui s'impriment lorsque des choses sont insérées et effacées et je ne vois rien de mal à cela.
Je sais que ce n'est pas assez d'informations pour vraiment aider, mais le code est vraiment grand et je ne suis pas sûr de ce que je peux faire pour dépister le problème. Je serais heureux de fournir plus d'informations s'il y a des suggestions. Je vais coller quelques parties du code pour avoir une idée rapide de ce qui se passe. J'espère qu'il y a quelque chose ici pour indiquer quel est mon problème.
est ici la partie du problème
case EGET_ELEMENT_CLOSED:
{
IGUIWindow* window =
static_cast<IGUIWindow*>(event.GUIEvent.Caller);
if(m_debugMap.find(window) != m_debugMap.end())
{
IGuiDebuggable* debug = m_debugMap[window];
debug->removeListener(this);
cout << "closing window: " << window << " attached"
" to debuggable: " << debug << endl;
m_debugMap.erase(window); /// segfault here
m_conMap.erase(debug); /// if above line commented, segfault here
}
m_eventMap.erase(window); /// if above block commented, segfault here
window->remove();
return true;
}
Et voici la partie où un élément est ajouté à la carte
IGUIElement* winElmnt =
m_env->getRootGUIElement()->getElementFromId(0,false);
IGUIElement* editElmnt = winElmnt->getElementFromId(1);
IGUIWindow* window = static_cast<IGUIWindow*>(winElmnt);
cout << "CModelTesterGui: adding " << window << "(" << winElmnt
<< ") to the debug map with edit box " << editElmnt << endl;
m_conMap[debug] = static_cast<IGUIEditBox*>(editElmnt);
m_debugMap[window] = debug;
window->setID(-1);
debug->addListener(this);
Comme vous pouvez le voir j'imprimer les adresses de ce qui est entrer et ce qui tente d'être effacé de la carte, et ils correspondent comme je m'attendais à ce que je ne cherche pas à effacer les valeurs défunts ou quoi que ce soit.
Oh, et une note finale. Voici une étrange bizarrerie. Si je n'ouvre qu'une fenêtre (c'est-à-dire que j'ajoute seulement un élément à la carte), je peux l'effacer correctement. Ce n'est qu'après avoir ajouté deux ou plusieurs éléments à la carte que tenter d'effacer l'un d'entre eux provoque une erreur de segmentation.
j'ai essayé de mettre un point d'arrêt sur HeapFree mais dit que la fonction n'est pas définie Peut-être le nom est-il déchiré? Je verrai si je peux le trouver – cheshirekow
OMG, merci, c'était exactement l'indice dont j'avais besoin, je n'ai pas trouvé de moyen de trouver une trace sur HeapFree , mais j'ai supposé que certains tas étaient en train d'être libérés (et ça ne devrait pas être le cas) et cela m'a alerté sur le problème, donc la classe est comptée, et -> removeListener a fait tomber l'objet source ... n'atteignait pas correctement la référence quand la classe a été ajoutée pour la première fois – cheshirekow