forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

An unexpected single step exception has occurred
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support
View previous topic :: View next topic  
Author Message
sparge



Joined: 11 Apr 2005
Posts: 371

PostPosted: Thu Jun 09, 2011 10:14 am    Post subject: An unexpected single step exception has occurred Reply with quote

Has anyone ever seen this runtime error before? I haven't, and I have just started to get it this morning, with the /RELEASE build, after adding some code to a previously working app.

At the moment I can get no handle on the cause, because the /CHECKMATE and /DEBUG builds both fall over with an unknown access violation and display of assembler code. I only ran the /RELEASE build in desperation!

So, unusually, the /RELEASE build is "less unhelpful" than the other two builds. I confess I am baffled as to why a /RELEASE build should be single stepping in the first place, unless it is using a different meaning of single stepping to the usual one i.e. just going about its normal sequential instruction business without supervision Rolling Eyes
Back to top
View user's profile Send private message Send e-mail
JohnCampbell



Joined: 16 Feb 2006
Posts: 2554
Location: Sydney

PostPosted: Thu Jun 09, 2011 11:30 am    Post subject: Reply with quote

If you compile with /debug then run with sdbg, do you at least get a trace back ?
Back to top
View user's profile Send private message
sparge



Joined: 11 Apr 2005
Posts: 371

PostPosted: Thu Jun 09, 2011 11:58 am    Post subject: Reply with quote

Ho John,

No, I don't. I was running from within Plato before, but the same thing happens if SDBG is explicitly in control of the /DEBUG build. Just a window of assembler.

However, I have now found the line of offensive code. I'm still trying to figure out in a model applet how I managed to sneak it past the compiler. The best I can offer at the moment is this:

Code:

        program strung_out
        use knots
        character (len = nb) chintz, chance
        chintz = 'xyz'
        chance = chaout (chintz) ! the error is (mis)diagnosed here
        stop
        end program strung_out

        module knots
        integer, parameter :: nb = 3
        contains
        character (len = nb) function chaout (chainp)
        character (len = nb) chainp
        integer b, inp (nb)
        do b = 1, nb
          inp (b) = ichar (chainp (b)) ! the error is here
        end do
        chaout = char (inp (2)) // char (inp (3)) // char (inp (1))
        end function chaout
        end module knots


which causes FTN95 to identify a problem but misdiagnose both its location and nature:

strung_out.F95(5) : error 327 - In the INTERFACE to CHAOUT (from MODULE KNOTS), the first dummy argument (CHAINP) was of type CHARACTER(LEN=3) FUNCTION, whereas the actual argument is of type CHARACTER(LEN=3)

It is failing to pick up the fundamental syntax error that chainp (b) should be chainp (b: b), even though chainp is explicitly typed only three lines previously in the same function!

This misdiagnosis is clearly at the root of the original problem. I'm sure a little more wrapping should allow me to reproduce it. Watch this space Wink

Andy
Back to top
View user's profile Send private message Send e-mail
sparge



Joined: 11 Apr 2005
Posts: 371

PostPosted: Thu Jun 09, 2011 2:26 pm    Post subject: It's a wrap Reply with quote

Right, time to declare "victory", spent too long on reproducing this already.

The following code snippet sneaks the fundamental syntax error past FTN95
Code:

        program strung_out
        use knots
        character (len = nb) chintz, chance
        chintz = 'xyz'
        call charcoal (chance, chintz)
        stop
        end program strung_out

        module knots
        integer, parameter :: nb = 3
        contains
        subroutine charcoal (champ, chimp)
        character (len = nb) champ, chimp
        champ = chaout (chimp)
        end subroutine charcoal
        character (len = nb) function chaout (chainp)
        character (len = nb) chainp
        integer b, inp (nb)
        do b = 1, nb
          inp (b) = ichar (chainp (b)) ! the error is here
        end do
        chaout = char (inp (2)) // char (inp (3)) // char (inp (1))
        end function chaout
        end module knots

The resulting /CHECKMATE and /DEBUG builds reproduce the runtime problem as originally reported. The /RELEASE build behaves a little differently, reporting as follows:

Access Violation
The instruction at address 20202020 attempted to read from location 20202020

