Utilizzo di file di origine identici per un dll di Fortran Posso compilarli con Compaq Visual Fortran 6.6C o Intel Visual Fortran 12.1.3.300 (IA-32). Il problema è che l'esecuzione fallisce sul binario Intel, ma funziona bene con Compaq. Sto compilando 32-bit su un sistema Windows 7 64-bit. Il driver di chiamata .dll è scritto in C#
.Overflow dello stack sulla chiamata di subroutine solo quando compilato con Intel Visual Fortran e corretto quando Compaq Visual Fortran è compilato
Il messaggio di errore deriva dalla temuta chiamata _chkstk()
quando viene chiamata una subroutine interna (chiamata dalla routine di immissione .dll). (SO rispondere su chkstk()
)
La procedura in questione viene dichiarato come (pardon il formato di file fisso)
SUBROUTINE SRF(den, crpm, icrpm, inose, qeff, rev,
& qqmax, lvtyp1, lvtyp2, avespd, fridry, luin,
& luout, lurtpo, ludiag, ndiag, n, nzdepth,
& unit, unito, ier)
INTEGER*4 lvtyp1, lvtyp2, luin, luout, lurtpo, ludiag, ndiag, n,
& ncp, inose, icrpm, ier, nzdepth
REAL*8 den, crpm, qeff, rev, qqmax, avespd, fridry
CHARACTER*2 unit, unito
e chiamato in questo modo:
CALL SRF(den, crpm(i), i, inose, qeff(i), rev(i),
& qqmax(i), lvtyp1, lvtyp2, avespd, fridry,
& luin, luout, lurtpo, ludiag, ndiag, n, nzdepth,
& unit, unito, ier)
con le specifiche variabili simili tranne che per crpm
, qeff
, rev
e qqmax
sono matrici di cui solo gli elementi i-th
vengono utilizzati per ogni chiamata SRF()
.
Capisco possibili problemi di stack se gli argomenti sono più di 8kb
dimensioni, ma in questo caso abbiamo 7 x real(64) + 11 x int(32) + 2 x 2 x char(8) = 832 bits
solo in argomenti passati.
ho lavorato duramente per spostare argomenti (specialmente array) in un modulo, ma io continuo a ricevere lo stesso errore
.
Il dissasembly dal Intel .dll è
Il dissasembly dal Compaq .dll è
Qualcuno può offrire qualche suggerimento su ciò che è causando la SO, o come eseguirne il debug?
PS. Ho aumentato lo spazio di stack riservato a centinaia di Mb
e il problema persiste. Ho provato a saltare la chiamata chkstk()
nel dissasembler ma in crash il programma. Il controllo dello stack inizia dall'indirizzo 0x354000
e scorre fino a 0x2D2000
dove si blocca durante l'accesso a una pagina di guardia. L'indirizzo inferiore dello stack è 0x282000
.
Quali opzioni del compilatore utilizzate in ciascun caso? Prova a compilare tutti i flag di errore di avviso che puoi pensare attivati. Come primo passo tendo ad usare '-std -check all -Warn all, nodec, interfacce, dichiarazioni -gen_interfaces -g -C -traceback -fpe0 -fp-stack-check' con ifort. – Chris
Mi aspetto che tu abbia individuato il tuo errore aritmetico, ma il tuo totale di 832 byte dovrebbe essere 832 bit. Non è sempre il caso, inoltre, che ogni carattere sia rappresentato da un byte: questo tende a variare con il compilatore e la piattaforma. Con un compilatore aggiornato, le dimensioni delle varie "unità di memoria" sono disponibili come costanti definite nel modulo intrinseco ISO_FORTRAN_ENV. –
Entrambi i commenti sopra mi danno qualcosa su cui lavorare. Investigherò di più. È possibile che si verifichi un danneggiamento dello stack che 'CVF' non sta catturando e in qualche modo ci soffia sopra. Nel codice c'è molto da fare visto che molti sviluppatori l'hanno toccato dagli anni '80 quando è stato scritto per la prima volta. – ja72