Domanda

Ho provato a rintracciare un bug incidente intermittente nel mio codice (che utilizza setjmp) e lo ho ristretto a: si presenta quando si compila con /o2, va via con /o2 /oy-, cioè si presenta solo con ometti Puntatore del telaio.

http://msdn.microsoft.com/en-us/library/2kxx5t2c(v=vs.80).aspx Suggerisce che setJMP richiede un puntatore del frame. Così:

  1. Sembra che quando un programma che utilizza setJMP viene compilato con /o2, Visual C ++ genera un codice che provoca corruzione di stack intermittente. È vero o mi manca qualcosa?

  2. Mi sembra che solo la funzione che invoca setJMP debba essere compilata con il puntatore del frame, il resto del programma - anche le funzioni che chiamano LongJMP - dovrebbero andare bene per omettere il puntatore del frame. È vero?

Modificare: L'ho ridotto un po 'di più.

Abilitare il puntatore del frame sulla funzione che chiamava setjmp non ha fatto alcuna differenza, ma è perché il compilatore lo stava già facendo, proprio come dovrebbe, ovviamente notando che doveva essere fatto e farlo automaticamente.

Ciò che ha fatto la differenza è stato abilitare il puntatore del telaio sul principale. Non è così bizzarro come sembra, poiché l'incidente si stava manifestando in cambio da Main. Ora che ci penso, tutti gli esempi che riesco a trovare in una rapida ricerca su Google dell'utilizzo di SetJMP, fallo in main. Forse è successo che il team del compilatore Microsoft lo abbia solo testato in questo modo.

Essendo il modo idiomatico di usarlo, forse la soluzione migliore sarebbe per me semplicemente in linea la funzione di uso del setjmp in Main.

È stato utile?

Soluzione

Ok, ho pubblicato un report di bug con un caso di test autonomo, quindi spero che una correzione sia nella pipeline: http://connect.microsoft.com/visualstudio/feedback/details/666704/visual-c-generates-incerrect-code-with-omit-frame-pointer-and-setjmp

Nel frattempo, la soluzione alternativa non utilizza il puntatore del frame omesso o inserire il codice che chiama setJmp in main o inserisci la funzione che chiama longjmp nello stesso file di origine della chiamata per setJMP.

Altri suggerimenti

Puoi per favore specificare maggiori informazioni sull'arresto anomalo stesso? Voglio dire, quale codice il compilatore generato per il longjmp, si verifica l'incidente immediatamente dopo il longjmp, o quando si tenta di accedere alle variabili automatiche o quando si tenta di uscire dalla funzione?

Immagino che il obbiettivo La funzione deve essere compilata con il telaio stack standard, non sembra esserci alcuna ragionevole limitazione alla funzione che usa longjmp.

SETJMP è implementato in molti modi diversi, ma questo probabilmente ha qualcosa a che fare con l'implementazione dell'assembly per il tuo particolare sistema operativo.

Quando una funzione viene compilata usando __stdcall, gli argomenti vengono archiviati rispetto al puntatore del frame. L'implementazione potrebbe accedere agli argomenti a SetJMP rispetto a detto puntatore in modo da non dover trasmettere più registri che li salvano il contesto (poiché ciò rovinerebbe gran parte del punto di setJMP); Mi sembra di ricordare che SetJMP sia implementato in questo modo nel kernel Linux.

Naturalmente se MSVC non genera istruzioni per impostare EBP, questo non funzionerà e sicuramente causerà un incidente.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top