Dans gdb, je peux appeler certaines fonctions de classe, mais d'autres “ne peuvent pas être résolus”. Pourquoi?
Je n'ai pas travaillé sur le partage des pointeurs encore .. je sais juste que le concept. Je suis en train de déboguer des fonctions en c++ suivant la classe, qui stocke les données d'un fichier XML (lire par xerces de la bibliothèque).
//header file
class ParamNode;
typedef boost::shared_ptr<ParamNode> PtrParamNode;
class ParamNode : public boost::enable_shared_from_this<ParamNode> {
public:
...
typedef enum { DEFAULT, EX, PASS, INSERT, APPEND } ActionType;
bool hasChildren() const;
PtrParamNode GetChildren();
PtrParamNode Get(const std::string& name, ActionType = DEFAULT );
protected:
....
ActionType defaultAction_;
}
Maintenant, si je suis le débogage d'un morceau de code dans lequel j'ai un exemple de l'pointeur vers la classe ParamNode
, et il est appelé paramNode_
PtrParamNode paramNode_;
//read xml file with xerces
paramNode_ = xerces->CreateParamNodeInstance();
//now, the xml data is stored in paramNode_.
std::string probGeo;
//this works in the code, but not in (gdb)!!
paramNode_->Get("domain")->GetValue("gt",probGeo);
cout << probGeo << endl; //<-- breakpoint HERE
À l'aide de gdb
je suis l'inspection de l' paramNode_
objet:
(gdb) p paramNode_
$29 = {px = 0x295df70, pn = {pi_ = 0x2957ac0}}
(gdb) p *paramNode_.px
$30 = {
<boost::enable_shared_from_this<mainclass::ParamNode>> = {weak_this_ = {px = 0x295df70, pn = {pi_ = 0x2957ac0}}},
_vptr.ParamNode = 0x20d5ad0 <vtable for mainclass::ParamNode+16>,
...
name_= {...},
children_ = {size_ = 6, capacity_ = 8, data_ = 0x2969798},
defaultAction_ = mainclass::ParamNode::EX, }
et imprimer ses membres:
(gdb) ptype *paramNode_.px
type = class mainclass::ParamNode : public boost::enable_shared_from_this<mainclass::ParamNode> {
protected:
...
mainclass::ParamNode::ActionType defaultAction_;
public:
bool HasChildren(void) const;
mainclass::PtrParamNode GetChildren(void);
mainclass::PtrParamNode Get(const std::string &, mainclass::ParamNode::ActionType);
Cependant, je ne peux appeler les fonctions HasChildren
ou GetChildren
, alors que l'appel de Get
de gdb
conduit à une erreur:
(gdb) p (paramNode_.px)->HasChildren()
$7 = true
(gdb) p (paramNode_.px)->GetChildren()
$8 = (mainclass::ParamNodeList &) @0x295dfb8: {
size_ = 6,
capacity_ = 8,
data_ = 0x29697a8
}
(gdb) p (paramNode_.px)->Get("domain")
Cannot resolve method mainclass::ParamNode::Get to any overloaded instance
(gdb) set overload-resolution off
(gdb) p (paramNode_.px)->Get("domain")
One of the arguments you tried to pass to Get could not be converted to what the function wants.
(gdb) p (paramNode_.px)->Get("domain", (paramNode_.px).defaultAction_)
One of the arguments you tried to pass to Get could not be converted to what the function wants.
Dans le code, l'exécution de la Get("domain")
fonction fonctionne très bien. Pourquoi est-ce? Je suis reconnaissant si vous incluez les explications dans votre réponse, en raison de ma connaissance limitée du partage des pointeurs.
- Peut-être que cela n'a rien à voir avec
shared_ptr
. Peut-êtregdb
juste ne peut pas convertir"domain"
(const char [7]
, peut implicitement se désintègrent en unconst char*
) àconst std::string&
(par la construction d'un temporairestd::string
) au moment de l'exécution. Je n'ai pas degdb
sous la main, mais je vous suggère d'essayer avec un code très simple commestd::size_t f(const std::string& s) { return s.length(); }
, puis dans gdbp f("hello")
et peut-êtrep f(std::string("hello"))
, pour voir si vous obtenez toujours l'erreur. - bonne idée. J'ai juste essayé ce. La fonction
f
travaille dans le code, cependant,(gdb) p f("hello") Attempt to take address of value not located in memory.
(gdb) set overload-resolution on (gdb) p f("hsdflo") Cannot resolve function f to any overloaded instance
. À l'aide destd:string
dans gdb a entraîné une erreur de syntaxe...
Vous devez vous connecter pour publier un commentaire.
gdb
n'est pas un compilateur, il ne sera pas faire le (pas si)nice type défini par l'utilisateur conversions pour vous. Si vous souhaitez appeler une fonction qui veut unstring
, vous avez besoin de lui donner unstring
, pas unconst char*
.Malheureusement,
gdb
ne peut pas construire unestd::string
pour vous sur la ligne de commande, parce que ce n'est pas un compilateur et de la création de l'objet n'est pas un simple appel de fonction.De sorte que vous devrez ajouter un peu de fonction d'aide de votre programme, qui prendrait une
const char*
et de retourner unestd::string&
. Notez la référence ici. Il ne peut pas revenir en valeur, parce qu'alorsgdb
ne sera pas en mesure de transmettre le résultat par référence const (ce n'est pas un compilateur!) Vous pouvez choisir de rentrer une référence à un objet statique, ou à un objet alloué sur le tas. Dans ce dernier cas, c'est une fuite de mémoire, mais ce n'est pas un gros problème puisque la fonction est destinée à être appelée uniquement à partir du débogueur de toute façon.Puis dans
gdb
devrait fonctionner.
DEFAULT
deuxième paramètre doit être fourni en tant que bien).(gdb) p (paramNode_.px)->Get(SSS("domain")) Too few arguments in function call.
. Toutefois, cela fonctionne:(gdb) p (paramNode_.px)->Get(SSS("domain"), (paramNode_.px).defaultAction_).px $28 = (mainclass::ParamNode *) 0x2969710
. Merci pour les commentaires détaillés!Un couple d'ajouts à la réponse précédente --
gdb va probablement fini par apprendre comment faire des conversions de ce genre. Il ne peut pas maintenant; mais il y est active, le travail sur l'amélioration du soutien pour le C++ analyse des expressions.
gdb ne pas comprendre les arguments par défaut, soit. C'est en partie un bug dans gdb; mais aussi en partie d'un bug dans g++, qui n'émet pas dans le NAIN. Je pense que le NAIN n'a même pas de définir un moyen pour émettre de la non-trivial des arguments par défaut.
Dans une telle situation, j'ai juste eu du succès après la commande
set overload-resolution off
"Désactiver la résolution de surcharge pour le C++ évaluation de l'expression. Pour éviter la surchauffe des fonctions qui ne sont pas membre de la classe des fonctions, GDB choisit la fonction première du nom spécifié qu'il trouve dans la table des symboles, qu'ils soient ou non ses arguments sont du type correct. Pour éviter la surchauffe des fonctions qui sont des fonctions de membre de classe, GDB recherches pour une fonction dont la signature correspond exactement les types d'argument." sourceware.org/gdb/current/onlinedocs/gdb/...n.m.'s réponse est génial, mais pour éviter d'avoir à modifier votre code et de recompiler prendre un coup d'oeil à la solution donnée dans La création de chaîne C++ dans GDB.
Dans cette solution, ils démontrent allocation d'espace pour un
std::string
sur le tas et puis l'initialisation d'unstd::string
de passer dans lafunction
ils aimeraient appel degdb
.