Si (false == true) exécute le bloc lorsque la levée d'une exception est à l'intérieur

152

J'ai un problème assez étrange qui se produit.

Voici mon code:

private async Task BreakExpectedLogic()
{
    bool test = false;
    if (test == true)
    {
        Console.WriteLine("Hello!");
        throw new Exception("BAD HASH!");
    }
}

Cela semble vraiment simple, il ne devrait pas toucher le Console.WriteLineou le throw. Pour une raison quelconque, il frappe toujours le throw.

Si je déplace le throwdans sa propre méthode, cela fonctionne bien. Ma question est de savoir comment ignorer le ifbloc et frapper le throw new Exception:

Voici quelques preuves

EDIT 1: J'ai mis à jour mon code pour inclure la signature, j'ai supprimé tout ce qui n'est pas lié à ce problème et l'ai exécuté, cela se produit toujours.

George
la source
5
@TimSchmelter l'image est-elle en cours de débogage, la surbrillance jaune est l'endroit où se trouve le code
George
5
Je viens de créer une application de console de base vierge, collé juste votre code dans Mainet .... surprise, norepro. Soit vous vous trompez, soit vous avez manqué un détail important.
Jamiec
16
Est-ce une asyncméthode par hasard? Parce qu'il semble similaire à stackoverflow.com/questions/42528458/...
Matthew Watson
7
@George: toujours aucune preuve car vous pourriez utiliser d'anciens symboles de débogage. Recompilez en mode débogage puis recommencez.
Tim Schmelter
4
@TimSchmelter J'ai recompilé, nettoyé, rouvert le projet, essayé différentes façons de faire le if, mais toujours la même chose
George

Réponses:

176

Cela semble être le bogue de la asyncméthode, le code n'est pas réellement exécuté mais le débogueur passe à la ligne avec throwinstruction. S'il existe des lignes de code avant que l' throwinstruction à l'intérieur de ifces lignes ne soit ignorée, le débogueur effectue uniquement des étapes jusqu'à la ligne contenant l' throwinstruction.

De plus, si vous n'utilisez pas de variable - if (false)ou if (true == false)alors les étapes du débogueur vers la ligne de code correcte - vers l'accolade fermante.

Ce bogue a été publié par @Matthew Watson dans l'équipe Visual Studio (le lien n'est pas disponible pour le moment).

Voir également la question similaire - Vérification des conditions dans la méthode asynchrone

EDIT (2017/10/06):

Le problème ne peut pas être reproduit dans VS 2017 15.3.5 à l'aide de .Net Framework 4.7. On dirait que l'équipe VS a résolu ce problème.

Roman Doskoch
la source
20
Merci, sans savoir que c'est un bogue dans le débogueur, je serais probablement devenu fou.
George
121
Un bug dans le débogueur? Comment très méta. :) (chantant je n'ai jamais rencontré de bug comme ça avant ... )
Simba
3
@George J'espère que cela ne vous dérange pas, j'ai pris votre échantillon et créé une application console en l'utilisant, et je l'ai attaché au problème VS auquel Roma a lié.
Obsidian Phoenix
5
@Simba: Dites-moi que vous n'avez jamais utilisé de débogueur pour se déboguer.
Joshua
3
Hmm. Il semble que le bogue pourrait être dans les informations de débogage générées par le compilateur plutôt que dans le débogueur lui-même. J'attendrai que MS reconnaisse le bogue Connect avant de voter pour ou contre.
Adrian McCarthy
10

Juste un addendum à la réponse, j'ai récemment rencontré le même problème et j'ai regardé le code x86 réel dans le débogueur, et il a été généré d'une manière étrange comme celle-ci (simplifiée):

// if (...) {
0001: jne 0006
...
0006: jmp 0007
// }
0007: ret

Donc, au lieu de sauter directement aux dernières instructions de la méthode, il fait un double saut, où je crois que le deuxième saut inconditionnel est reconnu à tort comme faisant partie du code à l'intérieur du ifbloc.

Je suppose donc que ce bogue pourrait être lié au compilateur JIT.

Serge Semenov
la source