20202020 routine at address 20202020 [+0000]
00401000 KNOTS!CHARCOAL [+001e]
004010d0 MAIN [+003c]

eax=0360fc02 ebx=00003a49 ecx=0360fc97
edx=000000fe esi=00402010 edi=0360fd28
ebp=0360fca8 esp=0360fc4c IOPL=0
ds=0023 es=0023 fs=003b
gs=0000 cs=001b ss=0023
flgs=00010a03 [CA OP NZ SN DN OV]


NB1 if subroutine charcoal is listed after function chaout rather than before, all three builds misdiagnose the nature and location of the error in the same way as the previous code snippet. The order has to be as per the code above, to fool the compiler.

NB2 if chintz and chance are declared in module knots rather than program strung_out, the runtime behaviour is slightly different:
- /CHECKMATE and /DEBUG builds display source code instead of assembler, and /DEBUG build reports privileged instruction rather than access violation
- /RELEASE build reports access violation a little differently:

Access Violation
The instruction at address 00404018 attempted to write to location 00003a49

00404018 routine at address 404018 [+0000]
00401000 KNOTS!CHARCOAL [+001e]
004010d0 MAIN [+0048]

eax=0360fca9 ebx=00003a49 ecx=0360fca0
edx=000000fe esi=00402010 edi=0360fd28
ebp=0360fcb0 esp=0360fc54 IOPL=3
ds=0023 es=0023 fs=003b
gs=0000 cs=001b ss=0023
flgs=00010a13 [CA OP NZ SN DN OV]

04040ff outs
00404100 outsb
00404101 cmpb ah,[eax]
Back to top
View user's profile Send private message Send e-mail
JohnCampbell



Joined: 16 Feb 2006
Posts: 2554
Location: Sydney

PostPosted: Fri Jun 10, 2011 3:06 am    Post subject: Reply with quote

Andy,

I tried to compile your program and found what I think is a problem with your program and with modules, which has been discussed previously.

Your second line has "use knots", but the version of the knots module it will use will be the previous one compiled and not the one listed below. Later in your program, the module knots will be updated.
If you first use the command "del knots.mod" you will see the problem.
I would suggest that the module should be compiled (listed) before it is used, as I don't think FTN95 does address this issue.
I don't know if the standard requires the compiler to be able to cope with this.

You should try the following :
Code:
        module knots
        integer, parameter :: nb = 3
        contains
        character (len = nb) function chaout (chainp)
        character (len = nb) chainp
        integer b, inp (nb)
        do b = 1, nb
          inp (b) = ichar (chainp (b:b)) ! the error is here
        end do
        chaout = char (inp (2)) // char (inp (3)) // char (inp (1))
        chaout = chainp(2:nb) // chainp(1:1)    !  doesn't this do the same ??
        end function chaout
        end module knots

        program strung_out
        use knots
        character (len = nb) chintz, chance
        chintz = 'xyz'
        chance = chaout (chintz) ! the error is (mis)diagnosed here
        stop
        end program strung_out


John
Back to top
View user's profile Send private message
sparge



Joined: 11 Apr 2005
Posts: 371

PostPosted: Fri Jun 10, 2011 10:10 am    Post subject: Reply with quote

Hi John,

Hmm, yes, this rings a bell. When I compile my code I always have main program and modules in separate files, and I rely on Plato to get the compilation order right - so this issue would not arise for me, and it is not the source of the problem I am reporting.

Andy
Back to top
View user's profile Send private message Send e-mail
LitusSaxonicum



Joined: 23 Aug 2005
Posts: 2388
Location: Yateley, Hants, UK

PostPosted: Fri Jun 10, 2011 11:08 am    Post subject: Reply with quote

Andy,

I had to put the module first to get it to compile. Afterwards, I modified the code as follows:

Code:
       module knots
        integer, parameter :: nb = 3
        contains
        subroutine charcoal (champ, chimp)
        character (len = nb) champ, chimp
        champ = chaout (chimp)
        end subroutine charcoal
        character (len = nb) function chaout (chainp)
        character (len = nb) chainp
        integer b, inp (nb)
        do b = 1, nb
          inp (b) = ichar (chainp (b:b)) ! the error is here
        end do
        chaout = char (inp (2)) // char (inp (3)) // char (inp (1))
        end function chaout
        end module knots

        program strung_out
        use knots
        character (len = nb) chintz, chance
        chintz = 'xyz'
        call charcoal (chance, chintz)
        write(*,*) chance
        stop
        end program strung_out


