Jump to content

Recursion level exceeded


Azu
 Share

Recommended Posts

How can I disable AutoIt's stack overflow protection? I have a bunch of functions that need to be called over and over.. some of them are in an adlibenable.. some in a while 1 loop.. and after a while AutoIt kills itself due to the stack overflow protection thing. I've searched the forums and the help file and was unable to find out how to disable it. Can somebody please tell me how to disable it? It would be extremely helpful if you could. :P

Link to comment
Share on other sites

  • Moderators

How can I disable AutoIt's stack overflow protection? I have a bunch of functions that need to be called over and over.. some of them are in an adlibenable.. some in a while 1 loop.. and after a while AutoIt kills itself due to the stack overflow protection thing. I've searched the forums and the help file and was unable to find out how to disable it. Can somebody please tell me how to disable it? It would be extremely helpful if you could. :P

I would say code it properly rather than looking for a means to disable something that is protecting poor coding habbits.

In Return you will find your answer to solve your issues.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

  • Moderators

Hi, I am using so many returns in my scripts that it's not even funny. I make use of them wherever I can. Can you please tell me how to stop AutoIt from closing itself due to the "Recursion level exceeded" error?

LOL, No I can't.

But again, you are missing the point... look at the script and start to debug or post it so someone can help you.

You more than likely have this scenerio somewhere:

Example 1:

Global $iCC
_RecursiveError1() ; Will get error around 380 or so
Func _RecursiveError1()
    $iCC += 1
    ToolTip('You have called _RecursiveError1 ' & $iCC & ' times.', 0, 0)
    Sleep(10)
    _RecursiveError1()
EndFunc

Edit:

Nice... You deleted your post! :P

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

Here is the part of my code that is erroring

adlibenable("dotimer",100)
func dotimer()
if pixelchecksum(483,436,600,440)=3854785502 then exit
if pixelchecksum(490,430,520,470)=2294337524 then
qm("{enter}",0,4,1,1,0,0,1)
;$mybotstatus=emergency()
endif
$ba=stringsplit(guictrlread($beltinput),' ',1)
if pixelchecksum(1230,274,1240,285)=313223617 then
qm(1254,264,2,0,0,0,0,1)
$ji=1
endif
if pixelchecksum(1230,274,1240,285)<>313223617 and $ji=1 then
qm(1254,264,2,0,0,0,0,1)
$ji=0
endif
if pixelgetcolor(1254,264)>4800000 and pixelgetcolor(1254,264)<5200000 then
qm(1254,264,2,0,0,0,0,1)
elseif pixelchecksum(1087,298,1182,302)=3593213006 and pixelgetcolor(1256,298)<15000000 then
qm(1256,298,2,0,0,0,0,1)
endif
if pixelchecksum(1088,279,1149,284)=2485491941 and pixelgetcolor(1254,283)<5200000 then
qm(1254,283,2,0,0,0,0,1)
elseif pixelchecksum(1088,279,1149,284)<>2485491941 and pixelgetcolor(1254,283)>15000000 then
qm(1254,283,2,0,0,0,0,1)
endif
tc(timerdiff($bottimer))
if $lh<>guictrlread($timerline) then guictrlsetdata($timerline,$lh)
endfunc

It works great for a while, but after a while it has the recursion error..

If I remove this part, there are other parts that are also effected by this nasty recursion prevention thing.

Edited by Azu
Link to comment
Share on other sites

  • Moderators

:P Errr.... where is the function qm()?

But I can see where you may be running into "an" issue, if you're already in the function and you've haven't cleared it out yet and you have Adlib comming in every 100 ms ... do you not see any problem with that?

Not sure how much this will help without seeing qm()... but try this:

