Shop OBEX P1 Docs P2 Docs Learn Events
Stacks robbing from stacks — Parallax Forums

Stacks robbing from stacks

T ChapT Chap Posts: 4,223
edited 2010-03-30 04:24 in Propeller 1
I just discovered something that may be already known. In a row of longs like below:

VAR
LONG stack1[noparse][[/noparse]24], stack2[noparse][[/noparse]16], stack3[noparse][[/noparse]24], unusedstack[noparse][[/noparse]17], morestack[noparse][[/noparse]24]


unusedstack was never implemented in the program, so when doing some housecleaning I deleted it, and the program started becoming very erratic. So I put back the unusedstack and things worked fine.

Here is the solution to get the program to work again:

VAR
LONG stack1[noparse][[/noparse]24], stack2[noparse][[/noparse]16], stack3[noparse][[/noparse]40], morestack[noparse][[/noparse]24]

So it looks like stack3 was borrowing from unusedstack all along but I didn't know it since the unusedstack never got used as I planned.

Comments

  • Mike GMike G Posts: 2,702
    edited 2010-03-28 19:33
    As far as I know SPIN does not manage memory.

    Seems more plausible that your code used more than 24 longs starting at @stack3 or removing unusedstack[noparse][[/noparse]17] shifted morestack[noparse][[/noparse]24]'s starting address to an unexpected run-time location. The first is probably true since 24+17 = 41.

    Right?

    Post Edited (Mike G) : 3/28/2010 8:02:07 PM GMT
  • MagIO2MagIO2 Posts: 2,243
    edited 2010-03-28 19:53
    Yep, it's well known .. or should be well known .. that you have to take care that the stack you offer to a new SPIN COG is big enough, as SPIN won't do any validations regarding stack size. You are the programmer and you should have an idea on how big the stack needs to be.

    Each call to sub-functions needs stack-space. The more parameters and local variables those have the more stackspace is needed. This is especially a problem when you use objects, because you usually won't look into the code to see how much stack will be needed by the objects. And objects using other objects ... ;o)
    But if you really want to make the stack as little as possible that's what you should do. Or run tests using the method you obviously found by yourself. Check that a stack does not overwrite into other sections. But testing can be really time consuming.
  • kuronekokuroneko Posts: 3,623
    edited 2010-03-29 01:22
    The PropellerTool comes with a Stack Length object enabling you to determine the required stack depth.
  • mikedivmikediv Posts: 825
    edited 2010-03-29 17:06
    Yes but is Todd correct can Spin know or have the ability to take room from the other unused stack statement??
  • Mike GMike G Posts: 2,702
    edited 2010-03-29 17:41
    If you have a stack that is 10 bytes long and you write 11 bytes to the stack, the 11h byte could overwrite someone else's memory location.

    There's no native stack memory management. You'd have to write that yourself.

    Post Edited (Mike G) : 3/29/2010 5:54:17 PM GMT
  • T ChapT Chap Posts: 4,223
    edited 2010-03-29 19:25
    mikediv said...
    Yes but is Todd correct can Spin know or have the ability to take room from the other unused stack statement??

    Yes this was the point, it is well known that you must allocate stack space to fit the bill, what I didn't know was that it would go to the next memory location to borrow from. Although there is stack space obj as mentioned, another method of checking if a stack is running over may be to put a dummy array after it in the declares, and watch to see if any values get changed in the dummy. If this in fact worked, then you could probably watch and see just how short the previous stack is in order to be correct.
  • MagIO2MagIO2 Posts: 2,243
    edited 2010-03-29 20:08
    Yep, theoretically this works. But you have to be sure that you ran through all possible paths of program execution to be rally sure that the "measured" stack-size is big enough. If you have code which behaves different based on time or external input your measurement might be fine for 99,9% of program execution, but once in a while another path is taken and one additional function is called which leads to a stack overflow again.
  • Dave HeinDave Hein Posts: 6,347
    edited 2010-03-29 20:59
    The same problem occurs in multi-tasking systems on a single processor.· A dedicated stack must be allocated for each task.· I haven't used the Stack Length object, but it looks like a useful tool.· The dummy array is also a good idea, but you could do the same thing by just using a larger stack and initializing it to a value that wouldn't normally be used.

    The code would look something like the code shown below.

    CON
    · checkcode = $dead1eaf
    VAR
    · long stack[noparse][[/noparse]1000]
    PUB start | i
    · longfill(@stack, checkcode, 1000)
    '· ...
    '· Do stuff
    '· ...
    · repeat i from 999 to 0
    ··· if stack[noparse][[/noparse]i] <> checkcode
    ····· quit
    · ser.dec(i+1)
    · ser.str(string(" longs used in the stack", 13))
  • Rob7Rob7 Posts: 275
    edited 2010-03-30 04:24
    Very Interesting !
    In the past I have come across problems of having not allocating enough stack space, however this is truly a great find.

    Post Edited (Rob7) : 3/30/2010 4:31:30 AM GMT
Sign In or Register to comment.