The main mod is in the line where you get an error (changed CHAINP(B) to CHAINP(B:B)). I didn't know that ICHAR was capable of operating on more than one char in a string at any one time (is it?), so I would automatically try to extract one char at a time. My WRITE statement tells me you get the right reorganisation if you do this. Using substring notation feeds ICHAR with only one character.

Eddie
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2554
Location: Sydney

PostPosted: Fri Jun 10, 2011 11:56 am    Post subject: Reply with quote

I suggested two alternative changes:

do b = 1, nb
inp (b) = ichar (chainp (b:b)) ! the error is here
end do
chaout = char (inp (2)) // char (inp (3)) // char (inp (1))

or
chaout = chainp(2:nb) // chainp(1:1) ! doesn't this do the same ??

I think both address the problem you had.
Back to top
View user's profile Send private message
sparge



Joined: 11 Apr 2005
Posts: 371

PostPosted: Fri Jun 10, 2011 12:52 pm    Post subject: Reply with quote

Eddie (edit: and John, who snuck in while I was composing this),

Evidently I did not make my point(s) clear.

The code I posted is designed to reproduce a FTN95 compile-time oversight and associated bad run-time behaviour.

Point 1: Compile-time oversight. The line of source with the comment "! the error is here", and which you corrected, is a basic error of syntax that FTN95 is not picking up. It is meant to be there! In my original code, it was committed by me, in haste. The resulting executable code, which should not have been produced by the compiler, (not surprisingly) failed at runtime, and not gracefully.

Point 2: Bad run-time behaviour. The /DEBUG and /CHECKMATE executable code that FTN95 generates fails at runtime with access violation and without diagnosis or traceback. In both cases, these builds are less helpful than the /RELEASE build - not Silverfrost's design intention for these builds.

The compile order issue is a red herring - although I do find it disturbing that a given compiler can generate different executable outputs from a given portion of source code, depending on how the source code is packaged. Before we had modules, I used to have every subroutine and function in a separate file. Now we have modules, I always keep the main program and every module in a separate file. It is the only way that makes sense to me. I'm going to have to make that clear when posting code in future, with multiple uses of "code" tags.

Andy
Back to top
View user's profile Send private message Send e-mail
LitusSaxonicum



Joined: 23 Aug 2005
Posts: 2388
Location: Yateley, Hants, UK

PostPosted: Fri Jun 10, 2011 2:46 pm    Post subject: Reply with quote

Andy,

I assumed that you knew a syntax that I didn't! Agreed, if it isn't valid, then the compiler should pick it up, and also agreed, that you should get more help if you go for error-checking than if you leave it out.

It isn't even that the issue is with the Fortran-95 or -90 part of the code, it is something that has been there from Fortran-77, and agreed, it needs looking at. I had a go at removing the MODULE stuff, and the error isn't picked up even if you modify your example to look like Fortran-77.

Prior to MODULEs, every routine was self-contained and could be compiled stand-alone (EXTERNAL resolves the one ambiguity regarding whether or not a symbolic name was a FUNCTION when used as a subprogram argument - it is evident from context in an assignment statement that it is either an undeclared array or a function, and that is resolvable during linking). With MODULE and USE, one may need the contents of a module to do a compilation, which I suppose is the reason for those MOD files, as the source code could be named anything, and finding it could be difficult.

This is a degree of complexity that I had not thought about before. Not having the MODULE to hand is like (in a Fortran-77 context) not finding an INCLUDE file, and everything may not be resolvable at link time as it used to be.

Eddie
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2554
Location: Sydney

PostPosted: Sat Jun 11, 2011 1:02 am    Post subject: Reply with quote

Andy,

My apologies. I now see the problem you have identified.
Certainly the error does not report where the syntax problem is.
I did look at the cryptic error report and tried to find how CHAINP could be interpreted as a function.
I must admit I don't understand the need for CONTAINS and put the interpretation of "ichar (chainp(b))" as valid/possible function reference to this.
Is the code, as you wrote, inside MODULE and CONTAINS possible ? It isn't what you wanted but I don't know if it is illegal.

