web-dev-qa-db-fra.com

Inspection des conteneurs STL dans Visual Studio 2015

J'utilise Visual Studio Enterprise 2015, version 14.0.23107.0 D14REL.

Lors du débogage d'un programme C++, je ne peux pas voir le contenu des conteneurs STL.

L'option "Afficher la structure brute des objets dans les fenêtres de variables" est décochée (Outils-> Options-> Débogage-> Général).

Voici un exemple qui illustre le problème:

#include <list>
#include <string>
#include <vector>

int main()
{
    std::string string = "test";
    std::vector<int> vector{ 4, 5, 6 };
    std::list<std::string> list{ "one", "two", "three" };
    return 0;
}

Dans les fenêtres Locals ou Watch, je vois ce qui suit:

list         [...]()
vector       [...](...
  (error)    0
  (error)    0
string       {npos=4294967295}
  (error)    0
  (error)    0

Si je coche ensuite l'option "Afficher la structure brute ...", je peux explorer correctement les objets vectoriels et chaîne, mais pas la liste!

Y a-t-il une autre option que j'ai manquée ou s'agit-il d'un véritable bogue dans VS?

31
Graham Bull

J'ai eu le même problème.

Vous devez aller dans Outils-> Options-> Débogage-> Général et décochez "Utiliser le mode de compatibilité géré" et "Utiliser le mode de compatibilité natif".

26
Bogdan Mazurenko

J'ai le même problème, mais uniquement si le type de débogueur est "Mixte" (ou si mon projet contient du code C++/CLI et que le type est "Auto"). Avec le type de débogueur "Native Only", std :: vector dans son ensemble et son élément unique sont affichés correctement.

Vous pouvez utiliser le type de débogueur "Native Only" pour déboguer la partie C/C++ pure d'un projet mixte. Vous ne pouvez pas entrer dans le code C++/CLI.

Ajout: si vous rencontrez un problème d'affichage dans le débogueur natif, vous pouvez lire ceci: https://msdn.Microsoft.com/en-us/library/jj620914.aspx

6
Eugene

"Fonctionne sur ma boîte" ... enfin ... enfin ... mais je devais faire les étapes suivantes:

  1. Installer VS2015 Update 2 , prend environ trois heures
  2. Décochez les options "Utiliser le mode de compatibilité managé" et "Utiliser le mode de compatibilité natif" dans Outils | Options | Débogage
  3. Ajoutez ce commutateur reg, comme indiqué dans "Comment l'essayer" :

Clé de registre: HKCU\Software\Microsoft\VisualStudio\14.0_Config\AD7Metrics\ExpressionEvaluator\{3A12D0B7-C26C-11D0-B442-00A0244A1DD2}\{994B45C4-E6E9-11D2-903F-00C04FA302A1} Ajoutez DWORD LoadInShimManagedEE défini sur 0

Maintenant, je peux voir les conteneurs standard comme je ne l'ai jamais fait auparavant comme je le faisais dans les versions précédentes. La plupart de notre code C++ natif est appelé à partir de code C++/CLI, ce correctif est donc nécessaire.

2
Chris O

Non, ce n'est pas un bug dans Visual Studio! 

Microsoft Visual Studio 2005 est la première des versions de Visual Studio à prendre en charge les visualiseurs de débogueur utilisables pour les classes de modèles.

Il vous manque en fait un visualiseur pour votre std::<list> 

Ajoutez une règle de formatage dans le fichier autoexp.dat.

Vous pouvez trouver le fichier ici

%VSINSTALLDIR%\Common7\Packages\Debugger\autoexp.dat

Ajoutez une nouvelle règle à la section [Visualizer].

par exemple. Pour voir la taille de la liste

std::list<*,*>{
  preview
    (
      #("[list size=", $e._Mysize, "]")
    )
}

Nous accédons au membre _Mysize de l'implémentation std::<list>. _Mysize vous donne le nombre d'éléments dans la liste.

Pattern Matching:

std::list<*,*> correspondra à std::list<int> et std::list<int,std::allocator<int> >

std::list<*,*> correspondra à std::list<string> et std::list<string,std::allocator<string> >

Pour voir les articles pour enfants

std::list<*,*>{
  children
  (
    #(
      first item: $e._Myhead->_Next->_Myval,
      second item: $e._Myhead->_Next->_Next->_Myval,
      [third item]: $e._Myhead->_Next->_Next->_Next->_Myval
    )
  )
}

