Silverfrost Forums

Welcome to our forums

Crash:This routine has been entered recursively (-ANSI mode)

2 May 2019 5:03 (Edited: 2 May 2019 10:02) #23565

I got this message when implemented slider %sl which calls function SliderFunction. The demo is here, but this demo works fine, itis the main code which crashes

module mod111 
integer kBusySliding 
real*8 SliderVariable
CONTAINS 
Integer function SliderFunction () 
  if(kBusySliding.eq.1) goto 10000 
  kBusySliding = 1 
  a=2.3
  Do i=1,5000000
  a=log(exp(a))
  enddo
  print*, a
kBusySliding = 0 
10000 continue 
SliderFunction=2 
end function 
end module mod111 
!============================= 
PROGRAM aaa 
use mod111 
  kBusySliding = 0 
  i=winio@('%60^sl', SliderVariable, 0d0, 1d0, SliderFunction) 
end program 

Inside this function goes some calculation but seems during mouse movement the slider calls this function hundreds times and way before the calculation inside the function SliderFunction ends. Despite that i implemented for such exact cases the measure (see the trick introducing variable kBusySliding) to prevent any new computations before previous ones complete (and may cause problems due to that), this time the crash happens exactly on the first line of function SliderFunction before doing anything

Questions:

  1. How to get rid of this crash? Though i admit that though the compiler is strict and absolutely right, but in this specific case i do not care about possible problems with the recursion, i just do not want it to crash. I will prevent potential collisions myself with kBusySliding trickery which worked perfectly for decades
  2. What means -ANSI mode warning in this case ? Good that such warning exists though i do not find it enough verbose to tell me more hints. With -ANSI this program even does not compile, so what for this -ANSI warning was made?

This demo example above works OK both with 64 and 32bits.

2 May 2019 7:36 #23566

Dan

You may need to use a recent version of the ClearWin+ library in order to avoid the recursive element.

2 May 2019 10:01 #23572

OOps, i missed your PM. Will try new library, thanks

3 May 2019 11:54 #23577

Still crashing. But sometimes not. Demo above also works fine. I do not know what's to do. Interesting is that using the wheel %dd with %^rd which calls the same function works no problem

3 May 2019 12:26 #23578

I would need a sample program that demonstrates the failure before I could comment.

5 Sep 2019 6:28 #24303

Was not possible again to extract the demo and keep the bug. It took me a day and the extraction grew and grew till eventually to become not manageable. Plus the bug in demo disappeared.

This will be the lesson to all and myself: over time i added and added and added features and now even simple plotting program became unmanageable. Needs way way too much time to keep it working. Programming has to be like in Lego: small simplest possible block not dependent on one giant module far away. All initiations have to be just nearby.

So my question is : how to trick the compiler and make it to miss this error? Nothing bad will happen. The place where this happen is related to realtime mouse position control in the callback mouse_pos which is called thousands time when mouse moved

i=winio@('%^og[...]', lx, ly, mouse_pos)

I speculate that some calls are not yet finished while next ones already happening so the mouse_pos could be called recursively. Usually before i included special variable into the first line of mouse_pos which made such congestions not happening by exiting immediately if previous mouse_pos was still running. May be i am wrong but looks like FTN95 became way too picky and now such congested calls become an error just by calling the mouse_pos before it succeed doing any executable statements if previous instance is still running. I have not changed anything in this part during last few years but this part of program started crashing.

6 Sep 2019 6:48 #24307

If a routine is being entered recursively against your wishes then you could put a SAVEd logical variable at the start of it. Set this .TRUE. on the first entry and exit immediately on reentry so that the routine is only executed at the first level.

SUBROUTINE sub(....) LOGICAL,SAVE:: active !!DATA statement to initialise active to .FALSE. IF(active) RETURN active = .TRUE. !! Body of subroutine active = .FALSE. END SUBROUTINE

6 Sep 2019 7:05 #24308

Or if you don't like SAVE, put it in a COMMON block.

Eddie

15 Feb 2022 5:35 #28783

