2014-12-18 21 views
30

Dato questo gioiello di codice:Debugger entrare in se() blocco in cui la condizione è falsa

class Program 
{ 
    private static bool IsAdmin = true; 

    static void Main(string[] args) 
    { 
     if (!IsAdmin) 
     { 
      throw new Exception(); 
     } 

     try 
     { 
      var x = 2342342; 
      var y = 123132; 
     } 
     catch (Exception) 
     { 
      throw; 
     } 
    } 
} 

Data la this.IsAdmin cede vero - mi aspetterei il debugger di non entrare in quel if. In realtà lo fa - e supera il tiro ma in realtà non lancia!

Ora questo accade solo quando si ha un'eccezione all'interno di un'istruzione if seguita da un blocco try/catch, in Visual Studio 2013, con targeting .NET Framework 4, 64 bit, "Prefer 32 bit" deselezionato.

Ho confermato questa stranezza con i colleghi su macchine diverse. Passo anche se il codice seguente e il debugger vi sembrerà di entrare nel caso ramo, ma non viene generata un'eccezione:

enter image description here

Sono in modalità debug, ho provato la compilazione e la pulizia il progetto più volte.

Qualcuno può spiegare perché questo sta accadendo?

+0

Nice find, il debuger fa tutto pazzo per IL IL, probabilmente il pre-ottimizzazione della variabile di ottimizzazione o qualcosa del genere – BhavO

risposta

29

Questo è un problema noto causato dal jitter x64, occasionalmente genera informazioni errate sul numero di riga di debug. Può armeggiare quando un'istruzione provoca la generazione di istruzioni NOP aggiuntive, intese ad allineare il codice. Il primo NOP diventa il numero di riga, anziché le istruzioni dopo i NOP. Questo byte in pochi punti, come una dichiarazione di lancio dopo un semplice test (se) e l'uso del ?? operatore con semplici operandi scalari. Questi NOP di allineamento sono anche la ragione per cui è così pericoloso interrompere i thread, descritto in this post.

La soluzione più semplice è Project + Properties, scheda Build, selezionare l'opzione "Prefer 32-bit" se disponibile, altrimenti impostare il target della piattaforma su x86. Nota come nulla vada veramente storto, mentre il debugger suggerisce che l'istruzione throw verrà eseguita il tuo programma in realtà non lancia un'eccezione.

È in corso di elaborazione, il jitter x64 è stato drasticamente riscritto, un progetto denominato RyuJIT. Spedirà in VS2015, attualmente in anteprima.

+0

Grazie - l'unico problema era che ho passato così tanto tempo a cercare di capire dove fosse il mio codice - non pensi che la roba della MS sarebbe il colpevole! – iwayneo

+0

RuyJIT-> RyuJIT? – StriplingWarrior

+4

Grazie. Che diamine stavano pensando. –

Problemi correlati