web-dev-qa-db-fra.com

Puis-je connaître la valeur de retour avant de retourner lors du débogage dans Visual Studio?

Prendre la fonction suivante:

DataTable go() {
    return someTableAdapter.getSomeData();
}

Lorsque je définis un point d'arrêt dans cette fonction, existe-t-il une possibilité d'inspecter la valeur renvoyée? go() est directement couplé à une grille de données dans une page .aspx.

Le seul moyen d'inspecter le datatable retourné est d'utiliser une variable temporaire. Cependant, c'est un peu gênant. N'y a-t-il pas un autre moyen?

363
doekman

Pas que je sache de. Notez que si vous do ajoutez une variable, elle sera supprimée par le compilateur dans les versions release de toute façon ...

Mise à jour: Cette fonctionnalité a été ajoutée à VS201 . Vous pouvez voir les valeurs de retour dans la fenêtre autos ou utiliser $ReturnValue dans la fenêtre de surveillance/immédiate.

La valeur ne peut être vue que directement après le retour de la fonction. Le moyen le plus simple d'y accéder est donc de placer un point d'arrêt sur l'appel de la fonction et de passer (F10) à l'appel.


Mise à jour pour VS2015: boo! malheureusement, cela ne semble pas être dans VS2015 (devenv v14)
Mise à jour pour VS2017: c'est de retour. (devenv v15)

250
Marc Gravell

Cela peut être fait dans Visual Studio 2013 avec CLR 4.5.1 selon le site de commentaires des clients . Il n'était pas disponible dans les versions précédentes pour C #.

(Visual Studio 2008 et versions antérieures le prenaient en charge pour VB.NET. Il a toujours été disponible pour les développeurs C/C++.)

58
Alex Angas

Je conviens que c’est une chose très utile: avoir non seulement la valeur de retour de la méthode avant d’en sortir, mais aussi la valeur de retour des méthodes que je viens de franchir. Je l'ai implémenté dans le cadre d'une extension commerciale de Visual Studio appelée " OzCode ".

Avec celui-ci, vous pouvez afficher les valeurs de retour de méthode directement sur l'éditeur de code, comme une sorte d'affichage HUD:

Statement Visualization

Pour plus d'informations, s'il vous plaît voir cette vidéo .

24
Omer Raviv

Selon Microsoft, il n’existe aucun moyen de l’implémenter de manière fiable avec du code géré. C’est un problème qu’ils connaissent et sur lesquels ils travaillent:

Pour ceux qui ont de l'expérience en débogage de code C++ ou VB6 natif, vous avez peut-être utilisé une fonctionnalité dans laquelle les valeurs de retour de fonction vous sont fournies dans la fenêtre Autos. Malheureusement, cette fonctionnalité n'existe pas pour le code géré. Bien que vous puissiez contourner ce problème en affectant les valeurs de retour à une variable locale, cela n’est pas aussi pratique car cela nécessite de modifier votre code. En code managé, il est beaucoup plus difficile de déterminer la valeur de retour d’une fonction que vous avez dépassée. Nous nous sommes rendus compte que nous ne pouvions pas toujours faire la bonne chose ici et nous avons donc supprimé la fonctionnalité plutôt que de vous donner des résultats incorrects dans le débogueur. Cependant, nous souhaitons vous en informer et nos équipes CLR et Debugger étudient diverses solutions potentielles à ce problème. Malheureusement, cela ne fera pas partie de Visual Studio 11.

https://connect.Microsoft.com/VisualStudio/feedback/details/597933/add-a-return-pseudo-variable-to-the-visual-studio-debugger-for-net-code

22
Dan Solovay

À propos de Visual Studio 2015:

Selon la réponse actuellement acceptée de Marc Gravell:

This fonctionnalité ajoutée à Visual Studio 201 . Vous pouvez voir les valeurs de retour dans les fenêtres autos ou utiliser $ ReturnValue dans la fenêtre watch/immediate

Cette réponse indiquait également que cette fonctionnalité ne fonctionnait pas dans Visual Studio 2015. Ce n'était pas (totalement) vrai. On Examine les valeurs de retour des appels de méthode, voici la remarque suivante:

