Announcement

Collapse
No announcement yet.

Exception error on RETURN statement

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Exception error on RETURN statement

    I have a program that uses GOSUB/RETURN but I get an execption at the RETURN.
    Does anyone know how I can check the return address so I can see when it is getting corrupted?

  • #2
    What kind of exception? Stack fault? page fault? Invalid opcode? NUmeric overflow?

    Just FWIW (and in this case it is worth a lot).... just because your program fails with a general protection fault after executing some line of source code does not mean the underlying memory corruption (if that is the problem) occurred sometime between the last executed line and the fault; the 'real' error may have occured elsewhere in in your program, hundreds or even thousands of executed lines ago.

    There is a FAQ on using TRACE to find instances of "error 9" in the FAQ forum which can be really handy in this case.

    PB's GOSUB/RETURN works; do not look for potential compiler problems here because it will be a total waste of your time. As Shakespeare has written...

    The problem, dear Brutus,
    Is not in our stars,
    It is in our selves.


    MCM
    Michael Mattias
    Tal Systems (retired)
    Port Washington WI USA
    [email protected]
    http://www.talsystems.com

    Comment


    • #3
      Make sure you are not executing a RETURN without a GOSUB this will cause a Memory Access Violation exception. Step through your program in the debugger and I am sure you will find the cause.
      Sincerely,

      Steve Rossell
      PowerBASIC Staff

      Comment


      • #4
        Thanks for the reply.

        I am getting an %EXCEPTION_ACCESS_VIOLATION trying to read data.
        Because it happens on the return I'm guessing the stack is being corrupted somewhere between the beginning of the gosubbed code and the return point. I am just wondering if it is possible to monitor the return address to see when it changes.

        I tried the error checking from the FAQ but didn't get any error logged.

        Comment


        • #5
          Because it happens on the return I'm guessing the stack is being corrupted somewhere between the beginning of the gosubbed code and the return point.
          Please re-read what I said. That is a bad assumption.

          Yes, it is possible the stack is being corrupted. It's also possible it's not.

          It's possible the corruption is in fact occuring between the GOSUB and the RETURN. It's also possible the corruption is occurring elsewhere... somewhere you think it just not possible to occur.

          Your best bet at this point is to post the code from the GOSUB'd label through the RETURN and see if a fresh set of eyes can spot something. But don't be surprised if that only leads to requests to post additional code, because it is by no means a certainty the corruption is occurring in this particular snippet.


          MCM
          Michael Mattias
          Tal Systems (retired)
          Port Washington WI USA
          [email protected]
          http://www.talsystems.com

          Comment


          • #6
            BTW, see the CALLSTK function if you are convinced the problem is with your stack.

            I'm not sure that handles GOSUB/RETURN, but you could just restructure
            Code:
              GOSUB Foo 
             ...
            
            foo:
              code
              code 
              code
              RETURN
            .. to use
            Code:
              CALL Foo (variables needed by subroutine as parameters) 
              ...
              ...
            FUNCTION Foo (variables needed by subroutine as parameters) 
             
               code
               code 
               code 
            
            END FUNCTION
            .. and now for sure CALLSTK will give you a good trail as to how you got to where you are.
            Michael Mattias
            Tal Systems (retired)
            Port Washington WI USA
            [email protected]
            http://www.talsystems.com

            Comment


            • #7
              Originally posted by Michael Mattias View Post
              Your best bet at this point is to post the code
              If your coding metabolism is anything like mine the very act of simplifying your code to make an example of the problem to post in this forum will probably lead you quickly to a resolution. If it does not, people here will fall upon your code like a pack of wolves and tear the error out of it. Good luck!

              Comment


              • #8
                the very act of simplifying your code to make an example of the problem to post in this forum will probably lead you quickly to a resolution
                Hmm, I think you are describing CNDS: Cliff Nichols' Doh! Syndrome.

                Other symptoms include posting messages which incorporate the icon.
                Michael Mattias
                Tal Systems (retired)
                Port Washington WI USA
                [email protected]
                http://www.talsystems.com

                Comment


                • #9
                  I see no update on this post. I seriously doubt that it casts doubt on how PowerBasic compilers handle GOSUB and RETURN operations. These compilers have been tested time and time again, and we all know how stable and reliable they are.

                  Anyone using GOSUB and RETURN rather than a SUB, EXIT SUB, END SUB tends to suggest someone not yet well versed in all the power and options presented by PowerBasic. That PowerBasic supports GOSUB and RETURN still is a testament to their commitment to let programmers program as they choose. But the structure and automatic error checking inherent in using formal procedures like SUB and FUNCTION make them the preferred method of coding redundant processes. The risk with GOSUB and RETURN is that these may not mate up correctly in spagetti code, and this can be a major problem to isolate and resolve.

                  Any call structure, whether GOSUB, RETURN, CALL, or EXIT (sub or function) effect the contents of the stack. Further, for SUBs and FUNCTIONs, passed parameters and local variables also are assigned space on the stack. GOSUB and RETURN are going to modify the stack, or stack pointer, any time they are used. And when the two do not balance each other out, the stack will be corrupted. Which is why we don't use them much any more. It puts too much responsibility on the programmer to get the code esactly right, and not jump to false conclusions when it blows up.

                  Comment


                  • #10
                    Originally posted by Donald Darden View Post
                    Anyone using GOSUB and RETURN rather than a SUB, EXIT SUB, END SUB tends to suggest someone not yet well versed in all the power and options presented by PowerBasic.
                    Anyone making the above assumption tends o suggest someone not yet well versed in the online help for GOSUB, from which I quote:

                    For time critical or high-performance code, using a GOSUB to perform a repetitive task is almost always faster then performing a call to a Sub or Function, since there is no overhead in setting up a stack frame for a GOSUB

                    Comment


                    • #11
                      Depending on the application:

                      I personally stay away from GOSUB on the sheer reason that for each one, its just as easy (if not easier) to create a function from the common routines, that other functions may be able to use at a future date (aka, if I write it, and realize I am duplicating the core idea in each function, with a slight twist, then I make the core idea a function, and code for "What-If" twist)

                      that and it eliminates a lot of "Hard to Find" bugs, that can not be solved by messageboxes, or logging errors, because just the messagebox, or the log being written, could allow enough time (and enough other functions) to correct the error that originally occurred and making it harder to find.
                      Engineer's Motto: If it aint broke take it apart and fix it

                      "If at 1st you don't succeed... call it version 1.0"

                      "Half of Programming is coding"....."The other 90% is DEBUGGING"

                      "Document my code????" .... "WHYYY??? do you think they call it CODE? "

                      Comment


                      • #12
                        Originally posted by Cliff Nichols View Post
                        Depending on the application:

                        I personally stay away from GOSUB on the sheer reason that for each one, its just as easy (if not easier) to create a function from the common routines, that other functions may be able to use at a future date (aka, if I write it, and realize I am duplicating the core idea in each function, with a slight twist, then I make the core idea a function, and code for "What-If" twist). ...
                        I use GOSUB/RETURN to maximize the speed of my reusable procedures. I limit them to inside procedures (with an "EXIT procedure" line as a fall-through barrier).

                        It's handy with some of the things I use over and over. So far the debugger's step through option has been sufficient for my needs when I encounter suspect GOSUBs.

                        Stan
                        Do not go quiet into that good night,
                        ... Rage, rage against the dark.

                        Comment


                        • #13
                          Maybe an interesting addition would be local functions/subs (i.e. visible only to the function/sub in witch they are declared), with (eventual) parameters passed on the registers.

                          Bye!
                          -- The universe tends toward maximum irony. Don't push it.

                          File Extension Seeker - Metasearch engine for file extensions / file types
                          Online TrID file identifier | TrIDLib - Identify thousands of file formats

                          Comment


                          • #14
                            GOSUB calls share all the data and variables visible where the call is made. There is no distinction from variables and data handled by the called gosub rountine. SUBs and FUNCTIONs only share what is global or passed to/from them. Between recursive and repeated calls to a SUB or FUNCTION, static variables retain their values. Local variables are assigned space on the stack and set to zero on each call.

                            Speed is not everything. The added methods of handling data and isolating variables can really be used to an advantage. When developing code, SUB and FUNCTION are much easier to deal with as modules, rather than the distributed calls that you have with GOSUB and RETURN. They even help further in debugging because you have the option to step into, step over, or step out of either a SUB or FUNCTION. Not so with a GOSUB and RETURN implementation.

                            If you want even faster speed, then you would be arguing that MACROs are the only way to go. Every technique has its positives and negatives. Like GOTOs, GOSUB and RETURN imposes some peril and responsibility on the programmer, and it it ends up in a thread like this, I would have to say it is because the user simply did not appear to know this.

                            I've used GOTO, GOSUB, and similar branches many times, because I know that they have their place. The primary reason for using GOSUB is not to go fast (which it does), but because you want the embedded code to act on the variables and data that it holds in common with the calling process. That's all. Otherwise, you end up having to pass a lot of parameters back and forth to no real purpose. On the other hand, you can make the items to be shared GLOBAL in nature, meaning that they are accessible at all levels of your code. It's something of a judgement call in which way to go.

                            Comment


                            • #15
                              GOSUB is VERY handy when you need time-critical code that must branch to the same routine at least once. The speed difference using GOSUB rather than setting up/releasing a stack frame (when calling a FUNCTION) in looping code is astounding. There is no point comparing GOSUB to GOTO <label>, CALL <FUNCTION>, or CALL <SUB>, as it is completely different.

                              MACRO is the closest you will get to GOSUB, but sometimes it's nice to keep all related code in just one procedure with two or more GOSUB branches. Of course, it can be abused (as with most branch statements, such as GOTO), but that is usually due to the programmer's inexperience. My first large BASIC program used many GOTOs/GOSUBs, but I learnt from it when it got harder to understand the code later on.
                              Last edited by Kev Peel; 9 May 2008, 12:30 AM.
                              kgpsoftware.com | Slam DBMS | PrpT Control | Other Downloads | Contact Me

                              Comment


                              • #16
                                I just took some of the medicine which I prescribed for Donald Darden and actually read the help on GOSUB, all of it, word by word. I usually skim reading matter, but since my spectacles got weaker this is not without hazard.

                                What it also says is:
                                Note that ON GOSUB (and ON GOTO) have been internally optimized to produce greater run-time performance than was possible with previous versions of PowerBASIC
                                I'm not familiar with previous versions so I don't know when that sentence was added, was it version 8? 7? or what? And what was actually changed? Just curious.

                                When I use GOSUB - in search of better performance as it happens - I follow Mr Zale's advice:
                                Each subroutine should end with RETURN, which causes execution to resume with the statement immediately following the ON GOSUB statement.
                                But given that the GOSUB operates within it's "parent" SUB or FUNCTION stack, wouldn't it also be safe to EXIT SUB or EXIT FUNCTION from within the GOSUB?

                                Comment


                                • #17
                                  I would have thought so, otherwise PB would have added the error: No EXIT FUNCTION|SUB from GOSUB

                                  PB has always handled EXIT statement be "tidying" up the stack (unless it was messed up with ASM statements)
                                  kgpsoftware.com | Slam DBMS | PrpT Control | Other Downloads | Contact Me

                                  Comment


                                  • #18
                                    Yes, it's perfectly safe to EXIT a function without a RETURN to a GOSUB. PowerBASIC handles all the messy details for you. That said, I just can't bring myself to write code that way. It just has no symmetry. {smile}

                                    The biggest mistake folks make with GOSUB/RETURN is "falling-through" into the subroutine, which executes the RETURN without a prior GOSUB. That's a guaranteed GPF.

                                    Code:
                                    SUB abc()
                                    
                                    GOSUB Routine
                                      ' do something
                                    
                                    Routine:
                                      ' do something else...
                                    RETURN
                                    
                                    END SUB
                                    The problem here is that the RETURN is executed twice. The code needs an EXIT SUB just before the label "Routine".

                                    Best regards,

                                    Bob Zale
                                    PowerBASIC Inc.

                                    Comment


                                    • #19
                                      Example redundant following Bob Zale's reply! Thanks Bob!

                                      Comment


                                      • #20
                                        The biggest mistake folks make with GOSUB/RETURN is "falling-through" into the subroutine, which executes the RETURN without a prior GOSUB. That's a guaranteed GPF.
                                        I did that myself just this week.

                                        Got the GPF, too.

                                        'Twas yet another moment when I found it.

                                        MCM
                                        Michael Mattias
                                        Tal Systems (retired)
                                        Port Washington WI USA
                                        [email protected]
                                        http://www.talsystems.com

                                        Comment

                                        Working...
                                        X