Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Fortran DLL built with Intel Fortran 2018 causes Excel to crash when accessed through a VBA wrapper function

avinashs
New Contributor I
559 Views

1. I have been using a Fortran DLL for the past several years (10+) which contains several utility functions. These functions are called in Excel VBA code via wrapper functions.
2. The DLL has always been created using the default project settings except

Configuration Properties -> Fortran -> External Procedures -> Calling Convention: CVF(/iface:cvf)
Configuration Properties -> Libraries -> Runtime Library: Debug Multithreaded (/libs:static /threads /dbglibs)

3. When the DLL was rebuilt using Intel® Parallel Studio XE 2018 with Microsoft Visual Studio Community 2017 last week, opening an Excel file that accesses the DLL generates the following error and causes Excel to crash.

_________________________________________________________________________

Microsoft Visual C++ Runtime Library
Debug Error!
Program: <Path to DLL>

Damage before 0x24DBE430 which was allocated by aligned routine

(Press Retry to debug the application).
_________________________________________________________________________

4. I have tested the DLL within Fortran by using a Fortran main program to call the same functions and it works without error. Somehow, the rebuilt DLL is incompatible with Excel.

5. Further, I had saved a copy of the same DLL built with Intel Parallel Studio 2017. Excel is able to access the functions in the same DLL built with the earlier version.

6. So somehow, IPS2018 seems to be causing a problem.

Your help will be greatly appreciated.

0 Kudos
8 Replies
gib
New Contributor II
559 Views

Have you tried building the DLL with Runtime Error Checking and Generate Traceback Information turned on?  These can be informative.  I use Custom and check the first three options.

Gib

0 Kudos
IanH
Honored Contributor II
559 Views

There's not a lot to go on here.

How much debugging of the crash have you done? You can debug through the Excel process into calls to your dll and try and narrow down the problematic code.

0 Kudos
avinashs
New Contributor I
559 Views

Thanks for the responses so far. The issue appears to be in the mixed-language interface within Excel since the DLL works without error in a Fortran environment. Debugging or traceback has been difficult since Excel crashes as soon as any legacy file is opened. So far I have managed to start Excel in manual calculation mode, delete all worksheets calling these functions and then incrementally start calling functions one at a time. Some functions are working fine whereas, in others, the results are meaningless upon return.

At the same time, the legacy DLL built with IVF2017 is working normally in Excel.

So I plan to reinstall IVF2017 and rebuild once again to see if I can create a normally functioning DLL. I will keep everyone posted.

Apparently, this error has been discussed on this Forum before though not related to Excel in the thread "What is up with "Debug Error!" from Microsoft Visual C++ Runtime Library?" by FortranFan.

0 Kudos
DavidWhite
Valued Contributor II
559 Views

You can debug this from MSVS.

Create a debug version of your DLL; if Excel is loading the DLL from a specific location, copy the DLL to that place.

In MSVS, set the debugging command to be Excel.exe (you probably will need to provide the full path to the exe file).

Set some break points in MSVS after the entry points in your DLL.

Start a debugging session ... this will start Excel.

Then load your Workbook that calls the DLL, and you should be able to see whether execution can get to the DLL, and whether execution fails before, during, or on exiting the DLL.  This will help narrow down the cause of the problem.

 

0 Kudos
avinashs
New Contributor I
559 Views
Thanks David White, IanH, gib for all the suggestions. The problem has been resolved without inordinate delay. I was not able to debug using Excel and MSVS as suggested because both were crashing when I tried to do so.  However, I was able to recreate (luckily) the source of the error in Fortran itself by writing another program. Here are my findings for reference presented in pseudocode format (actual code contains the relevant interfaces and declarations):
 
1. I have a user variable that contains allocatable components:
 
type :: myvar
   integer(4) :: nz
   real(8), dimension(:), allocatable :: z
end type myvar
 
2. An array of user defined variables is used in the main subroutine and passed to various other subroutines:
 
type(myvar), dimension(:), allocatable :: array
 
3. This array was being passed to a subroutine (INIT) where it was allocated along with the allocatable component (z) for each element of array.
 
subroutine INIT(m, nz, array)
  ...
  type(myvar), dimension(:), allocatable :: array
  ...
  allocate(array(m))
  do i = 1,m
       allocate(array(i)%z(nz))
  end do
  deallocate(array)
  ...
end subroutine INIT
 
4. Finally, this array was being deallocated by passing it to another subroutine (FREE), where first the individual components were deallocated and finally the entire array as a whole.
 
subroutine FREE(array)
  ...
  type(myvar), dimension(:), allocatable :: array
  ...
  m = size(array)
  do i = m,1,-1

      print *, array(i)%z ! OK

      ! THE STATEMENT BELOW CAUSES THE CRASH BECAUSE THE ALLOCATABLE COMPONENT IS CORRUPTED ON ENTRY
      deallocate(array(i)%z)  ! ERROR
  end do
  deallocate(array)
  ...
end subroutine FREE
 
5. The process of deallocating the individual components was generating the error since the MSVS debugger showed that the components z were defined prior to entering FREE but were undefined once FREE was entered. Interestingly, the contents of individual z's could be printed within FREE but not deallocated.
 
6. The solutions that worked were:
(a) Use only the deallocate(array) statement within FREE i.e. do not deallocate the individual z's first in the do loop where the error occurred.
(b) Not to use FREE. Move the executable statements of FREE to the main subroutine that is exported as a DLL to directly perform individual deallocations of components and then the array as a whole.
 
7. A similar error occurred if z was defined to be a pointer component or array was declared to be a pointer.
 
 
 
 
0 Kudos
IanH
Honored Contributor II
559 Views

Most likely, you have a bug elsewhere in your program that is corrupting memory.

Your INIT procedure has a deallocate statement in it - I assume that is a typo.

Do those procedures have an explicit interface accesible at the point they are called?  Are they defined in a module?

Allocatable components (versus pointer components) do not need to be manually deallocated ahead of the object that they belong to ceasing to exist.

0 Kudos
andrew_4619
Honored Contributor II
559 Views

I agree with Ian "5. The process of deallocating the individual components was generating the error since the MSVS debugger showed that the components z were defined prior to entering FREE but were undefined once FREE was entered. Interestingly, the contents of individual z's could be printed within FREE but not deallocated."

This I think is a bug in the debugger/fortran integrations that is well documented elsewhere on the forum. I do not think it is the cause of the problem. You have changed the code and it magically now works, but this could also be that the meory corruption bug has just moved to somewhere less damaging/obvious.

0 Kudos
avinashs
New Contributor I
559 Views

@IanH - You correctly point out that the deallocate statement is a typo in my pseudocode. These procedures all have an explicit interface but are not in a module. I thought there was a bug somewhere between calling INIT and calling FREE, but code execution works normally until FREE is entered. In fact, the process of deallocating the component occurs normally if it is done just before calling FREE. So clearly, corruption is either in FREE or not detected before calling FREE.

0 Kudos
Reply