Silverfrost Forums

Welcome to our forums

Difference in behaviour between 32/64 bit with fopen

14 Apr 2020 6:41 #25191

The following C++ code (called from Fortran, all compiled with silverfrost) opens a file under 32 bit in read mode but fails silently to open the same file in 64 bit.

f1 = fopen( input_filename, 'r' );

64 bit does get a file handle but does not open it for read (all attributes are cleared when inspected with handle.exe from sysinternals). This file handle cannot then be closed which causes more problems further on.

32 bit obtains a read handle fine (handle.exe reports an R flag for read which is correct).

I have checked;

  1. Latest 8.61 version of compiler.
  2. Both 32 bit DLLs (salflibc64.dll, clearwin64.dll) loaded from the 8.61 compiler path and both are version 22.2.3.15.
  3. Included /checkmate in the build process, nothing reported.
  4. Output the input_filename char buffer to a message box, appears the same in 32 and 64.
  5. The file attributes are checked by pausing the debugger immediately after fopen to ensure no other code is closing or interfering with the handle.

The next step is to isolate it to a tiny bit of Fortran and C++ code but this will take me an hour or so. Does this ring any bells for anyone? I may also try stepping back 8.5 as I did not receive bug reports on this code until the upgrade to 8.61.

Regards

Ryan

14 Apr 2020 7:44 #25193

Ryan

fopens was added to salflibc64.dll at v8.60 and fopen became a special case of fopens. So it is possible that there is a regression.

You may not be able to go back to an earlier version of salflibc64.dll on its own.

I will aim to look into this. In the mean time you could either try fopens or go back wholesale to an eariler version.

14 Apr 2020 7:50 #25194

Thank you Paul.

Do you have an example or signature for fopens? I'm guessing it is a secure version so the parameters will probably have changed.

14 Apr 2020 11:55 #25198

Please see https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/fopen-s-wfopen-s?view=vs-2019 . Many of the CRT functions with _s in their names are secure versions of the traditional functions that were present in older CRTs or Unix.

15 Apr 2020 7:28 #25200

Ryan

I should have written _fsopen which has sharing options but I aim to look at this issue later this morning if you can wait.

15 Apr 2020 10:01 #25202

Ryan

fopen works for me in a 64 bit C program. You say that you make the call from Fortran code. How do you declare fopen in Fortran?

15 Apr 2020 10:18 #25203

fopen works for me in an FTN95 program. Here is my sample code:

program main
   integer(7) tfile;
   character(2048) buffer
   integer nread,r
   C_EXTERNAL fopen  'fopen' (INSTRING,INSTRING):INTEGER(7)
   C_EXTERNAL fread  'fread' (REF,VAL,VAL,VAL):INTEGER*4
   C_EXTERNAL fclose 'fclose'(VAL):INTEGER*4
   tfile = fopen('c:\techsupport\ls1.f95','r')
   nread = fread(buffer, 1, 2048, tfile);
   r =  fclose(tfile);
   print*,tfile,nread,r
   print*, buffer(1:nread)
end program
15 Apr 2020 1:00 #25206

What I meant by 'called from Fortran' is that the Fortran code calls a routine in C which then calls fopen.

This uses the definition from include\stdio.h FILE *fopen(const char *filename, const char *mode);

Sorry for not mentioning this, the read works which may be why your code seems OK. I've checked a 32 and 64 bit copy of your code and the 64 bit one does not show the correct correct file access attributes in the handle.

I placed a pause statement after fopen in your code, ran it and then used 'handle -p procname'. In my case I got this for 32 bit;

290: File (RW-) D:\3d.txt

But for 64 bit I received;

B4: File (---) D:\3d.txt

All other file flags (the executable, current folder and winsxs assemblies) loaded with attributes set for both 32/64, for example;

AC: File (RW-) C:\Windows\WinSxS*****

I may be me barking up the wrong tree, I'm not sure. This does seem to be the source of a file access bug I am trying to track down.

I'll try the 8.5 compiler and DLLs now.

15 Apr 2020 2:00 #25207

Ryan

If you call fopen in 'r' mode and fread works OK what is the problem?

15 Apr 2020 2:05 #25208

Later on in the code the file is closed, then opened again for write.

In 32 bit this works.

In 64 bit the file handle is not released and the open for write fails.

Using procmon.exe I can see the same open, read, close, open steps for both executables but the 64 bit fails due to sharing violation.

Since I'm monitoring the events at a low level I can see that the same API calls are being made, the only difference I can see is the access flags not being set correctly.

15 Apr 2020 2:15 #25209

In 64 bit the file handle is not released and the open for write fails.

Is that because you do not call fclose or because of some other fault?

15 Apr 2020 2:22 #25211

It's the same code in both situations and they both call fclose before attempting to open it again.

It could be me, but at the moment the only thing I can see different is the file attributes not being set in the 64 bit version. I see the same issue with the code you sent.

I can see the fclose going through when monitoring the process and it allegedly succeeds. My guess is that the open does not work the same in 64 bit.

I'm wary of wasting your time if it is my fault, but I'm running out of ideas. I have tried 8.50 and that is the same but that does not rule any bugs in or out. I'll try the other fsopen later.

15 Apr 2020 4:22 #25213

I still don't understand the problem. Here is my new sample that works OK for me.

program main
   integer(7) tfile;
   character(2048) buffer
   integer nread,r,nwrite
   C_EXTERNAL fopen  'fopen' (INSTRING,INSTRING):INTEGER(7)
   C_EXTERNAL fread  'fread' (REF,VAL,VAL,VAL):INTEGER*4
   C_EXTERNAL fwrite 'fwrite'(REF,VAL,VAL,VAL):INTEGER*4
   C_EXTERNAL fclose 'fclose'(VAL):INTEGER*4
   tfile = fopen('c:\techsupport\ls1.f95','r')
   nread = fread(buffer, 1, 2048, tfile);
   r =  fclose(tfile);
   print*,tfile,nread,r
!  print*, buffer(1:nread)
   tfile = fopen('c:\techsupport\copy.f95','w')
   nwrite = fwrite(buffer,1,nread,tfile);
   r = fclose(tfile);
   print*,tfile,nwrite,r
end program

You need the 'w' mode for fwrite. You could use 'rw' on the first fopen and omit the middle fclose if you are writing back to the same file.

If you want me to look further into this then can you provide a demo program.

Please login to reply.