Volatile variable in a DLL - why?

Volatile variable in a DLL - why?

Hi All,

This problem is solved, but I would greatly value any insights or explanations any members of this group could provide.

A user discovered that an old, reliable, DLL failed with a message to provide a system DLL I had not noticed before: svml_dispmd.dll. I checked and found the same problem on 3 machines, but there was no problem on my development machine. So I found the missing dll and loaded it on a test machine, which got rid of the first problem, but this gave rise to an error 193 (Invalid Win 32 application) during the attempt to run LoadLibrary with the original DLL.

After much effort, I pinned the problem down to an integer loop counter variable in a minor subroutine - when I declared it as VOLATILE, the problem was solved.

As far as I know, the only thing different about this DLL in recent years is the fact that it is now built using IVF Composer XE 2013 under Windows 7, whereas  it was formally built using IVF 10 under Windows XP. All versions have been Win 32. Why did it fail on other machines but not on my developer's machine?

Many thanks in advance,

Mike

 

6 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Assuming that you are dynamically linking against the runtime (which it sounds like)...

Do your other machines have all the runtime libraries installed that correspond to the compiler used to build your DLL?  If not - that could explain your observations, though I'm a bit surprised you got away with it for so long.  Adding volatile may have inhibited some compiler optimisations that involved a call to that DLL. 

If you dynamically link to the runtime and you upgrade the compiler, you need to also upgrade the runtime installations on any machines that you deploy your programs to.

If your other machines do have the relevant (same version or later) runtime libraries installed - make sure that some other application hasn't obscured them by installing older versions of the runtime in a place ahead of the "correct" runtime installation in the Windows DLL search order.  Matlab used to do this (probably still does) by putting its directory at the front of the path and then having ifort DLL's in its directory, some other applications I've used do evil such as putting the ifort DLL's in system32.

svml_dispmd.dll is the Short Vector Math Library dispatch DLL. It is used in vectorizing math library functions. The older compiler you used didn't have this optimization, and as Ian suggests, adding VOLATILE disabled the optimization that caused it to be used.

I would say that you did not solve the problem, you just hid it. There is probably some other error in your program that is not currently being exposed.

Steve - Intel Developer Support

Thanks Steve and Ian for replies.

I searched hard for the hidden problem. I couldn't find any but I have distilled the whole thing down to something quite simple. I made a dummy routine in my DLL - a routine that isn't even called, just compiled (the actual code is more or less meaningless by this stage).

With the following version of the code, the DLL will not load - LoadLibrary gives an error 193 (Invalid Win 32 application):

subroutine dummy(radius)

implicit none

type   t_pol
   real*8         easting,northing
end type t_pol

type  (t_pol)     pgon(26)

real*8            radius,pi/3.14159/
integer*4         i			!This code will load if I declare i as VOLATILE

do i = 0,25
   pgon(i+1).easting = radius*sin(i*2*pi/100)
end do

return
end

But the following version loads just fine:

subroutine dummy(radius)

implicit none

real*8    	  easting(26)
real*8            radius,pi/3.14159/
integer*4         i

do i = 0,25
   easting(i+1) = radius*sin(i*2*pi/100)
end do

return
end

I have tried dozens of variations - different variables, breaking the expressions into sub-expressions, etc, but I can't get away from the problem if i is used to refer to an element of  pgon and as part of the expression in the sin function. This all looks innocent to me - what's wrong with it?

 

Many thanks in advance,

Mike

 

If I compile your subroutine, alone, as presented, to a DLL (which is pointless because nothing is exported), and then use the following little test program as a loader:

! In 2014-06-11 main.f90
PROGRAM LoadTheDll
  USE IFWIN
  IMPLICIT NONE
  INTEGER(HANDLE) :: dll_handle
  dll_handle = LoadLibrary('2014-06-11 dll.dll' // ACHAR(0))
  IF (dll_handle == 0_HANDLE) THEN
    PRINT "('It failed with error code ',I0)", GetLastError()
  ELSE
    PRINT "('It worked!')"
  END IF
END PROGRAM LoadTheDll

then it all works for me.

>ifort /dll "2014-06-11 dll.f90"
Intel(R) Visual Fortran Compiler XE for applications running on IA-32, Version 14.0.3.202 Build 20140422
Copyright (C) 1985-2014 Intel Corporation.  All rights reserved.

Microsoft (R) Incremental Linker Version 10.00.40219.01
Copyright (C) Microsoft Corporation.  All rights reserved.

"-out:2014-06-11 dll.dll"
-dll
"-implib:2014-06-11 dll.lib"
"2014-06-11 dll.obj"

>ifort "2014-06-11 main.f90"
...
>"2014-06-11 main.exe"
It worked!

Incidentally, if you use the dumpbin utility to examine the dll you can see that it has a dependency on svml_dispmd.dll.

>dumpbin /imports "2014-06-11 dll.dll"
Microsoft (R) COFF/PE Dumper Version 10.00.40219.01
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file 2014-06-11 dll.dll

File Type: DLL

  Section contains the following imports:

...
    svml_dispmd.dll
              10002080 Import Address Table
              1000227C Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference

                  66E __svml_sin2

If you add volatile, recompile the DLL then you will see that the import of svml_dispmd.dll has gone (but there is a reference to another ifort runtime dll).

You can run the depends utility against the DLL (starting depends with the same path and similar environment variables that exist when you try and run your program on the troublesome machines) to see exactly which imported DLL's the system will try and load when it loads your DLL.   Check that all those DLL's can be found, that all DLL's have resolved imports (some delay loaded things you can ignore), that each of those DLLs is actually being loaded from the right location (by right clicking on the DLL filename, selecting propertes and examining the Location field) and that it is the right version (see the Details tab) for the runtime that you've distributed with your program.
 

Thank you Ian for your invaluable help. I haven't used Dependency Walker before but now that I have I'm embarrassed to say I found I had selected the 64 bit svml_dispmd.dll by mistake. With the 32 bit version in place all is well.

Many thanks again

Mike

Leave a Comment

Please sign in to add a comment. Not a member? Join today