Se (false == true) executar o bloco quando a exceção de lançamento estiver dentro

152

Eu tenho um problema bastante estranho que está ocorrendo.

Este é o meu código:

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

Parece realmente simples, não deve atingir o Console.WriteLineou o throw. Por alguma razão, está sempre atingindo o throw.

Se eu mover o throwmétodo para seu próprio método, ele funcionará bem. Minha pergunta é como ele está ignorando o ifbloco e atingindo o throw new Exception:

Aqui estão algumas evidências

EDIÇÃO 1: atualizei meu código para incluir a assinatura, removi tudo que não estava relacionado a esse problema e o executei, ainda acontece.

George
fonte
5
@TimSchmelter a imagem está sendo depurado, o destaque amarelo é onde o código está em
George
5
Acabei de criar um aplicativo de console central em branco, colei apenas seu código no Maine .... surpresa, norepro. Ou você está enganado ou perdeu alguns detalhes importantes.
Jamiec
16
Isso está em um asyncmétodo por acaso? Porque parece semelhante a stackoverflow.com/questions/42528458/…
Matthew Watson
7
@ George: ainda não há evidências, porque você pode usar símbolos de depuração antigos. Recompile no modo de depuração e inicie novamente.
Tim Schmelter
4
@TimSchmelter eu recompilados, limpo, reabriu o projecto tentou maneiras diferentes de fazer o caso, mas ainda o mesmo
George

Respostas:

176

Parece ser o erro no asyncmétodo, o código não é realmente executado, mas o depurador avança para a linha com a throwinstrução Se houver algumas linhas de código antes que a throwinstrução dentro ifdessas linhas seja ignorada, o depurador passará apenas para a linha comthrow instrução

Além disso, se você não usar variável - if (false)ouif (true == false) etapas do depurador para a linha de código correta - para a chave de fechamento.

Este bug foi publicado por @Matthew Watson na equipe do Visual Studio (o link não está disponível agora).

Consulte também perguntas semelhantes - Verificação de condição no método assíncrono

EDIT (06/10/2017):

O problema não pode ser reproduzido no VS 2017 15.3.5 usando o .Net Framework 4.7. Parece que a equipe do VS corrigiu esse problema.

Roman Doskoch
fonte
20
Obrigado, sem saber que isso é um bug no depurador, eu provavelmente ficaria louco.
George
121
Um bug no depurador? Que meta! :) (cantando Eu nunca meta bug como isso antes ... )
Simba
3
@ George Espero que você não se importe, eu peguei sua amostra e criei um aplicativo de console usando-o e anexei-o ao problema do VS ao qual Roma se vinculou.
Obsidian Phoenix
5
@ Simba: Diga-me que você nunca usou um depurador para depurar a si próprio.
Joshua
3
Hmm. Parece que o erro pode estar nas informações de depuração geradas pelo compilador, e não no próprio depurador. Esperarei que a Microsoft reconheça o bug do Connect antes de votar para cima ou para baixo.
Adrian McCarthy
10

Apenas um adendo à resposta, encontrei recentemente o mesmo problema e olhei o código x86 real no depurador, e ele foi gerado de uma maneira estranha como esta (simplificada):

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

Então, em vez de pular diretamente para as últimas instruções do método, ele dá um pulo duplo, onde acredito que o segundo pulo incondicional é erroneamente reconhecido como parte do código interno if bloco.

Então, eu especularia que esse bug possa estar relacionado ao compilador JIT.

Serge Semenov
fonte