[tovabblepve] Fortran 95 ASSOCIATED (pointer) SIGSEGV

UPDATE:
Gfortran 4.3.2 + intel MKL 10.2.5 + fftw3
kombinacioban lefutott.
Koszonom a segitseget.

Hali,
van egy programom (cp2k), amit intel fortan 11.1 forditoval forditva elesik SIGSEGV hibaval.A call trace:


forrtl: severe (174): SIGSEGV, segmentation fault occurred
Image              PC                Routine            Line        Source      
cp2k.sopt          0000000001EDC686  Unknown               Unknown  Unknown
cp2k.sopt          0000000001BF8900  Unknown               Unknown  Unknown
[...]

Ez egy -O0 forditas. Linkeles kozben keszitettem mapfilet, es az alapjan ugy nez ki, hogy a kovetkezo
kodban esik el:


  FUNCTION dbcsr_buffers_valid (buffers) RESULT (valid)
    TYPE(dbcsr_block_buffer_obj), INTENT(IN) :: buffers
    LOGICAL                                  :: valid

    valid = ASSOCIATED (buffers%b)
  END FUNCTION dbcsr_buffers_valid

A dbcsr_block_buffer_obj definicioja:


  TYPE dbcsr_block_buffer_obj
     TYPE(dbcsr_block_buffer_type), POINTER :: b
  END TYPE dbcsr_block_buffer_obj

a problema az, hogy nem ertek fortranul.
A kerdes meg az, hogy milyen esetekben adhat ez SIGSEGV -t.
A keres meg az, hogy ne adjon, ugye :-)

Olyan mellekeredmenyeknek is orulnek, hogy a call trace ne "Unknown" feliratot adjon, hanem ertelmeset. ezugyben ott van a "-g -O0" a forditasnal.

Hozzászólások

Hát én se értek fortranul, de így ránézésre az a "buffers%b" cucc NULL pointer-nek túnik.

Szerk.:

Próbáld ki(ugyan ezt fortranra lefordítva):
if(buffers.b != NULL) return *(buffers.b);
else return FAKE;

Ihol egy listing (objdump -D) a problemas fuggvenyrol


000000000000221a <dbcsr_block_buffers_mp_dbcsr_buffers_valid_>:
    221a:       55                      push   %rbp
    221b:       48 89 e5                mov    %rsp,%rbp
    221e:       48 83 ec 20             sub    $0x20,%rsp
    2222:       48 89 7d e0             mov    %rdi,-0x20(%rbp)
    2226:       48 8b 45 e0             mov    -0x20(%rbp),%rax
    222a:       48 8b 00                mov    (%rax),%rax
    222d:       48 85 c0                test   %rax,%rax
    2230:       75 0a                   jne    223c <dbcsr_block_buffers_mp_dbcsr_buffers_valid_+0x22>
    2232:       48 c7 45 e8 00 00 00    movq   $0x0,-0x18(%rbp)
    2239:       00 
    223a:       eb 08                   jmp    2244 <dbcsr_block_buffers_mp_dbcsr_buffers_valid_+0x2a>
    223c:       48 c7 45 e8 ff ff ff    movq   $0xffffffffffffffff,-0x18(%rbp)
    2243:       ff 
    2244:       48 8b 45 e8             mov    -0x18(%rbp),%rax
    2248:       89 45 f0                mov    %eax,-0x10(%rbp)
    224b:       8b 45 f0                mov    -0x10(%rbp),%eax
    224e:       c9                      leaveq 
    224f:       c3                      retq   

A 222a cimu mov (%rax),%rax utasitason esik.
Sebaj, x86-64 assemblerul sem tudok;)

Ha az assembler minden vágyad, elmondhatom mit látok bele:

221a : beolvassa a paramétert a stack-ről
221b-2226 : Megkeresi a pointert
222a : Feloldja a pointert
222d- valami elágazás féle
2244- gondolom a visszatérési értékkel bíbelődik

Mindez a lényegen nem változtat:
1,hibás pointert kap a függvény
2,nem úszod meg a fortrant, ha ezt ki akarod javítani.

