2014-12-03 16 views
8

Sono in C# per un periodo piuttosto lungo, ma non ho mai avuto questo tipo di errore. Prima di tutto, vedi qualcosa di sbagliato (possibilmente sbagliato) su questo singolo blocco di codice (a parte la logica ovviamente, so che restituisce sempre 0)?AccessViolationException gettato in strana situazione

public static int GetDecimals(MySimpleEnum val) 
    { 
     int result = 0; 
     switch (val) 
     { 
      case MySimpleEnum.Base: 
      case MySimpleEnum.Slow: 
      case MySimpleEnum.Normal: 
      case MySimpleEnum.Quick: 
      case MySimpleEnum.Fastest: 
       result = 0; 
       break; 
     }    
     return result;   
    } 

impostazioni del progetto di uscita: DEBUG costante = false; Costante TRACE = true; Ottimizza codice = true; Informazioni su uscita/avanzato/debug = nessuna;

IIS = versione 7,5

Questo metodo, avendo impostazioni specificate rilascio getta "System.AccessViolationException:. Ha tentato di leggere o scrivere memoria protetta Questo è spesso un'indicazione che l'altra memoria è corrotta."

Ed ecco la parte divertente. Questi sono casi in cui non genera questa eccezione:

  1. Eseguirlo su IIS (Express e non-Express) 8.5 (non è necessaria alcuna modifica del progetto).
  2. Set Optimize code = false; e Output/Avanzate/Debug info = false;
  3. Wrapp il metodo all'interno per try/catch block (provato anche registrare l'eccezione utilizzando log4net nel blocco catch - log vuoto)
  4. Sostituire il metodo interno con un codice diverso.

cose da notare:

  • L'eccezione doveva essere catturato utilizzando debugger vittoria sul server (nessun gestore eccezioni regolare NET è stato chiamato)
  • crash dell'applicazione dopo l'eccezione.
  • Questo blocco di codice funzionava diversi mesi fa (nessuna versione per un lungo periodo). L'errore è iniziato probabilmente con qualche aggiornamento.
  • Testato su due server diversi con IIS 7.5 e un computer con IIS 8.5 e IIS Express (VS2012). Stessi risultati
  • Ho provato molte combinazioni diverse di impostazioni di progetto. Fondamentalmente se non imposto le impostazioni come al punto 2., lancia l'eccezione su IIS 7.5.
  • Il mio sistema operativo (e di compilazione) esegue Windows 8.1 con gli ultimi aggiornamenti.
  • Il blocco di codice si trova in un progetto separato (libreria di classi).

So come risolvere questo problema. Ma non mi piacciono i problemi di chiusura, pur non conoscendo la causa. Inoltre, voglio evitare questo in futuro. Pensi che potresti aiutarmi con quello? Se si tratta di un'eccezione di riferimento null, perché sta succedendo? E perché è specifico del debug/release specifico o di IIS?

* Note2:

Recentemente ho avuto un problema con mancanti (System.Net.Http.Formatting.dll, System.Web.Http.dll, System.Web.Http.WebHost.dll) mentre il dll pubblicazione. Era a causa di alcuni aggiornamenti di sicurezza Microsoft. Forse questo è qualcosa di simile.*

Modifica 1 Aggiunta della struttura della dichiarazione enum.

public enum MySimpleEnum 
    { 
     Base = 0, 
     Slow = 1, 
     Normal = 2, 
     Quick = 3, 
     Fastest = 4 
    } 

Inoltre, ho appena provato ad aggiungere [MethodImpl (MethodImplOptions.NoInlining)], ma nessun aiuto.

+0

Mi chiedo se l'arresto anomalo si verifica quando il metodo è in linea .. provare a contrassegnarlo '[MethodImpl (MethodImplOptions.NoInlining)]'? – Blorgbeard

+0

solo per curiosità puoi mostrare la firma/la struttura del tuo Enum ..? – MethodMan

+0

Penso che avremo bisogno di vedere il contesto in cui viene chiamata la funzione! – Phill

risposta

3

È atipico avere questi tipi di errori di violazione di accesso dal codice gestito. Provengono dalla corruzione della memoria che può indicare l'hardware difettoso - in casi estremamente rari questo indica un bug nel CLR stesso.

La causa più probabile di questo tipo di errore proviene da altrove, ad es. se questo codice utilizza in qualche modo il codice nativo - chiamando nel codice nativo in un contesto non sicuro o chiamando dal codice nativo.

Per citare MSDN AccessViolationException:

Nei programmi composti interamente di codice verificabile gestito, tutti i riferimenti sono o valido o nullo, e le violazioni di accesso sono impossibili. Un'eccezione AccessViolationException si verifica solo quando il codice gestito verificabile interagisce con codice non gestito o con codice gestito non sicuro.

In ogni caso, in genere è necessario cercare altrove nel codice per trovare il codice errato che corrompe la memoria. Sfortunatamente questo è un problema abbastanza difficile da risolvere. In bocca al lupo!

0

Non sono sicuro che sia ancora rilevante per te ma sono riuscito a generare questo errore di AccessViolation semplicemente cambiando un bool molto piccolo e insignificante in una sezione di codice completamente gestita. La parte migliore tuttavia, se disattivo l'ottimizzazione del codice nel compilatore per quel sottoprogetto, tutto gira bene. Sembra essere un errore introdotto dal compilatore in un tipo molto specifico di situazione che non ha bisogno di dare alcun senso logico.

Problemi correlati