Global $iTrack = False
AdlibEnable("dotimer",100)
Func dotimer()
    If Not $iTrack Then
        $iTrack = True
        If PixelChecksum(483, 436, 600, 440) = 3854785502 Then Exit
        If PixelChecksum(490, 430, 520, 470) = 2294337524 Then
            qm ("{enter}", 0, 4, 1, 1, 0, 0, 1)
            ;$mybotstatus=emergency()
        EndIf
        $ba = StringSplit(GUICtrlRead($beltinput), ' ', 1)
        If PixelChecksum(1230, 274, 1240, 285) = 313223617 Then
            qm (1254, 264, 2, 0, 0, 0, 0, 1)
            $ji = 1
        EndIf
        If PixelChecksum(1230, 274, 1240, 285) <> 313223617 And $ji = 1 Then
            qm (1254, 264, 2, 0, 0, 0, 0, 1)
            $ji = 0
        EndIf
        If PixelGetColor(1254, 264) > 4800000 And PixelGetColor(1254, 264) < 5200000 Then
            qm (1254, 264, 2, 0, 0, 0, 0, 1)
        ElseIf PixelChecksum(1087, 298, 1182, 302) = 3593213006 And PixelGetColor(1256, 298) < 15000000 Then
            qm (1256, 298, 2, 0, 0, 0, 0, 1)
        EndIf
        If PixelChecksum(1088, 279, 1149, 284) = 2485491941 And PixelGetColor(1254, 283) < 5200000 Then
            qm (1254, 283, 2, 0, 0, 0, 0, 1)
        ElseIf PixelChecksum(1088, 279, 1149, 284) <> 2485491941 And PixelGetColor(1254, 283) > 15000000 Then
            qm (1254, 283, 2, 0, 0, 0, 0, 1)
        EndIf
        tc (TimerDiff($bottimer))
        If $lh <> GUICtrlRead($timerline) Then GUICtrlSetData($timerline, $lh)
        $iTrack = False
    EndIf
EndFunc

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

Hi, thanks, it seemed to run longer then it did before before giving me the

---------------------------

AutoIt Error

---------------------------

Line 171 (File "C:\Documents and Settings\Administrator\Desktop\Autoit\a.au3"):

tc(timerdiff($bottimer))

Error: Recursion level has been exceeded - AutoIt will quit to prevent stack overflow.

---------------------------

OK

---------------------------

error.

If I make the adlibenable run slower, it takes longer still for it to error up.

It still does though, eventually.

Edited by Azu
Link to comment
Share on other sites

  • Moderators

Right before endfunc put Return 1

Edit:

And keep the Adlib like I had it... your logic is flawed (Let me jump to a function every 100 ms, and sleep 200 to 250 ms during a function that is called many times in the 1 function I'm jumping too.... that doesn't make sense does it?)

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

Hi, I kept the adlib how you add it, and I added "return 1" right before the endfunc on every single function in my whole script that doesn't already return something, and in the ones where they return something based on an if, I added the "return 1" as an else, so there is always a return.

After a while, I still get a recursion error though.. T_T

---------------------------

AutoIt Error

---------------------------

Line 466 (File "C:\Documents and Settings\Administrator\Desktop\Autoit\a.au3"):

if $er<>1 and pg($speedometer5x,$speedometer5y)>6300000 and cargo()=1 then

Error: Recursion level has been exceeded - AutoIt will quit to prevent stack overflow.

---------------------------

OK

---------------------------

Link to comment
Share on other sites

  • Moderators

Azu... Please read your error messages, it tells you exactly what function is causing the problem. I'm not going to help any longer, either post the entire thing, or quit posting error messages on functions that you don't even provide to debug:

if $er<>1 and pg($speedometer5x,$speedometer5y)>6300000 and cargo()=1 then

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

I know there is a problem.

The problem is that it keep giving a recursive error.

I didn't even want to post as much of my script as I did, but I'm very desperate right now.

Can you please just tell me how I can prevent the recursive error? I have no clue why it's giving this error, every single function has some kind of return at the end of it, I thought you meant that adding a return would prevent this recursive error thing, I was wrong. Can you please tell me what it is I have to do to prevent it? I read your example and tried it and it doesn't give an error.

By the same, in your first example, the function is calling itself, repeatedly, over and over.

None of my functions call themselves.

They call other functions.

And none of them are in any kind of back and forth redundancy where one functions calls the other, which then calls the first, etc etc forever and ever.

I have a while 1 loop doing a sleep, an adlibenable calling some functions, and some functions calling other functions when they get to a certain point.

The script should run forever or until I close it.

Instead it keeps erroring up.

