|
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
wahorger
Joined: 13 Oct 2014 Posts: 1226 Location: Morrison, CO, USA
|
Posted: Sat Jan 23, 2021 5:07 pm Post subject: |
|
|
Robert, yes, this is a side effect of memory being filled with spaces, incorrectly, wiping out local variables, and constants that would nominally be correct for error-free operation. The reason for this is mystifying especially since I did a test where none of my code was run, yet local variables did not have their set values (via a DATA statement).
I am no longer concerned about LENG8$, it is operating correctly if given correct inputs. In this case, it was not. |
|
Back to top |
|
|
mecej4
Joined: 31 Oct 2006 Posts: 1897
|
Posted: Sat Jan 23, 2021 5:08 pm Post subject: |
|
|
Robert wrote: "It isn't byte 0x20 repeated, it is 0x02 repeated".
The index variable I_LOGMTR pertains to character*16 variables. The instructions
MOVSX_Q RBX,I_LOGMTR
IMUL_Q RBX,16_4
cause RBX to contain I_LOGMTR shifted left by one nybble, before the call to LENG8$, and the function does not touch RBX. |
|
Back to top |
|
|
Robert
Joined: 29 Nov 2006 Posts: 450 Location: Manchester
|
Posted: Sat Jan 23, 2021 5:15 pm Post subject: |
|
|
Ah, I see. |
|
Back to top |
|
|
StamK
Joined: 12 Oct 2016 Posts: 162
|
Posted: Wed Jan 26, 2022 9:23 am Post subject: |
|
|
So what is the conclusion from this thread? Is it an ftn95 bug (zeroing not happening properly) or is it a user error?
I am asking because I occasionally get the same error (cannot easily repeat it). |
|
Back to top |
|
|
mecej4
Joined: 31 Oct 2006 Posts: 1897
|
Posted: Wed Jan 26, 2022 12:10 pm Post subject: |
|
|
My assessment is that there could be no conclusion, since no reproducer was provided. From the code fragments that were shown, speculations were made.
A reexamination allows me to suspect that it was an error in the user code. Here is a short test program that may help you if your code has the same error as in the test program.
Code: | program leng8dolbug
implicit none
character*16:: feet_or_meters_scale(0:2)
data feet_or_meters_scale/'UNDEFINED','feet/inch','meters/2.54 cm'/
call prlen(feet_or_meters_scale)
end program
subroutine prlen(str)
implicit none
character*(*), intent(in), dimension(*) :: str
integer :: i
do i=0,2
print '(i2,2x,A,2x,i6)',i,trim(str(i)),len_trim(str(i))
end do
return
end subroutine |
The output from FTN95 8.83 with /64:
Code: | 0 φ$@ 16
1 UNDEFINED 9
2 feet/inch 9 |
The error is that the lower bound of an array of any type is, by default, 1. If a user declares an array with a different lower bound (0 in the example code) and then passes that array to a subroutine that expects an assumed size array, the lower bound in the subroutine will be 1, not 0 as the programmer may have expected. In other words, a non-default lower bound is not provided to the subroutine by the caller.
The same program, compiled for 32-bit, aborts with an access violation.
I wonder if the OP of this thread (WAHorger) inserted the 'Undefined' value into the array in an attempt to catch exactly the same error -- default LBOUND of dummy array argument not equal to actual LBOUND of corresponding actual array argument. |
|
Back to top |
|
|
wahorger
Joined: 13 Oct 2014 Posts: 1226 Location: Morrison, CO, USA
|
Posted: Wed Jan 26, 2022 3:03 pm Post subject: |
|
|
mecej4,
I read your post, then re-read the thread. One thing you missed in your assumption of an error in my code: This is a local variable (0:2) and other local variables have been initialized/modified to be (hex) 2020... sequences. Even floating point constants. Bizarre. And the 32-bit version of the code runs just fine.
StamK indicates that this also happens to him occasionally and he cannot easily repeat it either. |
|
Back to top |
|
|
mecej4
Joined: 31 Oct 2006 Posts: 1897
|
Posted: Wed Jan 26, 2022 3:52 pm Post subject: |
|
|
Bill,
You did say that i_logmtr was local and had values in the range 0..2; later, you wrote "That is - every local variable I looked at contained the same pattern of (hex) 20202020", but I did not know if that applied to the feet_or_meters_scale array and if that array was local.
This new errror (all variables set to values of Z'20202020') is, by itself, worthy of analysis. Can you provide a reliable reproducer for this error? That would help.
Noting that your OP was made a year ago, I looked at the code of LEN8$ in the most recent version of CLEARWIN64.DLL, and found that it was the same as in the older version (which was listed in an earlier post in this thread).
Last edited by mecej4 on Wed Jan 26, 2022 8:43 pm; edited 1 time in total |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8018 Location: Salford, UK
|
Posted: Wed Jan 26, 2022 5:58 pm Post subject: |
|
|
I have not followed the discussion on this thread but LENG8$ is the same as LEN_TRIM except that it returns an INTEGER*8 value.
So it would only be needed for CHARACTR variables with length LEN(str) greater than 2,147,483,647 (very long). It scans from the end looking for the first character that is not a space (0x20).
I would need to check the explist to see if FTN95 is sending it an INTEGER*8 value as the input for its LEN. |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8018 Location: Salford, UK
|
Posted: Thu Jan 27, 2022 10:52 am Post subject: |
|
|
This is a correction to my last post.
FTN95 implements LEN_TRIM(string, kind=k) where k defaults to 3. For 64 bits, regardless of k, it calls LENG8$ and passes a 64 bit value for LEN(str). LENG8$ returns a 64 bit value that is moved (via MOV, MOV_Q etc.) to the "destination". For example, a simple assignment to an INTEGER*4 will use a 32 bit MOV whilst an assignment to an INTEGER*8 will use a 64 bit MOV_Q.
It is possible that this is not the best strategy and a review may be required. In particular, there may be problems when LEN_TRIM is called within a function or subroutine argument list.
If this turns out to be the case then a temporary fix is to remove the call to LEN_TRIM from the argument list and to provide a simple assignment (to a temporary INTEGER of the required kind) before the call. |
|
Back to top |
|
|
mecej4
Joined: 31 Oct 2006 Posts: 1897
|
Posted: Thu Jan 27, 2022 7:41 pm Post subject: |
|
|
Here is a test program that exhibits many of the malfunctions encountered in 64-bit runs by Wahorger, as described earlier in this thread.
Code: | program wahbug
implicit none
character*16:: fms(2)
data fms/'feet/inch','meters/2.54 cm'/
integer:: i_logmtr, ls
integer*8 :: l8
!
i_logmtr = 1
ls = 3
fms(ls) = ' ' !deliberately exceed upper bound of array
l8 = len_trim(fms(i_logmtr))
print *,l8
end program |
Compile with /64 /debug and run. It crashes with an access violation at the instruction
Code: | movzx eax,byte ptr [rcx] |
inside the function LENG8$. What happens is that the integer constant 16, which is the length parameter of the variable FMS, is overwritten by 8 blank characters, changing Z'0000000000000010' to Z'2020202020202020'. This overwriting happens prior to the call to LENG8$. As a result, the string length hidden argument passed to LENG8$ is that huge integer instead of 16.
If something similar happens in Wahorger's large application compiled in 64-bit mode, using /check or /checkmate should help locate the place where the bug arises.
Last edited by mecej4 on Fri Jan 28, 2022 9:38 am; edited 2 times in total |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8018 Location: Salford, UK
|
Posted: Fri Jan 28, 2022 9:20 am Post subject: |
|
|
Thanks. I will take a look at this. |
|
Back to top |
|
|
mecej4
Joined: 31 Oct 2006 Posts: 1897
|
Posted: Fri Jan 28, 2022 9:51 am Post subject: |
|
|
Two properties of the SDBG64 debugger that I noticed as being handicaps while probing this issue at the assembler level:
1. A bug in the disassembler, as reported at http://forums.silverfrost.com/viewtopic.php?t=4594 .
2. The string length parameter, 16, is a constant stored in the data segment. It may be represented by an address such as "[50b0]$" in the disassembly and /EXP listings, and it took several disassembly runs to associate 50b0 with the character length. For instance, the EXP listing shows
but in the disassembly window SDBG64 may show
Code: | IMUL_Q RBX, [50b0]$ |
(I think that the '$' indicates that the address is to be added to the contents of register RBP). Once the address is identified and its association with the string length constant recognised, we face another obstacle, which is that there is no way (?) in SDBG64 to display the contents of that memory location in a watch-variable window. |
|
Back to top |
|
|
Robert
Joined: 29 Nov 2006 Posts: 450 Location: Manchester
|
Posted: Fri Jan 28, 2022 2:31 pm Post subject: |
|
|
You are correct about the $. RBP is loaded with the DLL/EXE's load address and then data is referenced from it. |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8018 Location: Salford, UK
|
Posted: Sat Jan 29, 2022 9:43 am Post subject: |
|
|
mecej4
Thank you for your feedback. I can now confirm your analysis.
At the moment I can't think of a way to avoid this failure (apart from correcting the Fortran source code) nor how to provide a meaningful error report when the source code contains this bug. |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8018 Location: Salford, UK
|
Posted: Sat Jan 29, 2022 10:11 am Post subject: |
|
|
mecej4
I have changed LENG8$ so that your sample code will give a runtime failure
"Memory corrupted before call to LEN_TRIM".
This is not very helpful but better than nothing. |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|