Unfortunately this ' Run-time error 18 - This routine has been entered recursively' stops in debugger exactly on the line If(active) Return i.e. the error is generated before doing any IFs.

Is there any way to prevent this error to occur? At least temporally for debugging (and may be even permanently : Clearwin GUI has not to crash in this case. Things are that if you use slider, for example, and move slider fast, its callback might be executed many times while you slide. In this case some new call might happen while previous one is still not ended.

15 Feb 2022 6:56 #28784

Perhaps you should look at the result of clearwin_string@( 'CALLBACK_REASON') within your callback function.

This may tell you when to immediately return from the callback function rather than do other things that lead to the recursion.

15 Feb 2022 12:01 #28787

My impression is that the error is generated just by entering same function second time while first is not finished. This happens before any executable statements are attempted to run. Situation looks like a total screw up for any possible workarounds ... 😦

15 Feb 2022 1:05 #28791

It is possible to step through the callback on the first call using the debugger? If you know the point at which re-entry occurs, you may be able to avoid it.

16 Feb 2022 12:58 #28792

I'm still not getting what this will do. The callback is permanently used when you use slider. The problem which i am describing is mostly takes place during debug because during debug the code runs 10-100 slower and overlap of callbacks can happen

16 Feb 2022 7:43 #28793

If it runs OK when you are not using debug mode then you can put a PRINT statement into your failing callback function to print the value of clearwin_string@( 'CALLBACK_REASON'). There may be 'reasons' that need filtering out.

It seems unlikely that it fails in debug mode because it is running slower. Perhaps the compiler does not add checks for recursion in non-debug mode.

I hesitate to ask but what happens if you make the callback recursive?

17 Feb 2022 2:14 #28794

Never used it. Will try...

17 Feb 2022 2:58 #28795

Thanks for the idea. Looks like this is the way to go, all callbacks related to mouse movement seems now always have to be recursive !

17 Feb 2022 3:49 #28797

That is why I hesitated. Making the function recursive provides a work-around for a fault in the Fortran code but it really should not be necessary.

Perhaps you could use RECURSIVE in this particular context and when debugging but in general you don't want to be entering callbacks recursively.

20 Feb 2022 5:56 #28802

Hi Dan,

Any chance you could post code for the mouse_pos callback? If your callback doesn't call itself, it should not be recursive. It really should not matter how many times it get's called.

21 Feb 2022 2:57 #28803

Quoted from DanRRight My impression is that the error is generated just by entering same function second time while first is not finished. This happens before any executable statements are attempted to run. Situation looks like a total screw up for any possible workarounds ... 😦

This does not imply recursion, but multiple interupt initiations. (which are multiple threads? or at least act like multiple threads.)

For this reason, it is best to compile this routine as recursive, so that all local variables are on the stack and not static allocations.

I have experienced having multiple mouse click responses being analysed, before the previous has completed it's computed response. So the response to the interupt has to be careful that further diagnosis gets the state related to this interupt and not later interupts. Mouse movement tracking can generate interupts faster than they can be processed.

This is my interpretation of these many interupts, but may not be correct.

John

21 Feb 2022 11:28 #28804

Quoted from DanRRight My impression is that the error is generated just by entering same function second time while first is not finished. This happens before any executable statements are attempted to run. Situation looks like a total screw up for any possible workarounds ... 😦

This does not imply recursion, but multiple interupt initiations. (which are multiple threads? or at least act like multiple threads.)

For this reason, it is best to compile this routine as recursive, so that all local variables are on the stack and not static allocations.

I have experienced having multiple mouse click responses being analysed, before the previous has completed it's computed response. So the response to the interupt has to be careful that further diagnosis gets the state related to this interupt and not later interupts. Mouse movement tracking can generate interupts faster than they can be processed.

This is my interpretation of these many interupts, but may not be correct.

My solution was to find ways of processing the response more quickly, especially for mouse move interrupt, where I tested if the movement was less than a few pixels, then to ignore and return from the interupt.

Please login to reply.