If you want, I can send my whole script to you, but it's very very very long and a lot of it probally wouldn't make a lot of sense to anyone but me, and I would prefer not to have to release it until I have finished it..

Please can you just tell me what I have to do in a script to prevent this from happening?

Basically my script is this

[autoit]

Shit load of variables being declared

While loop until I press a certain key then it activates the rest of the script

Adlibenable a function, which calls a bunch of other functions also

The first function, which does things based on ifs, and then uses return functionname to start another function, depending on ifs

A bunch of other functions that also do this

Some functions which are just called by other functions and return values

None of the functions call themselves, and none of them will go straight back and forth between eachother.

There is no

func foo()

return blah

endfunc

func blah()

return foo

endfunc

going on.

The functions will eventually lead back to the first function after a while and start over, and it should go on until I press a key to end it.

Instead it gets a recursive error on one of the functions. Not always the same one. In fact I think it has happened on all of them at least once.

I'm not sure whether or not there is anything wrong in the code logic here.

I was just looking for a simple and quick way to disable the recursive overflow checking thingy.

I'm sorry if I sounded rude or demanding.

Link to comment
Share on other sites

The functions will eventually lead back to the first function after a while and start over, and it should go on until I press a key to end it.

Listen to Smoke.. this is your problem

After 64 (I think) recusion levels of calling funcs within funcs within funcs you will reach the recursion level because the funcs never return

Edit

looks like 384 times

Edited by ChrisL
Link to comment
Share on other sites

  • Moderators

Your not sounding rude or demanding, but what you're asking for isn't the correct solution either.

You can send the script to me via PM, I'll have a look... but I always find in these situations that when the author says "I'm doing everything and I have everything" that if they are still getting the error they don't or they have just plain coded incorrectly.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

Listen to Smoke.. this is your problem

After 64 (I think) recusion levels of calling funcs within funcs within funcs you will reach the recursion level because the funcs never return

Hi, my funcs do call eachother a lot, and usually they don't return to the func that called them, but instead they simply call the next func, and eventually, at the last func, the first func gets called and it starts over. I thought that that was correct function logic. But if I am understanding you correctly then, I think my function logic is very very very very wrong.. :">

Your not sounding rude or demanding, but what you're asking for isn't the correct solution either.

You can send the script to me via PM, I'll have a look... but I always find in these situations that when the author says "I'm doing everything and I have everything" that if they are still getting the error they don't or they have just plain coded incorrectly.

Hi, I sent it, and I don't mean to sound like I think my script is all uber or anything, I just meant, I'm not understanding correctly, and I thought I did it right but I'm not sure, and I don't wanna make my code public, it's really messy and not very good yet, it would embarrass me if a bunch of people saw it at the crappy stage it is in right now. :P Edited by Azu
Link to comment
Share on other sites

  • Moderators

I'll be honest Azu... after looking at the (and definately having to use Tidy on it, I know you just got it, and it's going to save you alot of headaches)... You should write your plan out, and start from scratch.

You have functions doing this:

If Condition = True
    func1()
EndIf

Func func1()
    If func5() = 3 Then
        Return func3()
    EndIf
    Return func60()
EndFunc

Func func2()
    If func60() <> 2
        Return func8()
    EndIf
EndFunc

Func func60etc()
    If func7() = 8 Then
        Return func9()
    Else
        Do
            Sleep(30)
        Until func2() <> 1
    EndIf
EndFunc
There's no ending point, no where to take a breath, you just jump all over the place, it might as well be one big function so it doesn't have jump from place to place, and you can just make it conditional.

You really should just start over. Hope this doesn't offend you, it's just my honest opinion.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

Hi, I didn't want it to be a bunch of functions, but I don't know how to do it otherwise.

I can't think of any way for it to interpret which endif would end which nested if, same with the whiles and fors, so instead of trying to do that I made a new function each time.

Is there a different way I can do that? I thought it could be done with some kind of goto function but AutoIt 3 doesn't have it.. I'm very confused and feel like I'm in over my head. :P

The script seems to me to do what I intended it to except that the way it is, it can't work. It will keep bringing up recursive errors. But I don't know any other way to do it.. is there any other way? Or would I have to use a differant language? Or AutoIt 2 so I can use goto? I would really rather not have to take either of those routes..

