domingo, 10 de março de 2013

Se eu soubesse antes... 2

Um pequeno complemento no texto anterior. O programa chamado "errado" roda sem problemas aparentes se não é usada a opção -fbounds-check (ou -fcheck=bounds na versão mais atualizada).
program errado
implicit none
integer,dimension(:),allocatable :: a
integer :: b
allocate(a(10))
b = a(11)
endprogram errado
Usando o Valgrind (mais especificamente, a ferramenta MemCheck), aparece o seguinte aviso:
==5433== Invalid read of size 4
==5433==    at 0x4008F2: MAIN__ (errado.f03:6)
==5433==    by 0x40094A: main (errado.f03:7)

Rodando um segundo programa, que eu fiz pra continuar testando como se encontrar os erros, encontrei o seguinte:
program errado2

integer,parameter :: kr = 8
integer,dimension(6) :: r
real(kr),dimension(:),allocatable :: a,b
integer :: i,j

allocate(a(10),b(10))

b = (/ (real(i,kr),i=1,10) /)

do i=1,10
 r = (/ (i+j,j=1,6) /)
 write(*,'(6ES13.3E3)')a(r)
enddo

do i=1,10
 r = (/ (i+j,j=1,6) /)
 write(*,'(6ES13.3E3)')b(r)
enddo

write(*,*)'Fim'
endprogram errado2

$ valgrind --track-origins=yes ./errado2
*** algumas linhas cortadas ***
==5672== Conditional jump or move depends on uninitialised value(s)
==5672==    at 0x4F0FF57: ??? (in /usr/lib/x86_64-linux-gnu/libgfortran.so.3.0.0)
==5672==    by 0x4F10BC6: ??? (in /usr/lib/x86_64-linux-gnu/libgfortran.so.3.0.0)
==5672==    by 0x4F11D80: ??? (in /usr/lib/x86_64-linux-gnu/libgfortran.so.3.0.0)
==5672==    by 0x4F0AC25: ??? (in /usr/lib/x86_64-linux-gnu/libgfortran.so.3.0.0)
==5672==    by 0x4F08F72: _gfortran_transfer_array (in /usr/lib/x86_64-linux-gnu/libgfortran.so.3.0.0)
==5672==    by 0x400E8F: MAIN__ (errado2.f03:15)
==5672==    by 0x40118F: main (errado2.f03:24)
==5672==  Uninitialised value was created by a heap allocation
==5672==    at 0x4C28B8C: malloc (vg_replace_malloc.c:270)
==5672==    by 0x400AD7: MAIN__ (errado2.f03:9)
==5672==    by 0x40118F: main (errado2.f03:24)
==5672== 
==5672== Syscall param write(buf) points to uninitialised byte(s)
==5672==    at 0x58E0AF0: __write_nocancel (syscall-template.S:82)
==5672==    by 0x4F0E0BC: ??? (in /usr/lib/x86_64-linux-gnu/libgfortran.so.3.0.0)
==5672==    by 0x4F145EE: ??? (in /usr/lib/x86_64-linux-gnu/libgfortran.so.3.0.0)
==5672==    by 0x4F09B76: ??? (in /usr/lib/x86_64-linux-gnu/libgfortran.so.3.0.0)
==5672==    by 0x4F0A458: _gfortran_st_write_done (in /usr/lib/x86_64-linux-gnu/libgfortran.so.3.0.0)
==5672==    by 0x400E9E: MAIN__ (errado2.f03:15)
==5672==    by 0x40118F: main (errado2.f03:24)
*** mais algumas linhas cortadas ***
A opção --track-origins=yes mostra as informações em Unitialised value was created by a heap allocation ... As linhas que apontam onde está o erro (dessas que eu colei acima) são as seguintes:
==5672==    by 0x400E8F: MAIN__ (errado2.f03:15)
==5672==    by 0x400AD7: MAIN__ (errado2.f03:9)
==5672==    by 0x400E9E: MAIN__ (errado2.f03:15)
Nota-se que a linha 9 é onde a variável é alocada, e esse local é apontado onde diz como o valor não inicializado foi criado.

Nenhum comentário:

Postar um comentário