My attempt in a dos box with /check /lgo did not proceed to link and run to test SDBG.

There is a lot of new syntax in fortran now, with .net, 2003 and 2008. You should look at the 2003 or 2008 standard. Most of it I don't understand and I think all of it I don't need !
My sympathies are with the compiler writers.

John
Back to top
View user's profile Send private message
davidb



Joined: 17 Jul 2009
Posts: 560
Location: UK

PostPosted: Sat Jun 11, 2011 7:00 am    Post subject: Re: Reply with quote

Code:

        program strung_out
        use knots
        character (len = nb) chintz, chance
        chintz = 'xyz'
        chance = chaout (chintz) ! the error is (mis)diagnosed here
        stop
        end program strung_out

        module knots
        integer, parameter :: nb = 3
        contains
        character (len = nb) function chaout (chainp)
        character (len = nb) chainp
        integer b, inp (nb)
        do b = 1, nb
          inp (b) = ichar (chainp (b)) ! the error is here
        end do
        chaout = char (inp (2)) // char (inp (3)) // char (inp (1))
        end function chaout
        end module knots


Actually, your function chaout is perfectly valid Fortran if chainp is an EXTERNAL function of type character(len=nb). The compiler treats it this way. The error then is that you don't pass a function to it but a character(len=nb) variable in your main program.

The compiler diagnosis is correct I think.

So, either change the main program to pass a function (declared EXTERNAL) or change chainp(b) to chainp(b:b).

Incidently, you DO need to move the module so it is first in the file. As it is, the compiler will compile your main program first and read the interface definition from the MOD file it created at the last compile. Your first compile will always fail, as will subsequent compiles that follow a change to the interface.

This is what JohnCampbell was saying I think.

Obviously, if you're using Plato and separate files for your main program and module you will be fine as Plato will determine the correct compilation order.
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2554
Location: Sydney

PostPosted: Sat Jun 11, 2011 8:25 am    Post subject: Reply with quote

chainp was not declared EXTERNAL, so should the compiler assume this?

Also, "if you're using Plato and separate files for your main program and module you will be fine as Plato will determine the correct compilation order." Can this be assumed ?
Back to top
View user's profile Send private message
davidb



Joined: 17 Jul 2009
Posts: 560
Location: UK

PostPosted: Sat Jun 11, 2011 10:40 pm    Post subject: Re: Reply with quote

JohnCampbell wrote:
chainp was not declared EXTERNAL, so should the compiler assume this?


The compiler should assume this. You only need an EXTERNAL statement if the function name is the same as an INTRINSIC function ("Fortran 95/2003 Explained", p. 82), or if the function is passed as an actual argument to a subroutine or function. (Its a dummy argument in the example, and EXTERNAL is not needed for those). These are the rules for FORTRAN 77, which Fortran 95 inherits.

JohnCampbell wrote:

Also, "if you're using Plato and separate files for your main program and module you will be fine as Plato will determine the correct compilation order." Can this be assumed ?


Plato parses the file collection in a project and determines the correct compile order. I assume it uses Automake.exe to do this, as this utility is included in Plato's install directory.
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2554
Location: Sydney

PostPosted: Sun Jun 12, 2011 2:06 am    Post subject: Reply with quote

davidb,

I'm not sure that the default assumption is a function, as a text I have, "Fortran 95 Handbook", by Adams et al, claims "the processor assumes that the argument is a variable".
I'd expect that for "chainp" to be assumed a function, it should have been declared EXTERNAL, although the only valid interpretation of "chainp(b)" is that it is a function.
You say "The compiler should assume this", but I'm not sure that this is the case. My recollection of F77, is that EXTERNAL is required and not optional, but alas I've recently lost my copy of the Fortran 77 standard.
I also think the argument for the intrinsic "char" can not be character*3.

While we are discussing the subtleties of EXTERNAL, has anyone looked at the proposed 2008 standard ? The amount of new code structures in it is really scary. I wonder how many would use this new language. To me it looks like a lead weight that will kill the language. Who could afford to develop a compiler to support this ? I wonder how many Fortran users have given input to this latest colossus.

John
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support All times are GMT + 1 Hour
Goto page 1, 2, 3  Next
Page 1 of 3

 
Jump to:  
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