Thanks again for pointing out the source of the problem! I really appreciate your help so far! :nuke::)

Link to comment
Share on other sites

Hi, I didn't want it to be a bunch of functions, but I don't know how to do it otherwise.

I can't think of any way for it to interpret which endif would end which nested if, same with the whiles and fors, so instead of trying to do that I made a new function each time.

Is there a different way I can do that? I thought it could be done with some kind of goto function but AutoIt 3 doesn't have it.. I'm very confused and feel like I'm in over my head. :P

The script seems to me to do what I intended it to except that the way it is, it can't work. It will keep bringing up recursive errors. But I don't know any other way to do it.. is there any other way? Or would I have to use a differant language? Or AutoIt 2 so I can use goto? I would really rather not have to take either of those routes..

Thanks again for pointing out the source of the problem! I really appreciate your help so far! :nuke::)

I know you don't want to but you should just post your script. No one can really help without seeing it.

You do not need goto.

Whatever it is you are tying to do can be done with conditional statements.

So post your code.. you say you are worried about people mocking your code, the best way of learning to get better is to post what you have and let someone else suggest a different way of doing it, and this will help you to learn. IMHO

Link to comment
Share on other sites

Hi, I didn't want it to be a bunch of functions, but I don't know how to do it otherwise.

I can't think of any way for it to interpret which endif would end which nested if, same with the whiles and fors, so instead of trying to do that I made a new function each time.

Start with writing your script in SciTE and hitting Ctl-T (Tidy) once in a while. Did you see the nicely indented version of your fragment that SmOke_N posted early on? That indenting is how you track nesting of Func/IF/While/Select/Etc., and it can be done automaticly by Tidy, which is included with SciTE.

Is there a different way I can do that? I thought it could be done with some kind of goto function but AutoIt 3 doesn't have it.. I'm very confused and feel like I'm in over my head. :nuke:

Having your script be "a bunch of functions" is a GOOD thing, but a good thing that can be overdone. You have to start from understanding what you want to do. For instance, why AdLibEnable()? It is obviously causing you trouble, probably because the functions of one AdLibEnable cycle are not yet complete when it triggers again. Why not just a While loop that repeats what you want done with a 100ms delay inserted in the loop?

The script seems to me to do what I intended it to except that the way it is, it can't work. It will keep bringing up recursive errors. But I don't know any other way to do it.. is there any other way? Or would I have to use a differant language? Or AutoIt 2 so I can use goto? I would really rather not have to take either of those routes..

Thanks again for pointing out the source of the problem! I really appreciate your help so far! :):D

Start with the high-level framework of your scipt and then work your way down into more detail. Does the following sumarize your intention, at the highest level? The script should run until you kill it manually:

HotKeySet("{ESC}", "_Quit")

While 1
     ; More stuff here later
     Sleep(100)
WEnd

Func _Quit()
     Exit
EndFuncoÝ÷ Ø×±µø¥)Ú+m騭ç^µ¨¥m¢®r­¢w¶.®¶­sd÷D¶W6WBgV÷C·´U47ÒgV÷C²ÂgV÷CµõVBgV÷C² ¢b33c¶G&6²ÒfÇ6P¥vÆR¢bæ÷Bb33c¶G&6²FVà¢b33c¶G&6²ÒG'VP ¢²Ö÷&R7GVfbW&RÆFW  ¢b33c¶G&6²ÒfÇ6P¢VæD`¢6ÆVW¥tVæ@ ¤gVæ2õVB¢W@¤VæDgVæ0oÝ÷ ØÚ0¶¬²)©'âyÛ®*)er©W«º|"¶.µê뢻½éí +]¡ë'ßÛ]¢k'­Z­Ëazw±¶W¯zZuëZU¡jاm«"r W¯z[^®k'¢Ùh¶ÊuëZµÚ2¢ìÛhªizxÓ~¢N¶+'¢Û·'­J)ÜzØZ¶X§zå¢ë-±ëlÓ~¢N¶©Ý¶§rW®È­¶­½ªâi¹^±ç¦±Ê&¦W­z®wzÆ«É*0yø¥)梷zÖ¢úèæ«'«¦-±)ã]Ö ¢c¡¶ j)Ú×¥h§j×­éèû§rب©tߨ­§$jëh×6HotKeySet("{ESC}", "_Quit")

