2008-11-03 30 views
5

Tôi đang cố gắng sử dụng mtrace để phát hiện rò rỉ bộ nhớ trong chương trình fortran. Tôi đang sử dụng trình biên dịch gfortran. Xem mục nhập wikipedia cho ví dụ C (ví dụ) của mtrace: http://en.wikipedia.org/wiki/Mtracemtrace cho chương trình fortran

Tôi đã thử cả hai cách, tức là gói mtrace() và muntrace() và gọi chúng từ chương trình fortran, cũng như tạo chương trình C trực tiếp gọi hàm mtrace() và muntrace(), bên cạnh mã fortran bị rò rỉ ở giữa. Cả hai cách tiếp cận sẽ không phát hiện rò rỉ bộ nhớ, nhưng ở đây tôi chỉ trình bày sau.

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 

tôi biên dịch với:

gfortran -g example.c leaky.f90 

Sau đó, tôi chạy với:

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

Sau đó, tôi phân tích đầu ra raw.txtmtrace với:

mtrace a.out raw.txt 

và nhận được:

Không rò rỉ bộ nhớ.

Có điều gì tôi đang làm sai hay điều gì đó tôi có thể thực hiện để cho phép mtrace tìm phân bổ bộ nhớ fortran bị rò rỉ? Tôi đoán gfortran đang sử dụng một cuộc gọi malloc khác, trong đó mtrace không theo dõi ... Trong thực tế, như tôi đã viết ở trên tôi nhận được kết quả tương tự nếu tôi viết một fortran chính mà sẽ gọi (bọc) mtrace()muntrace(). CHỈNH SỬA: Tôi đã xem xét các tùy chọn khác (bao gồm một số chưa được đề cập ở đây), nhưng mã thực tế đang được gỡ lỗi chạy trên P6/AIX, vì vậy Valgrind sẽ là "chỉ" bất tiện (nó cần chạy trên một máy khác), trong khi Forcheck sẽ là bất tiện (nó cần phải chạy trên một máy khác) và đắt tiền (~ 3k $). Hiện tại mtrace sẽ là giải pháp tốt nhất, nếu nó hoạt động.

EDITED một lần nữa: tôi đoán

Tôi đoán gfortran đang sử dụng một malloc gọi khác nhau, trong đó mtrace không theo dõi ...

là đúng. Nhìn vào tệp thực thi (với nm hoặc readelf), không có bất kỳ cuộc gọi nào malloc(), nhưng _gfortran_allocate_array những người - có thể sẽ gọi malloc). Bất kỳ ý tưởng nào khác?

EDITED một lần nữa: tôi đăng các câu trả lời nhưng tôi không thể chấp nhận nó (đi đến http://stackoverflow.uservoice.com/pages/general/suggestions/39426 và yêu cầu tính năng này, nó thực sự cần thiết - không đạt được danh tiếng muốn)

Trả lời

1

Steve Kargl có câu trả lời, một thời gian ngắn là mtrace không tìm thấy bất kỳ rò rỉ nào, vì không có bất kỳ rò rỉ nào nếu trình biên dịch tuân thủ tiêu chuẩn: Xem http://gcc.gnu.org/ml/fortran/2008-11/msg00163.html để biết chi tiết. Trong thực tế, tôi không phải là một chuyên gia fortran lớn (tôi chủ yếu là C/C++/java guy), và tôi cũng đang sử dụng một trình biên dịch khác, mà bị rò rỉ trong tình trạng như vậy (tôi đã không đề cập đến điều đó giữ cho câu hỏi dễ dàng hơn). Vì vậy, tôi nhầm tưởng rằng rò rỉ đã có cũng với gfortran, mà không phải là trường hợp (tôi kiểm tra với đầu)

1

Tôi không phải là một chuyên gia về mtrace, vì vậy tôi không thể giúp với điều đó. Tôi khuyên bạn nên thử công cụ valgrind để tìm rò rỉ bộ nhớ nếu bạn đang sử dụng hệ thống được hỗ trợ. Sử dụng valgrind để tìm rò rỉ bộ nhớ cũng đơn giản như gọi valgrind --leak-check=full ./a.out.

1

Tôi có kinh nghiệm gỡ lỗi chương trình Fortran nhưng phải trung thực tôi không thể thực sự hiểu câu hỏi của bạn. Tôi nghĩ rằng đó là bởi vì tôi không có nhiều kinh nghiệm gỡ lỗi C/C++ khác với Fortran. Tuy nhiên, tôi nghĩ rằng điều này sẽ mang lại lợi ích cho bạn:

Sử dụng trình biên dịch Intel với các tùy chọn biên dịch sau sẽ phát hiện hầu như mọi rò rỉ bộ nhớ, truy cập địa chỉ sai hoặc sử dụng biến/biến không khởi động trong thời gian chạy.

intel: -O0 -debug -traceback -Kiểm tra -ftrapuv

Đối Gfortran bạn cũng khá nhiều có thể nhận được một trong các lỗi trên với các tùy chọn trình biên dịch.

gfortran: -g -O0 -fbounds kiểm tra -Wuninitialized

Nó sẽ in traceback của chương trình con gọi cho đến khi xảy ra lỗi. Nó luôn luôn là hữu ích để biên dịch với hai trình biên dịch khác nhau và trong kinh nghiệm của tôi, bạn sẽ có hầu như không có rò rỉ bộ nhớ sau này.

Các vấn đề liên quan