47 votes

Impression/Débogage de libcMD STL avec XCode/LLDB

Je suis en train d'utiliser LLDB dans Xcode 8 pour déboguer très de base de la STL. J'ai utilisé pour être en mesure d'imprimer un vecteur comme ceci:

p myvector[0]

pour voir tout ce qui était dans le premier vecteur d'index. Maintenant, quand je fais ça, j'obtiens cette erreur:

error: Couldn't lookup symbols:
  __ZNSt3__16vectorI9my_classNS_9allocatorIS1_EEEixEm

Au lieu de cela, j'ai taper ceci:

p myvector.__begin_[0]

afin d'obtenir une sortie.

J'ai essayé d'importer les libcxx.py et unordered_multi.py scripts à partir de la LLDB dépôt svn, mais qui ne semble pas changer quoi que ce soit.

Quelqu'un a pu obtenir aucune sortie utile de LLDB avec la libc++??

90voto

Jim Ingham Points 12823

[] est un opérateur de la méthode sur std::vector, afin d'imprimer l'expression que vous voulez, lldb devrait être en mesure d'appeler l' [] méthode. Le problème ici est que le TSL sur OS X est agressif sur inline tout ce qu'il peut, et pour ne pas perdre de l'espace de production de la ligne des copies des mêmes fonctions. C'est super pour l'optimisation de code, mais pas très bon pour le débogage, parce qu'elle laisse le débogueur avec n' [] opérateur téléphonique. C'est le message d'erreur que vous voyez.

Si vous voulez juste pour voir les éléments de ce vecteur, vous pouvez utiliser le lldb "STL formateurs" à faire ce travail pour vous. Ils savent comment la plupart des types STL sont disposés, et peut 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 y a aussi une autre commande "cadre " variable" qui peut inspecter des objets statiques, et des crochets dans les données de formatage. Il ne peut pas appeler des fonctions et d'autres plus complexes analyseur d'expression de tâches, mais il sait comment utiliser la STL de données des formateurs pour en extraire des éléments:

(lldb) frame var my_vec[1]
(Foo) my_vec[1] = (var1 = 10, var2 = 20)

Vous pouvez même utiliser un cadre de var -L option pour localiser les éléments du vecteur, et puis vous pouvez lancer les adresse pour passer à 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 cela pour du débogage si vous êtes à l'aide de C++11 - est-ce en mettant:

template class std::vector<MyClass>

dans votre code quelque part. Qui va demander au compilateur d'émettre hors-ligne des copies de tous les modèle de fonctions pour cette spécialisation. Ce n'est pas une bonne solution générale, et vous ne voulez le faire pour les versions de débogage, mais il ne vous laissez appeler ces fonctions et de les utiliser dans des expressions complexes.

0voto

Tora Points 407

Le même problème se produit également avec moi: error: Couldn't lookup symbols:

Ma solution est d'utiliser explicitement remis en question la fonction 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 de 1; et de 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 dans un bloc de TEXTE?

(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 appris cela avant. Un débogage stade, au lieu de l'étape de la production. Si nous avons mis un point d'arrêt sur une ligne en fonction d'un modèle, ce serait un débogueur à faire? Définition de points d'arrêt, effectivement remplacer certains de code assembleur avec siphon ou de sauter, ici et là, partout, le modèle est appliqué? Ou tout simplement mettre un point d'arrêt dans une fonction? Il est écrit comme un modèle. Donc, il devrait être incorporé dans une étape de production. Un débogage stade, cependant, la fonction n'est pas incorporé et écrit comme une fonction normale. S'il vous plaît ne pas simplement croire ce que je dis ici. Merci de confirmer par vous-même. Consulter la documentation de l' 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];
}

L' _LIBCPP_INLINE_VISIBILITY est définie en #include <__config> comme:

#define _LIBCPP_INLINE_VISIBILITY __attribute__ ((__visibility__("hidden"), __always_inline__))

Ces mots-clés hidden et __always_inline__ semblent contrôler son comportement.

Quand j'ai ajouté inline _LIBCPP_INLINE_VISIBILITY de la solution de l'échantillon de code ci-dessus:

    inline _LIBCPP_INLINE_VISIBILITY
    T& operator[](size_t n)
    { return std::vector<T>::operator[](n); }

traduite par:

(lldb) p b[0]
error: Couldn't lookup symbols:
  __ZN6VectorI3XXXEixEm

J'espère que l'aide et quelqu'un look beaucoup plus profondément.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X