Les évaluateurs d’expressions héritées doivent être activés pour que $ ReturnValue soit reconnu (Outils/Options/Débogage/Utiliser les anciens C # et VB évaluateurs d'expression ). Sinon, vous pouvez utiliser $ ReturnValue1 .

J'ai testé cela dans Visual Studio 2015 Enterprise:

  • Avec les évaluateurs d’expression existants désactivés: seulement $ ReturnValue1 fonctionne
  • Avec les évaluateurs d’expression existants activés: les deux $ ReturnValue et $ ReturnValue1 fonctionne
19
PascalK

Si vous accédez au menu OutilsOptions, IntelliTrace, et modifiez le paramètre pour collecter des événements et des informations sur les appels.

Vous pouvez revenir à l'événement d'appel précédent (Ctrl + Shift + F11) et voyez la valeur temporaire renvoyée par l'appel de méthode dans la fenêtre autos en tant qu'enfant du nom de la méthode.

Cela ne vous montre pas la valeur de retour pour la méthode dans laquelle vous vous trouvez. Il vous montre simplement la valeur de retour de la dernière méthode appelée dans la méthode en cours.

Donc, ça va pour

DataTable go(){return someTableAdapter.getSomeData();}

car il vous montre la valeur de retour pour someTableAdapter.getSomeData().

Mais pas pour:

int go(){return 100 * 99;}
13
Ross Buggins

Ancien truc des années antérieures à .NET: Ouvrez la fenêtre Registres et examinez la valeur du registre EAX. Ceci contient la valeur de retour de la dernière fonction appelée.

12
ColinM

Sortez de la méthode go () en utilisant Shift-F11, puis dans la fenêtre de débogage "Autos", il affichera la valeur de retour de l'appel de méthode qui vient de sortir de la pile (dans ce cas, la méthode go () qui est ce que tu veux). C'est le comportement dans Visual Studio 2005; Je n'ai pas utilisé Visual Studio 2008, donc je ne sais pas si cela se comporte de la même manière dans cette version.

9

Oui, il y a une très belle façon. Un inconvénient majeur est que vous devrez attendre 5, voire 6 ans. Depuis que je vois que tu as posté en novembre 2008, je suggère que tu waaaaaaa ...

... aaaait. Et voilà! Juste pour vous, MS a publié la dernière version de Visual Studio 201, qui est une fonctionnalité par défaut accessible à partir des menus en cours d’exécution en mode débogage (menu Debug Windows Autos ).

7
Konrad Viltersten

Il existe de nombreuses solutions de contournement, mais aucune ne semble satisfaisante.

Pour citer John Skeet ci-dessous (commentez une réponse maintenant supprimée):

Cela me semble toujours incommode, surtout si vous ne savez pas quelle valeur de retour vous allez avoir besoin avant de commencer le débogage. Je ne veux vraiment pas avoir une variable temporaire encombrant mon code chaque fois que je retourne quelque chose.t

En théorie, le débogueur pourrait avoir une variable return-. Après tout: c'est juste une variable sur la pile:

unsafe {
  int * sp = stackalloc int[1];
  try {
    return a+b;
  }
  finally {
    Trace.WriteLine("return is " + *(sp+3));
  }
}

Alors considérez ceci comme une demande de fonctionnalité pour Visual Studio.

5
doekman

Microsoft Visual C++ avait l'habitude de faire cela, mais Visual Studio ne s'en souvient pas .. :(

2
Sprintstar

Je voulais développer réponse de PascalK pour que cela fonctionne dans Visual Studio 2015, car il existe une fonctionnalité cachée qui n'est pas documentée dans Examiner le retour valeurs des appels de méthode.

Si vous avez des appels de fonction imbriqués, les pseudo-variables $ResultValueX Sont automatiquement créées, où X fait référence à l'ordre d'appel des fonctions. Donc, si vous avez un appel tel que Multiply(Five(), Six()), les pseudo-variables suivantes sont créées:

Five()     | $ResultValue1 = 5
Six()      | $ResultValue2 = 6
Multiply() | $ResultValue3 = 30
2
splttingatms

Le seul moyen que je connaisse est de placer un point d'arrêt sur la ligne de retour, puis d'appeler la fenêtre Quick Watch et d'entrer l'expression renvoyée:

someTableAdapter.getSomeData();

Mais cela ne fonctionne que si l'appel ne change pas l'état d'un objet (puisqu'il y aura un deuxième appel à la même méthode lorsque vous reprendrez l'exécution).

2
Sylvain Rodrigue

Vous pouvez également demander à évaluer la valeur dans la fenêtre intermédiaire également, si elle ne définit pas d'indicateurs ou d'autres variables, mais ne renvoie que quelque chose.

1
Biri

La réponse acceptée ne fonctionne pas correctement avec Visual Studio 2015, mais en plaçant un point d'arrêt sur la dernière ligne de la méthode et en appuyant sur F10, toutes les expressions de la valeur de retour seront placées dans la fenêtre locale.

1
Esben Skov Pedersen

L'ouverture de la fenêtre Débogage → Autos vous rapproche. Il ne montrera pas la valeur de retour réelle, mais montrera ce qui a été évalué dans l'instruction de retour.

1
GeekyMonkey

Oui, en passant à VB.NET. ; P (Vous venez de dire "Visual Studio".;)

Aussi longtemps que je me souvienne (de Visual Basic à toutes les versions de VB.NET), vous pouvez simplement interroger le nom de la fonction. Il "fonctionne" comme une variable locale implicitement déclarée au début de la fonction. Sa valeur actuelle est également utilisée comme valeur de retour à chaque fois que la fonction quitte via des instructions non retournées (c'est-à-dire Exit Function ou juste en train de tomber à travers) et bien sûr, lorsque l'instruction return est utilisée.

Il est également défini sur l'expression de l'instruction return. Tout comme une variable locale, sa valeur peut être inspectée à tout moment de l'exécution dans la fonction (y compris après l'exécution de l'instruction return). C # n'a pas cela et devrait.

Cette petite fonctionnalité VB.NET (plus le Exit Function déclaration qu’elle permet - une autre fonctionnalité que C # n’a pas et devrait) est très utile sous la forme de programmation défensive Je pratique où j’initialise toujours le nom de la fonction avec la valeur d'échec/par défaut comme première déclaration. Ensuite, à n'importe quel point de défaillance (ce qui se produit normalement beaucoup plus souvent que les points de réussite), je peux simplement appeler le Exit Function déclaration (c'est-à-dire sans avoir à dupliquer l'expression d'échec/par défaut ni même un nom constant/variable).

1
Tom

Je pense que vous pouvez le déterminer en consultant le registre RAX dans la fenêtre Registres (Debug/Windows/Registers). Après avoir quitté (SHIFT + F11) de la fonction, vérifiez le registre RAX. Je ne sais pas pour un fait, mais une fois sur une lune, vous pouvez vérifier un registre (avant les jours .NET) et voir la valeur de retour. Ce pourrait même être une combinaison de RAX et RBX, etc.

1
Joe Rattz

Vous pouvez essayer de sélectionner "someTableAdapter.getSomeData();", cliquer dessus avec le bouton droit de la souris et choisir Quick Watch.

0
Yann Semet