J'essaie d'utiliser LLDB dans Xcode 8 pour déboguer une STL très basique. J'avais l'habitude d'imprimer un vecteur comme celui-ci:
p myvector[0]
pour voir ce qui était dans le premier index vectoriel. Maintenant, quand je fais ça, j'obtiens cette erreur:
error: Couldn't lookup symbols:
__ZNSt3__16vectorI9my_classNS_9allocatorIS1_EEEixEm
Au lieu de cela, je dois taper ceci:
p myvector.__begin_[0]
afin d'obtenir une sortie.
J'ai essayé d'importer les scripts libcxx.py et unordered_multi.py à partir du référentiel LLDB svn mais cela ne semble rien changer.
Quelqu'un a-t-il pu obtenir une sortie utile de LLDB avec libc ++?
[]
est une méthode d'opérateur sur std::vector
. Ainsi, pour imprimer l'expression souhaitée, lldb doit pouvoir appeler la méthode []
. Le problème ici est que la STL sous OS X s'acharne à tout aligner et à ne pas gaspiller de l'espace en produisant des copies décalées des mêmes fonctions. C'est excellent pour le code optimisé, mais pas pour le débogage, car il ne laisse aucun opérateur []
à appeler. C'est le message d'erreur que vous voyez.
Si vous voulez juste voir les éléments dans ce vecteur, vous pouvez utiliser le lldb "Formateurs de données STL" pour faire ce travail pour vous. Ils savent comment la plupart des types STL sont disposés et peuvent imprimer les éléments de la plupart des types de conteneurs. Par exemple:
(lldb) expr my_vec[0]
error: Couldn't lookup symbols:
__ZNSt3__16vectorI3FooNS_9allocatorIS1_EEEixEm
mais:
(lldb) expr my_vec
(std::__1::vector<Foo, std::__1::allocator<Foo> >) $0 = size=2 {
[0] = (var1 = 10, var2 = 20)
[1] = (var1 = 10, var2 = 20)
}
Il existe également une autre commande "frame variable" qui peut inspecter des objets statiques et s’accroche aux formateurs de données. Il ne peut pas appeler de fonctions ni effectuer d’autres tâches d’analyseur d’expression plus complexes, mais il sait comment utiliser les formateurs de données STL pour récupérer des éléments individuels:
(lldb) frame var my_vec[1]
(Foo) my_vec[1] = (var1 = 10, var2 = 20)
Vous pouvez même utiliser l'option -L
de frame var pour localiser les éléments du vecteur, puis vous pouvez transtyper l'adresse pour la transmettre à d'autres fonctions:
(lldb) frame var -L my_vec[1]
0x0000000100100348: (Foo) my_vec[1] = {
0x0000000100100348: var1 = 10
0x000000010010034c: var2 = 20
}
(lldb) expr printf("%d\n", ((class Foo *) 0x0000000100100348)->var1)
10
(int) $3 = 3
Une autre façon de contourner ce problème pour le débogage - si vous utilisez C++ 11 - consiste à mettre:
template class std::vector<MyClass>
dans votre code quelque part. Cela demandera au compilateur d'émettre des copies hors ligne de toutes les fonctions de modèle pour cette spécialisation. Ce n'est pas une excellente solution générale, et vous voulez le faire uniquement pour les versions de débogage, mais cela vous permet d'appeler ces fonctions et de les utiliser dans des expressions complexes.
Le problème similaire se produit aussi avec moi: error: Couldn't lookup symbols:
Ma solution est d'utiliser explicitement la fonction en question quelque part dans un code source.
#include <vector>
template<typename T>
struct Vector : std::vector<T>
{
Vector(size_t n)
: std::vector<T>{n}
{}
T& operator[](size_t n)
{ return std::vector<T>::operator[](n); }
};
struct XXX
{
int x;
};
void func()
{
std::vector<XXX> a{10};
Vector<XXX> b{10};
auto x = b[0]; // gcc will produce an assembler code of operator[] for debug purpose
1; // as a break point
}
Définissez un point d'arrêt sur la ligne 1; et l'exécuter.
(lldb) p a[0]
error: Couldn't lookup symbols:
__ZNSt3__16vectorI3XXXNS_9allocatorIS1_EEEixEm
(lldb) p b[0]
(XXX) $0 = (x = 0)
Bingo !! La fonction existe-t-elle dans un bloc TEXT?
(lldb) image lookup -r -n 'XXX.*operator'
1 match found in /Users/xxx/Library/Developer/Xcode/DerivedData/xxx:
Address: sandbox[0x00000001000011f0] (sandbox.__TEXT.__text + 256)
Summary: sandbox`Vector<XXX>::operator[](unsigned long) at main.cpp:19
Je ne suis pas sûr, mais j'avais déjà appris cela. Dans une étape de débogage, au lieu de l’étape de production. Si nous définissons un point d'arrêt sur une ligne dans une fonction d'un modèle, que ferait un débogueur? Définir des points d'arrêt, remplacer en réalité un code assembleur existant par trap ou jump, ici et là partout où le modèle est appliqué? Ou simplement définir un seul point d'arrêt dans une fonction? C'est écrit comme un modèle. Donc, il devrait être intégré dans une phase de production. Dans une phase de débogage, cependant, la fonction n'est pas en ligne et écrite comme une fonction normale. S'il vous plaît ne croyez pas simplement ce que je dis ici. S'il vous plaît confirmer par vous-même. Consultez la documentation de gcc,
clang,
et lldb.
#include <vector>
de MacOS 10.13.6, Xcode version 9.4.1 a une macro _LIBCPP_INLINE_VISIBILITY
:
template <class _Tp, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
typename vector<_Tp, _Allocator>::reference
vector<_Tp, _Allocator>::operator[](size_type __n)
{
_LIBCPP_ASSERT(__n < size(), "vector[] index out of bounds");
return this->__begin_[__n];
}
Le _LIBCPP_INLINE_VISIBILITY
est défini dans #include <__config>
comme:
#define _LIBCPP_INLINE_VISIBILITY __attribute__ ((__visibility__("hidden"), __always_inline__))
Ces mots-clés hidden
et __always_inline__
semblent contrôler le comportement.
Lorsque j'ai ajouté inline _LIBCPP_INLINE_VISIBILITY
à l'exemple de code de solution ci-dessus:
inline _LIBCPP_INLINE_VISIBILITY
T& operator[](size_t n)
{ return std::vector<T>::operator[](n); }
abouti à:
(lldb) p b[0]
error: Couldn't lookup symbols:
__ZN6VectorI3XXXEixEm
J'espère que cette aide et quelqu'un approfondiront davantage.