Domanda

Sto cercando di usare mtrace per rilevare perdite di memoria in un programma fortran. Sto usando il compilatore gfortran. Vedi la voce wikipedia per un esempio C di lavoro (funzionante) di mtrace: http://en.wikipedia.org/ wiki / Mtrace

Ho provato in entrambi i modi, ovvero avvolgendo mtrace () e muntrace () e chiamandoli dal programma fortran, oltre a creare un programma C che chiama direttamente mtrace () e muntrace (), oltre al codice fortran che perde nel mezzo. Entrambi gli approcci non riusciranno a rilevare la perdita di memoria, ma qui sto presentando solo quest'ultimo.

example.c

#include <stdlib.h>
#include <mcheck.h>

extern void leaky_();  // this might be different on your system
    // if it doesn't work, try to run:
    // 1) gfortran leaky.f90 -c
    // 2) nm leaky.o
    // and then change this declaration and its use below

void main() { 
    mtrace();
    leaky_();
    muntrace();
}

leaky.f90

subroutine leaky()
  real, allocatable, dimension(:) :: tmp
  integer :: error
  allocate (tmp(10), stat=error)
  if (error /= 0) then
    print*, "subroutine leaky could not allocate space for array tmp"
  endif
  tmp = 1
  !of course the actual code makes more...
  print*, ' subroutine leaky run '
  return
end subroutine leaky

Compilo con:

gfortran -g example.c leaky.f90

Quindi corro con:

export MALLOC_TRACE=`pwd`/raw.txt; ./a.out

Quindi analizzo l'output raw.txt mtrace con:

mtrace a.out raw.txt

e ottieni:

Nessuna perdita di memoria.

C'è qualcosa che sto facendo di sbagliato o qualcosa che posso fare per consentire a mtrace di trovare l'allocazione di memoria fortran che perde? Suppongo che gfortran stia usando una diversa chiamata malloc , che mtrace non traccia ... In effetti, come ho scritto sopra ottengo lo stesso risultato se scrivo un main fortran che chiamerebbe (wrapped) mtrace () e muntrace () .

EDITED: ho preso in considerazione altre opzioni (incluse alcune non ancora menzionate qui), ma il codice effettivo in fase di debug viene eseguito su P6 / AIX, quindi Valgrind sarebbe " solo " scomodo (deve funzionare su una macchina diversa), mentre Forcheck sarebbe scomodo (deve funzionare su una macchina diversa) e costoso (~ 3k $). Attualmente mtrace sarebbe la soluzione migliore, se funzionasse.

MODIFICATO di nuovo: La mia ipotesi

  

Suppongo che gfortran stia usando una diversa chiamata malloc , che mtrace non traccia ... ...

era corretto. Esaminando l'eseguibile (sia con nm o readelf ) non c'è alcuna chiamata malloc () , ma _gfortran_allocate_array quelli - che forse chiameranno malloc). Altre idee?

MODIFICATO di nuovo: Ho pubblicato la risposta ma non posso accettarla (vai a http: //stackoverflow.uservoice. com / pages / general / suggestions / 39426 e richiedi la funzione, è davvero necessaria - non è necessario guadagnare la reputazione)

È stato utile?

Soluzione 3

Steve Kargl ha avuto la risposta, che brevemente è che mtrace non trova alcuna perdita, perché non c'è alcuna perdita se il compilatore è conforme allo standard: Vedi http://gcc.gnu.org/ml/fortran/2008-11/msg00163.html per i dettagli.

In realtà non sono un grande esperto di fortran (sono principalmente C / C ++ / java guy) e stavo anche usando un altro compilatore, che perde in una tale condizione (non ho detto che per mantenere la domanda più semplice). Quindi ho erroneamente pensato che la perdita fosse presente anche con gfortran, il che non è il caso (ho controllato con la parte superiore)

Altri suggerimenti

Non sono un esperto di mtrace, quindi non posso fare a meno. Suggerirei di provare lo strumento valgrind per trovare perdite di memoria se si utilizza un sistema supportato. Usare valgrind per trovare perdite di memoria è semplice come chiamare valgrind --leak-check = full ./a.out .

Valgrind è solo Linux. Per un prodotto Windows, guarda Forcheck. http://www.forcheck.nl/features.htm

Ho esperienza con il debug dei programmi Fortran ma ad essere sincero non sono riuscito a capire davvero la tua domanda. Penso che sia perché non ho molta esperienza di debug in C / C ++ diversa da Fortran. Tuttavia, penso che questo ti gioverà:

L'uso del compilatore Intel con le seguenti opzioni di compilazione rileverà quasi ogni perdita di memoria, accesso errato all'indirizzo o utilizzo di puntatori / variabili non inizializzati durante il runtime.

Intel: -O0 -debug -traceback -check -ftrapuv

Anche per Gfortran è possibile ottenere praticamente tutti gli errori sopra descritti con queste opzioni del compilatore.

gfortran: -g -O0 -fbounds-check -Wuninitialized

Stampa il traceback delle chiamate della subroutine fino a quando si verifica l'errore. È sempre utile compilare con due diversi compilatori e nella mia esperienza non avrai quasi nessuna perdita di memoria dopo questo.

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