While 1
      If PixelChecksum(483, 436, 600, 440) = 3854785502 Then Exit

      If PixelChecksum(490, 430, 520, 470) = 2294337524 Then qm("{enter}", 0, 4, 1, 1, 0, 0, 1)

      $ba = StringSplit(GUICtrlRead($beltinput), ' ', 1)

      If PixelChecksum(1230, 274, 1240, 285) = 313223617 Then 
           qm(1254, 264, 2, 0, 0, 0, 0, 1)
           $ji = 1
      EndIf

      If PixelChecksum(1230, 274, 1240, 285) <> 313223617 And $ji = 1 Then
           qm(1254, 264, 2, 0, 0, 0, 0, 1)
           $ji = 0
      EndIf

      If PixelGetColor(1254, 264) > 4800000 And PixelGetColor(1254, 264) < 5200000 Then
           qm(1254, 264, 2, 0, 0, 0, 0, 1)
      ElseIf PixelChecksum(1087, 298, 1182, 302) = 3593213006 And PixelGetColor(1256, 298) < 15000000 Then
           qm(1256, 298, 2, 0, 0, 0, 0, 1)
      EndIf

      If PixelChecksum(1088, 279, 1149, 284) = 2485491941 And PixelGetColor(1254, 283) < 5200000 Then
           qm(1254, 283, 2, 0, 0, 0, 0, 1)
      ElseIf PixelChecksum(1088, 279, 1149, 284) <> 2485491941 And PixelGetColor(1254, 283) > 15000000 Then
           qm (1254, 283, 2, 0, 0, 0, 0, 1)
      EndIf
      Sleep(100)
WEnd

Func _Quit()
     Exit
EndFunc

Func qm($ia, $ib, $ic, $id, $ie, $if, $ig, $ih)
     ; More here later
EndFunc

The use of qm() as a function makes good sense here, though you didn't tell us what's in it. Nothing in the code here will ever produce a recursion error (unless it's in the mysterious qm()). If you want more help you'll have to post more info...

:P

Edited by PsaltyDS
Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

@Azu

Another thing that you should remember that you only need a function if you are going to perform a specific task more than once or twice. Each function should have only one job (specific and detailed). Like ChrisL's _Quit() Function. It has one specific purpose, to quit the program. The function name is descriptive, and it performs a specific task.

I am not saying that a function shouldnt use other functions, or even perform a few calculations, but the problem lies in your trying to use functions as a "goto". As well as it seems you are trying to use AdLibEnable() as a While...WEnd loop that calls a "start" function, and never makes it to the end of the "start" function due to each function calling another.

Write down your entire process, but do it in steps, make them small as possible at first, then you will see which ones you can group into a larger step. If you find yourself saying you need to use the same Step in step 5 as step 3 then you need a function that contains _Step3(), and call that in step 5 as _Step3(). Understand? I hope I am not confusing you.

Let me know,

JS

AutoIt Links

File-String Hash Plugin Updated! 04-02-2008 Plugins have been discontinued. I just found out.

ComputerGetInfo UDF's Updated! 11-23-2006

External Links

Vortex Revolutions Engineer / Inventor (Web, Desktop, and Mobile Applications, Hardware Gizmos, Consulting, and more)

Link to comment
Share on other sites

I don't think all this explaining and troubleshooting needs to be done.

Azu, you said your functions point to another which points to another which eventually points back tot he first one. So lets say you start up the script.... 100ms pass and it runs the function in your AdlibEnable. That function runs then calls the next and so on till it gets to the beginning again. While those functions are still executing since they stay in a loop, your AdlibEnable runs again and again causing multiple loops. When your functions call the other functions, remember that that function does not complete until the function that it calls completes and so on and so forth until the last function calls the first function again and wont end till the first one ends but the first one wont because all the others are still running(I know... that was confusing)

I don't see how thats hard to understand? Just put your functions in a while loop and use the returns to see what function to call next.

Edited by BPBNA
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...