ou même

std::list<*,*>{
  children
  (
    #list(size: $c._Mysize,
          head: $c._Myhead->_Next,
          next: _Next
    ) : $e._Myval
  )
}
1
user1

Eu le même problème. Mon environnement: Gagnez 10 prof. x64, VS 2015, mise à jour 3, jeu d'outils v140, projet c ++. Je ne pouvais même pas voir les chaînes en plus . Le problème semble avoir été introculé par une mise à jour ou une extension.

Solution: J'ai effectué une nouvelle installation de VS2015 sur un autre système (gagnez 7 prof. X64). Cela a été installé .__ avec la mise à jour 3 (net. Install) . Sur cette machine, tout fonctionnait bien: pouvait voir les chaînes (sans développer l'infobulle dbg). Pour les conteneurs, la taille est indiquée lors du déplacement et vous pouvez inspecter des éléments. Parfait.

Quelle est la différence ? Je ne sais pas. J'ai comparé les fichiers .natvis sur les deux machines .__ et le C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Packages\Debugger\autoexp.dat

Pas de différences.

La solution était donc habituelle dans de tels cas: désinstaller VS2015. Exécutez un nettoyeur régulier. Réinstallez . Démarrer. Mes anciens paramètres étaient présents dès le premier démarrage et l'inspection de débogage A fonctionné à nouveau. Problème résolu.

0
nullptr

Je cours VS2015 SP3. J'ai passé 2 heures à essayer chaque solution que l'Internet me disait de faire. Rien n'a fonctionné! Mon dernier recours a été de réinstaller VS (ce qui prend des heures.) Je suis donc allé dans "Ajout/Suppression de programmes"> "Microsoft Visual Studio Professional 2015". Cependant, au lieu de désinstaller, j'ai essayé de faire une "réparation". Je ne sais pas ce qui a causé le problème, mais réparer l'installation l'a corrigé.

0
Jeff Lamb

Pour VS2015, j'ai dû modifier autoexp.dat pour la liste en tant que telle:

std::list<*>{
    preview (
        #(
            "[",
            $e._Mypair._Myval2._Mysize,
            "](",
        #list(
            head: $e._Mypair._Myval2._Myhead->_Next,
            size: $e._Mypair._Myval2._Mysize,
            next: _Next
        ) : $e._Myval,
            ")"
        )
    )  

    children (
        #list(
            head: $e._Mypair._Myval2._Myhead->_Next,
            size: $e._Mypair._Myval2._Mysize,
            next: _Next
        ) : $e._Myval
    )
}    

Ces modifications ont été obtenues en inspectant le stl.natvis du VS2015 et en notant les modifications apportées aux différentes structures de données marquées avec <!-- VC 2015 -->

J'ai également apporté des modifications appropriées à d'autres structures stl, mais sachez que je ne les ai pas toutes testées

std::unique_ptr<*>{
    preview (
        #if ($e._Mypair._Myval2 == 0) (
            "empty"
        ) #else (
            #(
                "unique_ptr ",
                *$e._Mypair._Myval2
             )
        )
    )

    children (
        #if ($e._Mypair._Myval2 == 0) (
            #array(expr: 0, size: 0)
        ) #else (
            #([ptr] : $e._Mypair._Myval2)
        )
    )
}

std::_Bind<*>{
    preview (
        #(
            "bind(", $e._Mypair,
            ", ", $e._Mypair._Myval2,
            ")"
        )
    )

children (
        #(
            #([f] : $e._Mypair),
            #([bound_args] : $e._Mypair._Myval2)
            )
    )
}

