- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
With 17.0.1 (and perhaps earlier, I didn't check) the compiler does not correctly handle the deallocation of polymorphic objects, where there is some sort of inheritance hierarchy and the deallocation is triggered by associating an allocatable object with an INTENT(OUT) dummy, or by using MOVE_ALLOC.
For example:
MODULE m IMPLICIT NONE TYPE, PUBLIC :: Parent INTEGER :: tag_parent = TRANSFER('prnt', 1) END TYPE Parent TYPE, PUBLIC :: Element CLASS(Parent), ALLOCATABLE :: item INTEGER :: tag_element = TRANSFER('elem', 1) END TYPE Element TYPE, PUBLIC, EXTENDS(Parent) :: Extension INTEGER :: tag_extension = TRANSFER('extn', 1) TYPE(Element), ALLOCATABLE :: array(:) END TYPE Extension TYPE, PUBLIC, EXTENDS(Extension) :: ExtExt INTEGER :: tag_extext = TRANSFER('exex', 1) END TYPE ExtExt TYPE, PUBLIC, EXTENDS(Parent) :: Other CHARACTER(:), ALLOCATABLE :: buffer INTEGER :: tag_other = TRANSFER('othr', 1) END TYPE Other PUBLIC :: Run CONTAINS SUBROUTINE Run(option) INTEGER, INTENT(IN) :: option CLASS(Parent), ALLOCATABLE :: a CLASS(Parent), ALLOCATABLE :: not_allocated CALL create_extext(a) SELECT CASE (option) CASE (1) ; DEALLOCATE(a) CASE (2) ; CALL intent_out(a) CASE (3) ; CALL MOVE_ALLOC(not_allocated, a) END SELECT END SUBROUTINE Run SUBROUTINE intent_out(arg) CLASS(Parent), INTENT(OUT), ALLOCATABLE :: arg END SUBROUTINE intent_out SUBROUTINE create_extext(arg) CLASS(Parent), INTENT(OUT), ALLOCATABLE :: arg TYPE(ExtExt), ALLOCATABLE :: tmp INTEGER :: i ALLOCATE(tmp) ALLOCATE(tmp%array(10)) DO i = 1, SIZE(tmp%array) CALL create_other(tmp%array(i)%item) END DO CALL MOVE_ALLOC(tmp, arg) END SUBROUTINE create_extext SUBROUTINE create_other(arg) CLASS(Parent), INTENT(OUT), ALLOCATABLE :: arg TYPE(Other), ALLOCATABLE :: tmp ALLOCATE(tmp) tmp%buffer = REPEAT('x',1024) CALL MOVE_ALLOC(tmp, arg) END SUBROUTINE create_other END MODULE m PROGRAM p USE m IMPLICIT NONE INTEGER :: i continue ! Get heap stats here. DO i = 1, 1000 ! 1000000 - use larger number to force crash. CALL Run(2) END DO continue ! Get heap stats here. END PROGRAM p
(The components initialized by transfer are just to provide identifiable tags for each type of object when examining the allocated blocks on the heap.)
On x86, if the upper limit of the do loop in the main program is increased to one million or so, the program will crash at run time - (the runtime is unable to report anything meaningful due to memory exhaustion). With more nominal values for the upper limit (e.g. as in the code above), the leak can be observed by using your heap analysis tools of choice. For example (on x64):
>ifort /check:all /warn:all /standard-semantics /debug "2017-02-02 memleak.f90" Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64, Version 17.0 Build 20161005 Copyright (C) 1985-2016 Intel Corporation. All rights reserved. 2017-02-02 memleak.f90(44): remark #7712: This variable has not been used. [ARG] SUBROUTINE intent_out(arg) ------------------------^ Microsoft (R) Incremental Linker Version 14.00.24215.1 Copyright (C) Microsoft Corporation. All rights reserved. "-out:2017-02-02 memleak.exe" -debug "-pdb:2017-02-02 memleak.pdb" -subsystem:console "2017-02-02 memleak.obj" >"c:\Program Files (x86)\Windows Kits\8.1\Debuggers\x64\windbg.exe" "2017-02-02 memleak.exe"
then...
Microsoft (R) Windows Debugger Version 6.3.9600.17237 AMD64 Copyright (c) Microsoft Corporation. All rights reserved. CommandLine: "2017-02-02 memleak.exe" ************* Symbol Path validation summary ************** Response Time (ms) Location Deferred srv*c:\Users\ian\Symbols*http://msdl.microsoft.com/download/symbols Symbol search path is: srv*c:\Users\ian\Symbols*http://msdl.microsoft.com/download/symbols Executable search path is: ModLoad: 00007ff7`c6960000 00007ff7`c6aee000 2017-02-02 memleak.exe ModLoad: 00007ffe`a33f0000 00007ffe`a35c1000 ntdll.dll ModLoad: 00007ffe`a11f0000 00007ffe`a129b000 C:\WINDOWS\System32\KERNEL32.DLL ModLoad: 00007ffe`9fbf0000 00007ffe`9fe0d000 C:\WINDOWS\System32\KERNELBASE.dll ModLoad: 00007ffe`a0cd0000 00007ffe`a0cec000 C:\WINDOWS\System32\imagehlp.dll ModLoad: 00007ffe`9fe80000 00007ffe`9ff75000 C:\WINDOWS\System32\ucrtbase.dll (22f0.3ebc): Break instruction exception - code 80000003 (first chance) ntdll!LdrpDoDebuggerBreak+0x30: 00007ffe`a34c34e0 cc int 3 0:000> bu `2017-02-02 memleak.f90:78` *** WARNING: Unable to verify checksum for 2017-02-02 memleak.exe 0:000> g ModLoad: 00007ffe`a1070000 00007ffe`a110e000 C:\WINDOWS\System32\msvcrt.dll Breakpoint 0 hit 2017_02_02_memleak!P+0x4f: 00007ff7`c69692c4 48c7454800000000 mov qword ptr [rbp+48h],0 ss:00000096`b3bffdb8=cccccccccccccccc 0:000> !heap -s NtGlobalFlag enables following debugging aids for new heaps: tail checking free checking validate parameters LFH Key : 0x3f9ea29935acbd81 Termination on corruption : ENABLED Heap Flags Reserv Commit Virt Free List UCR Virt Lock Fast (k) (k) (k) (k) length blocks cont. heap ------------------------------------------------------------------------------------- 00000245043d0000 40000062 1020 148 1020 43 9 1 0 0 00000245042b0000 40008060 64 4 64 2 1 1 0 0 0000024504770000 40001062 60 36 60 13 2 1 0 0 ------------------------------------------------------------------------------------- 0:000> bu `2017-02-02 memleak.f90:84` 0:000> g Breakpoint 1 hit 2017_02_02_memleak!P+0x8a: 00007ff7`c69692ff 48c7455000000000 mov qword ptr [rbp+50h],0 ss:00000096`b3bffdc0=cccccccccccccccc 0:000> !heap -s NtGlobalFlag enables following debugging aids for new heaps: tail checking free checking validate parameters LFH Key : 0x3f9ea29935acbd81 Termination on corruption : ENABLED Heap Flags Reserv Commit Virt Free List UCR Virt Lock Fast (k) (k) (k) (k) length blocks cont. heap ------------------------------------------------------------------------------------- 00000245043d0000 40000062 16364 13708 16364 3 14 5 0 0 00000245042b0000 40008060 64 4 64 2 1 1 0 0 0000024504770000 40001062 60 36 60 13 2 1 0 0 ------------------------------------------------------------------------------------- 0:000> WTF!!! ^ Syntax error in 'WTF!!!'
The differences in the record for the first heap for the process across the do loop show an increase of about 13MB of allocations, when the difference in allocations should be all but zero.
A slightly modified example is attached that uses the C runtime memory routines to illustrate the leak (must be compiled with /MTd).
>ifort /check:all /warn:all /standard-semantics /MTd /debug /exe:"2017-02-02 memleak2.exe" H:\Projects\Win32Lib\Other\CrtMemoryUtilities.f90 "2017-02-02 memleak2.f90" && "2017-02-02 memleak2.exe" Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64, Version 17.0 Build 20161005 Copyright (C) 1985-2016 Intel Corporation. All rights reserved. 2017-02-02 memleak2.f90(44): remark #7712: This variable has not been used. [ARG] SUBROUTINE intent_out(arg) ------------------------^ Microsoft (R) Incremental Linker Version 14.00.24215.1 Copyright (C) Microsoft Corporation. All rights reserved. "-out:2017-02-02 memleak2.exe" -debug -pdb:CrtMemoryUtilities.pdb -subsystem:console CrtMemoryUtilities.obj "2017-02-02 memleak2.obj" Explicit deallocate 0 bytes in 0 Free Blocks. 0 bytes in 0 Normal Blocks. 0 bytes in 0 CRT Blocks. 0 bytes in 0 Ignore Blocks. 0 bytes in 0 Client Blocks. Largest number used: 13010 bytes. Total allocations: 1301000 bytes. End of procedure 0 bytes in 0 Free Blocks. 0 bytes in 0 Normal Blocks. 0 bytes in 0 CRT Blocks. 0 bytes in 0 Ignore Blocks. 0 bytes in 0 Client Blocks. Largest number used: 0 bytes. Total allocations: 1301000 bytes. INTENT(OUT), ALLOCATABLE argument 0 bytes in 0 Free Blocks. 1289100 bytes in 2100 Normal Blocks. 0 bytes in 0 CRT Blocks. 0 bytes in 0 Ignore Blocks. 0 bytes in 0 Client Blocks. Largest number used: 1276209 bytes. Total allocations: 1301000 bytes. MOVE_ALLOC with unallocated from 0 bytes in 0 Free Blocks. 1289100 bytes in 2100 Normal Blocks. 0 bytes in 0 CRT Blocks. 0 bytes in 0 Ignore Blocks. 0 bytes in 0 Client Blocks. Largest number used: 1289100 bytes. Total allocations: 1301000 bytes.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you for the complete, detailed analysis and convenient reproducer. I reported all of this to Development.
(Internal tracking id: DPD200417531)
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page