Tout d'abord, je m'excuse pour la longueur de cette question.
Je suis l'auteur de IronScheme. Récemment, j'ai travaillé dur sur émettant décent informations de débogage, de sorte que je peux utiliser le "native".NET débogueur.
Tout cela a été en partie réussi, je suis en cours d'exécution dans certains problèmes de dentition.
Le premier problème est lié à l'intensification.
En raison de Régime étant une expression de la langue, tout tend à être enveloppé dans la parenthèse, à la différence de la majeure .NET languages qui semble être énoncé (ou de ligne).
Le code d'origine (Schéma) ressemble à:
(define (baz x)
(cond
[(null? x)
x]
[(pair? x)
(car x)]
[else
(assertion-violation #f "nooo" x)]))
J'ai exprès mis chaque expression sur un retour à la ligne.
Le code émis transforme en C# (via ILSpy) ressemble à:
public static object ::baz(object x)
{
if (x == null)
{
return x;
}
if (x is Cons)
{
return Builtins.Car(x);
}
return #.ironscheme.exceptions::assertion-violation+(
RuntimeHelpers.False, "nooo", Builtins.List(x));
}
Comme vous pouvez le voir, assez simple.
Remarque: Si le code a été transformé en une expression conditionnelle (?:) en C#, le tout serait juste un debug étape, gardez cela à l'esprit.
Ici, IL est sortie avec la source et les numéros de ligne:
.method public static object '::baz'(object x) cil managed
{
// Code size 56 (0x38)
.maxstack 6
.line 15,15 : 1,2 ''
//000014:
//000015: (define (baz x)
IL_0000: nop
.line 17,17 : 6,15 ''
//000016: (cond
//000017: [(null? x)
IL_0001: ldarg.0
IL_0002: brtrue IL_0009
.line 18,18 : 7,8 ''
//000018: x]
IL_0007: ldarg.0
IL_0008: ret
.line 19,19 : 6,15 ''
//000019: [(pair? x)
.line 19,19 : 6,15 ''
IL_0009: ldarg.0
IL_000a: isinst [IronScheme]IronScheme.Runtime.Cons
IL_000f: ldnull
IL_0010: cgt.un
IL_0012: brfalse IL_0020
IL_0017: ldarg.0
.line 20,20 : 7,14 ''
//000020: (car x)]
IL_0018: tail.
IL_001a: call object [IronScheme]IronScheme.Runtime.Builtins::Car(object)
IL_001f: ret
IL_0020: ldsfld object
[Microsoft.Scripting]Microsoft.Scripting.RuntimeHelpers::False
IL_0025: ldstr "nooo"
IL_002a: ldarg.0
IL_002b: call object [IronScheme]IronScheme.Runtime.Builtins::List(object)
.line 22,22 : 7,40 ''
//000021: [else
//000022: (assertion-violation #f "nooo" x)]))
IL_0030: tail.
IL_0032: call object [ironscheme.boot]#::
'ironscheme.exceptions::assertion-violation+'(object,object,object)
IL_0037: ret
} // end of method 'eval-core(033)'::'::baz'
Remarque: Pour empêcher le débogueur de simplement en soulignant l'ensemble de la méthode, je fais la méthode de point d'entrée à seulement 1 colonne de large.
Comme vous pouvez le voir, chaque expression correctement les cartes à une ligne.
Maintenant, le problème avec les pas à pas (testé sur VS2010, mais même problème sur VS2008):
Ce sont avec IgnoreSymbolStoreSequencePoints
n'est pas appliqué.
- Appel baz avec null arg, il fonctionne correctement. (null? x), suivie par x.
- Appel baz, par Contre arg, il fonctionne correctement. (null? x) alors (paire? x) alors (car x).
- Appel baz avec d'autres arg, il échoue. (null? x) alors (paire? x) alors (car x) alors (affirmation de la violation ...).
Lors de l'application d' IgnoreSymbolStoreSequencePoints
(comme recommandé):
- Appel baz avec null arg, il fonctionne correctement. (null? x), suivie par x.
- Appel baz, par Contre arg, il échoue. (null? x) alors (paire? x).
- Appel baz avec d'autres arg, il échoue. (null? x) alors (paire? x) alors (car x) alors (affirmation de la violation ...).
Je trouve aussi dans ce mode que certaines lignes (non montré ici) sont incorrectement mis en évidence, ils sont à 1.
Voici quelques idées de ce que pourrait être les causes:
- Tailcalls confond le débogueur
- Le chevauchement des lieux (non montré ici) confond le débogueur (il le fait très bien lors de la configuration d'un point d'arrêt)
- ????
La deuxième, mais aussi grave, le problème est le débogueur à défaut de casser/hit points d'arrêt dans certains cas.
Le seul endroit où je peux obtenir le débogueur pour rompre correctement (et toujours), est à la méthode de point d'entrée.
La situation devient un peu mieux quand IgnoreSymbolStoreSequencePoints
n'est pas appliquée.
Conclusion
Il se pourrait que le VS débogueur est tout simplement buggy :(
Références:
Mise à jour 1:
Mdbg ne fonctionne pas pour la version 64 bits assemblées. De sorte que c'est. Je n'ai plus les machines 32 bits, pour faire des tests. Mise à jour: je suis sûr que c'est pas un gros problème, quelqu'un aurait-il une solution? Edit: Oui, je suis bête, il suffit de commencer mdbg en vertu de l'x64 l'invite de commande :)
Mise à jour 2:
J'ai créé une application en C#, et j'ai essayé de disséquer la ligne info.
Mes conclusions:
- Après tout
brXXX
d'instructions, vous devez avoir un point de séquence (si ce n'est valable aka '#line caché", émettent unnop
). - Avant tout
brXXX
instruction, émettent un "#line caché " et unnop
.
Cette application n'est toutefois pas de résoudre les problèmes (seul?).
Mais l'adjonction de ce qui suit, donne le résultat souhaité :)
- Après l'
ret
, émettent un "#line caché " et unnop
.
C'est à l'aide de la mode où IgnoreSymbolStoreSequencePoints
n'est pas appliquée. Lorsqu'il est appliqué, certaines étapes sont encore ignorés :(
Voici le IL lors de la sortie ci-dessus a été appliquée:
.method public static object '::baz'(object x) cil managed
{
// Code size 63 (0x3f)
.maxstack 6
.line 15,15 : 1,2 ''
IL_0000: nop
.line 17,17 : 6,15 ''
IL_0001: ldarg.0
.line 16707566,16707566 : 0,0 ''
IL_0002: nop
IL_0003: brtrue IL_000c
.line 16707566,16707566 : 0,0 ''
IL_0008: nop
.line 18,18 : 7,8 ''
IL_0009: ldarg.0
IL_000a: ret
.line 16707566,16707566 : 0,0 ''
IL_000b: nop
.line 19,19 : 6,15 ''
.line 19,19 : 6,15 ''
IL_000c: ldarg.0
IL_000d: isinst [IronScheme]IronScheme.Runtime.Cons
IL_0012: ldnull
IL_0013: cgt.un
.line 16707566,16707566 : 0,0 ''
IL_0015: nop
IL_0016: brfalse IL_0026
.line 16707566,16707566 : 0,0 ''
IL_001b: nop
IL_001c: ldarg.0
.line 20,20 : 7,14 ''
IL_001d: tail.
IL_001f: call object [IronScheme]IronScheme.Runtime.Builtins::Car(object)
IL_0024: ret
.line 16707566,16707566 : 0,0 ''
IL_0025: nop
IL_0026: ldsfld object
[Microsoft.Scripting]Microsoft.Scripting.RuntimeHelpers::False
IL_002b: ldstr "nooo"
IL_0030: ldarg.0
IL_0031: call object [IronScheme]IronScheme.Runtime.Builtins::List(object)
.line 22,22 : 7,40 ''
IL_0036: tail.
IL_0038: call object [ironscheme.boot]#::
'ironscheme.exceptions::assertion-violation+'(object,object,object)
IL_003d: ret
.line 16707566,16707566 : 0,0 ''
IL_003e: nop
} // end of method 'eval-core(033)'::'::baz'
Mise à jour 3:
Problème avec dessus de "semi-fix". Peverify rapports d'erreurs sur toutes les méthodes en raison de l' nop
après ret
. Je ne comprends pas le problème. Comment peut - nop
pause de vérification après un ret
. C'est comme du code mort (sauf qu'il n'est PAS même code) ... eh bien, l'expérimentation continue.
Mise à jour 4:
De retour à la maison maintenant, enlevé le "invérifiable" code, en cours d'exécution sur VS2008 et les choses sont bien pires. Peut-être l'exécution de code non vérifiable pour des raisons de débogage appropriés pourrait être la réponse. Dans "libération" mode, toutes les données de sortie serait toujours vérifiables.
Mise à jour 5:
J'ai maintenant décidé de mon idée ci-dessus est la seule option viable pour l'instant. Bien que le code généré est invérifiable, j'ai encore trouvé aucune VerificationException
'. Je ne sais pas quel sera l'impact sur l'utilisateur final avec ce scénario.
En bonus, ma deuxième question a également être résolus. :)
Voici une petite vidéo de démonstration de ce que j'ai. Il frappe des points d'arrêt, une bonne étape (in/out/), etc. Dans l'ensemble, l'effet désiré.
Cependant, je suis toujours pas accepter ce que la façon de le faire. Il se sentir trop hacky pour moi. Avoir une confirmation sur le vrai problème, ce serait bien.
Jour 6:
Juste eu le changement de tester le code sur VS2010, il semble y avoir quelques problèmes:
-
Le premier appel de ne pas marcher correctement. (affirmation de la violation ...) est atteint. Dans d'autres cas, des œuvres d'amende.Certains vieux code émis inutile positions. Enlevé le code fonctionne comme prévu. :) - Plus sérieusement, les points d'arrêt d'échouer sur la deuxième invocation du programme (à l'aide-mémoire de la compilation, de l'immersion de l'assemblée pour déposer semble faire des points d'arrêt encore heureux).
Ces deux cas fonctionner correctement sous VS2008. La principale différence est que, sous VS2010, l'ensemble de l'application est compilée .NET 4 et sous VS2008, compile .NET 2. Les deux cours d'exécution 64 bits.
Jour 7:
Comme mentionné, j'ai eu mdbg fonctionnant sous 64 bits. Malheureusement, c'est aussi avoir le point d'arrêt d'un problème où il ne parvient pas à percer si je exécutez à nouveau le programme (ce qui implique qu'il obtient recompilé, afin de ne pas utiliser le même montage, mais toujours en utilisant la même source).
Jour 8:
J'ai déposé un bug lors de la connexion MS site concernant le point d'arrêt de l'émission.
Mode coup de gueule
Espérons que ce n'est fixée par les états membres, à la différence des précédentes bugs que la réclamation est fixe, mais sont encore à être vu en public.
Coup de gueule de désactiver le mode