std::_Mem_fn_wrap<*>{
    preview (
        ; We preview the functor returned by mem_fn() with "mem_fn(<stored member function pointer>)".
        #(
            "mem_fn(",
            $e._Pm,
            ")"
        )
    )

    children (
        ; Member function pointers have no children.
        #array(expr: 0, size: 0)
    )
}

std::_Func_impl<*>{
    preview ( $e._Mypair._Myval2 )
    children (
        #(
            #([functor] : $e._Mypair._Myval2),
            #([allocator] : $e._Mypair)
        )
    )
}

std::function<*>{
    preview (
        #if ($e._Mystorage._Ptrs[$e._Impl] == 0) (
            ; Detecting empty functions is trivial.
            "empty"
        ) #else (
            *$e._Mystorage._Ptrs[$e._Impl]
        )
    )

    children (
        #if ($e._Mystorage._Ptrs[$e._Impl] == 0) (
            ; We make empty functions appear to have no children.
            #array(expr: 0, size: 0)
        ) #else (
            #([functor and allocator] : *$e._Mystorage._ptrs[$e._Impl])
        )
    )
}
std::basic_string<char,*>{
    preview     ( #if (($e._Mypair._Myval2._Myres) < ($e._Mypair._Myval2._BUF_SIZE)) ( [$e._Mypair._Myval2._Bx._Buf,s] ) #else ( [$e._Mypair._Myval2._Bx._Ptr,s] ))
    stringview  ( #if (($e._Mypair._Myval2._Myres) < ($e._Mypair._Myval2._BUF_SIZE)) ( [$e._Mypair._Myval2._Bx._Buf,sb] ) #else ( [$e._Mypair._Myval2._Bx._Ptr,sb] ))

    children (
        #(
            #([size] : $e._Mypair._Myval2._Mysize),
            #([capacity] : $e._Mypair._Myval2._Myres),
            #if (($e._Mypair._Myval2._Myres) < ($e._Mypair._Myval2._BUF_SIZE)) (
                #array(expr: $e._Mypair._Myval2._Bx._Buf[$i], size: $e._Mypair._Myval2._Mysize)
            ) #else (
                #array(expr: $e._Mypair._Myval2._Bx._Ptr[$i], size: $e._Mypair._Myval2._Mysize)
            )
        )
    )
}
std::basic_string<unsigned short,*>|std::basic_string<wchar_t,*>{
    preview     ( #if (($e._Mypair._Myval2._Myres) < ($e._Mypair._Myval2._BUF_SIZE)) ( [$e._Mypair._Myval2._Bx._Buf,su] ) #else ( [$e._Mypair._Myval2._Bx._Ptr,su] ))
    stringview  ( #if (($e._Mypair._Myval2._Myres) < ($e._Mypair._Myval2._BUF_SIZE)) ( [$e._Mypair._Myval2._Bx._Buf,sub] ) #else ( [$e._Mypair._Myval2._Bx._Ptr,sub] ))

    children (
        #(
            #([size] : $e._Mypair._Myval2._Mysize),
            #([capacity] : $e._Mypair._Myval2._Myres),
            #if (($e._Mypair._Myval2._Myres) < ($e._Mypair._Myval2._BUF_SIZE)) (
                #array(expr: $e._Mypair._Myval2._Bx._Buf[$i], size: $e._Mypair._Myval2._Mysize)
            ) #else (
                #array(expr: $e._Mypair._Myval2._Bx._Ptr[$i], size: $e._Mypair._Myval2._Mysize)
            )
        )
    )
}
std::deque<*>{
    preview (
            #(
            "[",
            $e._Mypair._Myval2._Mysize,
            "](",
            #array(
                expr: $e._Mypair._Myval2._Map[(($i + $e._Mypair._Myval2._Myoff) / $e._EEN_DS) % $e._Mypair._Myval2._Mapsize][($i + $e._Mypair._Myval2._Myoff) % $e._EEN_DS],
                size: $e._Mypair._Myval2._Mysize
            ),
            ")"
        )
    )

    children (
        #(
            #array(
                expr: $e._Mypair._Myval2._Map[(($i + $e._Mypair._Myval2._Myoff) / $e._EEN_DS) % $e._Mypair._Myval2._Mapsize][($i + $e._Mypair._Myval2._Myoff) % $e._EEN_DS],
                size: $e._Mypair._Myval2._Mysize
            )
        )
    )
}
std::forward_list<*>{
    preview (
        #(
            "(",
            #list(
                head: $e._Mypair._Myval2._Myhead,
                next: _Next
            ) : $e._Myval,
            ")"
        )
    )

    children (
        #list(
            head: $e._Mypair._Myval2._Myhead,
            next: _Next
        ) : $e._Myval
    )
}
std::vector<bool,*>{
    preview (
        #(
            "[",
            $e._Mysize,
            "](",
            #array(
                expr: (bool)(($e._Myvec._Mypair._Myval2._Myfirst[$i / $e._EEN_VBITS] >> ($i % $e._EEN_VBITS)) & 1),
                size: $e._Mysize
            ),
            ")"
        )
    )

    children (
        #(
            #([size] : $e._Mysize),
            #([capacity] : ($e._Myvec._Mypair._Myval2._Myend - $e._Myvec._Mypair._Myval2._Myfirst) * $e._EEN_VBITS),
            #array(
                expr: (bool)(($e._Myvec._Mypair._Myval2._Myfirst[$i / $e._EEN_VBITS] >> ($i % $e._EEN_VBITS)) & 1),
                size: $e._Mysize
            )
        )
    )
}
std::vector<*>{
    preview (
        #(
            "[",
                $e._Mypair._Myval2._Mylast - $e._Mypair._Myval2._Myfirst,
            "](",
            #array(
                expr: $e._Mypair._Myval2._Myfirst[$i],
                size: $e._Mypair._Myval2._Mylast - $e._Mypair._Myval2._Myfirst
            ),
            ")"
        )
    )

    children (
        #(
            #([size] : $e._Mypair._Myval2._Mylast - $e._Mypair._Myval2._Myfirst),
            #([capacity] : $e._Mypair._Myval2._Myend - $e._Mypair._Myval2._Myfirst),
            #array(
                expr: $e._Mypair._Myval2._Myfirst[$i],
                size: $e._Mypair._Myval2._Mylast - $e._Mypair._Myval2._Myfirst
            )
        )
    )
}
std::map<*>|std::multimap<*>|std::set<*>|std::multiset<*>{
    preview (
        #(
            "[",
            $e._Mypair._Myval2._Myval2._Mysize,
            "](",
            #tree(
                head: $e._Mypair._Myval2._Myval2._Myhead->_Parent,
                skip: $e._Mypair._Myval2._Myval2._Myhead,
                left: _Left,
                right: _Right,
                size: $e._Mypair._Myval2._Myval2._Mysize
            ) : $e._Myval,
            ")"
        )
    )

    children (
        #(
            #tree(
                head: $e._Mypair._Myval2._Myval2._Myhead->_Parent,
                skip: $e._Mypair._Myval2._Myval2._Myhead,
                left: _Left,
                right: _Right,
                size: $e._Mypair._Myval2._Myval2._Mysize
            ) : $e._Myval
        )
    )
}
std::unordered_map<*>|std::unordered_multimap<*>|std::unordered_set<*>|std::unordered_multiset<*>|stdext::hash_map<*>|stdext::hash_multimap<*>|stdext::hash_set<*>|stdext::hash_multiset<*>{
    preview (
        #(
            "[",
            $e._List._Mysize,
            "](",
            #list(
                head: $e._List._Myhead->_Next,
                size: $e._List._Mysize,
                next: _Next
            ) : $e._Myval,
            ")"
        )
    )

    children (
        #list(
            head: $e._List._Myhead->_Next,
            size: $e._List._Mysize,
            next: _Next
            ) : $e._Myval
    )
}
0
Dwayne Fujima