A *di regiszter (által hivatkozott memóriaterület) a ludas, a hivatkozott terület zárolt ( - de nem feltétlen triviálisan 0 az értéke - ) a procedúra kódrészlet előtt. De erre más is rájött, dongolom én, van még bővebb objdump arról, hogy kideríthesd, mi rdi értéke? (És hogy melyik függvény rontja el)?

Szerk.

Szerk.2. közben látom, miből lesz a cserebogár, de már írták, buffers%b nem asszociált memóriahivatkozás lesz. De nem tudok fortranul.

http://hup.hu/taxonomy/term/209
http://www.youtube.com/watch?v=QXz7-BNC6jw
http://nocirc.org/

kis dokisolvasgatas utan ugy tunik, hogy ebben a nyelben a pointer a nyelv alapjan egy elegge vedett tipus, megjegyzi, hogy hozza-lett-e rendelve valamihez vagy sem. Ennelfogva az ASSOCIATED builtin hasznalhato, mley szerint ezzel a statusszal ter vissza. Ez minosegileg mas, mint a C style pointer. Mondjuk ugy lehet elkepzelni, hogy egy kis struktura, amiben van foglaltsagjelszo mezo a valodi cimen kivul.

Ha ez az olvasata a doksinak igaz, akkor nem eshet el itt es ekkor a progi. De elesik, ami vagy memoriaszemeteles, vagy pedig valami limit (tipikusan a stack) elhaznalodasa. Ez utobbit ki tudom tesztelni.

Kicsit zavaros az assembly kód is. A rax-ot miért másolja a "(rax)"-ra? Mert ugye a "mov" jobbról balra másol.
Úgy olvastam a pointer feloldás [] zárójel. Akkor ez mi?
De ami a legfurcsább hogy a rax-ot miért hasonlítja össze saját magával utána?

Lehet mégsem vágom annyira ezt a nyelvet.

No igen, ez megmagyaráz egy-két dolgot. :)

Még forrás:
http://www.nasm.us/links/unix64abi

%rdi used to pass 1st argument to functions

Tehát a függvény első paraméterét bemásolja a stack-re, majd feloldja a pointert, és a hozzá tartozó értéket összeveti saját magával, és ha egyezik őnmagával, akkor bemásol egy 0-át a stack-re. Aha, minden világos :S

Rosszul értelmezed. Az összehasonlítja magával rész egyszerű nem-nulla feltétel.
Bár ezt assemblyben nem így szokás, hanem az olvashatóbb nem-zero:

or %eax, %eax
jnz nemnulla
...
nemnulla:

Egyébként meg ez a kód mindenképp elvérzik.
222a: nem lett leellenőrizve, hogy a paraméter érvényes cím-e.
2232 és 223c: ha a paraméter által mutatott dword 0, a pointer 0 egyébként -1 lesz
2244: akár 0, akár -1, a pointer feloldása mindenképp bukta.
Kb ez a fenti kód C-ben:

if(*arg) ptr=-1; else ptr=0;
a=*ptr;

Ma már kvázi mindegy, ez igaz. De régen, órajelínséges időkben intrókódolásnál még számítottak az ilyesfajta (méret|sebesség|biztonság|hordozhatóság)(növelő|csökkentő) trükkök.

http://hup.hu/taxonomy/term/209
http://www.youtube.com/watch?v=QXz7-BNC6jw
http://nocirc.org/

szerintem fortranban nem jellemzo a segfault, ugyhogy valoszinuleg kulso hiba

--
NetBSD - Simplicity is prerequisite for reliability

-debug all fordítás és az idb (intel debugger) mit mond?

btw első körben 10.1-es fordítóval próbálnám, az intel fordítók nem mindig hibamentesek

nocsak.

Azota van hasznalhato MPI build (gfortran+mpich2)

egy regebbi feladatnal (cfour) a Szalai Peter sajat ifort 10-es forditasa fut, a ifort 11.1 -gyel az egyik modul crashel. Azok a modulok viszont, amik nem esnek, azok cca 20%-25% -kal gyorsabbak ifort 11.1 -gyel.

Es mennyire mukodik az, hogy regabbi forditoval hasznalom az ujabb MKL-t? Merthogy minden fordito kiadasnal jon vele egy MKL is.