-
Notifications
You must be signed in to change notification settings - Fork 89
Description
This issue was prompted by discussion #269, which lead to issue #277 and handled by PR #409. Using the ESMF_RUNTIME_GARBAGE=NONE it is easy now to write a little test code to see whether a Create()/Destroy() sequence leaves memory leaks using AddressSanitizer (available for GNU and LLVM based compilers) or Valgrind.
Using this setup, I find memory leaks for Grid with the Fortran API ESMF_GridCreate()/ESMF_GridDestroy() as well as the C API ESMC_GridCreate()/ESMC_GridDestroy(). The relevant code segments are for Fortran:
block
type(ESMF_Grid) :: grid
grid = ESMF_GridCreateNoPeriDimUfrm(maxIndex=[10,20], &
minCornerCoord=[0.d0,0.d0], maxCornerCoord=[1.d0,2.d0], rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) call ESMF_Finalize(endflag=ESMF_END_ABORT)
call ESMF_GridDestroy(grid, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) call ESMF_Finalize(endflag=ESMF_END_ABORT)
end block
Notice that if this code is in the main program section, the Fortran block structure is helpful to ensure the leak is correctly detected with grid variable going out of scope. Alternatively place this code segment into a subroutine for the same effect.
The same memory leaks are detected using the C API:
enum ESMC_CoordSys_Flag coordsys = ESMC_COORDSYS_CART;
enum ESMC_TypeKind_Flag typekind = ESMC_TYPEKIND_R8;
int *maxIndex = (int *)malloc(2*sizeof(int));
maxIndex[0] = 10;
maxIndex[1] = 20;
ESMC_InterArrayInt i_maxIndex;
rc = ESMC_InterArrayIntSet(&i_maxIndex, maxIndex, 2);
if (rc != ESMF_SUCCESS) ESMC_FinalizeWithFlag(ESMC_END_ABORT);
ESMC_Grid srcgrid = ESMC_GridCreateNoPeriDim(&i_maxIndex, &coordsys,
&typekind, NULL, &rc);
if (rc != ESMF_SUCCESS) ESMC_FinalizeWithFlag(ESMC_END_ABORT);
rc = ESMC_GridDestroy(&srcgrid);
if (rc != ESMF_SUCCESS) ESMC_FinalizeWithFlag(ESMC_END_ABORT);
free(maxIndex);
The Valgrind report for the Fortran test:
6,380 (1,192 direct, 5,188 indirect) bytes in 1 blocks are definitely lost in loss record 95 of 95
at 0x4C2E94F: operator new(unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
by 0x5DF6E20: ESMCI::Grid::create(int, char*, ESMC_TypeKind_Flag*, ESMCI::DistGrid*, ESMCI::InterArray<int>*, ESMCI::InterArray<int>*, ESMCI::InterArray<int>*, ESMCI::InterArray<int>*, ESMC_CoordSys_Flag*, ESMCI::InterArray<int>*, ESMCI::InterArray<int>*, ESMCI::InterArray<int>*, ESMC_IndexFlag*, bool*, bool*, int*, ESMCI::VM*) (ESMCI_Grid.C:1665)
by 0x5DEC3A2: c_esmc_gridcreatefromdistgrid_ (ESMCI_Grid_F.C:161)
by 0x6B949D3: __esmf_gridmod_MOD_esmf_gridcreatefrmdistgrid (ESMF_Grid.F90:4789)
by 0x6B411C0: __esmf_gridmod_MOD_esmf_gridcreatenoperidimr (ESMF_Grid.F90:10951)
by 0x6B3520A: __esmf_gridmod_MOD_esmf_gridcreatenoperidimufrmr (ESMF_Grid.F90:11964)
by 0x404E88: MAIN__ (garbageModeTest.F90:76)
by 0x405161: main (garbageModeTest.F90:7)
and the C test:
4,904 (1,192 direct, 3,712 indirect) bytes in 1 blocks are definitely lost in loss record 22 of 22
at 0x4C2E94F: operator new(unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
by 0x5DF6E20: ESMCI::Grid::create(int, char*, ESMC_TypeKind_Flag*, ESMCI::DistGrid*, ESMCI::InterArray<int>*, ESMCI::InterArray<int>*, ESMCI::InterArray<int>*, ESMCI::InterArray<int>*, ESMC_CoordSys_Flag*, ESMCI::InterArray<int>*, ESMCI::InterArray<int>*, ESMCI::InterArray<int>*, ESMC_IndexFlag*, bool*, bool*, int*, ESMCI::VM*) (ESMCI_Grid.C:1665)
by 0x5DEC3A2: c_esmc_gridcreatefromdistgrid_ (ESMCI_Grid_F.C:161)
by 0x6B949D3: __esmf_gridmod_MOD_esmf_gridcreatefrmdistgrid (ESMF_Grid.F90:4789)
by 0x6B411C0: __esmf_gridmod_MOD_esmf_gridcreatenoperidimr (ESMF_Grid.F90:10951)
by 0x6A49601: f_esmf_gridcreatenoperidim_ (ESMF_Grid_C.F90:75)
by 0x5DF3EB8: ESMCI::Grid::createnoperidim(ESMC_InterArrayInt*, ESMC_CoordSys_Flag*, ESMC_TypeKind_Flag*, ESMC_IndexFlag*, int*) (ESMCI_Grid.C:254)
by 0x5A9D9D3: ESMC_GridCreateNoPeriDim (ESMC_Grid.C:81)
by 0x403F0B: main (garbageModeTest.c:35)