Stack Overflow Issue

rajesh4you

New Member
Hi friends,

Case: One lot no. is given. For this lot no. I have to process all the ISS-WO transaction in the tr_hist table and for each new lot from this I have to process the ISS-WO transactions like this(like a tree) it will continue until no ISS-WO transactions found for a lot. This can be done by the concept of recursion.

Problem: For some of the lots I am facing the error stack overflow.

Query: My question is can I predict before when the stack overflow occurs or can I calculate when the stack overflow occurs?
Please advice.
 

TomBascom

Curmudgeon
It would depend on the depth of the recursion and the amount of data being pushed onto the stack.

Unless you know that with a high degree of reliability you cannot predict it.

It also depends on which stack overflow error you are getting and why. There are, for instance, big differences in the likely causes of -s related errors vs -nb related errors. It might be in your best interest to post the complete and actual error message.

It would also be nice to post some sample code that illustrates the problem. (Use [ code ] tags to properly format the code if you post any...)
 

rajesh4you

New Member
Hi Tom,

The procedure is below. For this procedure the input is a lot number where tt-lot is a temp-table.

PROCEDURE lotTrace:
DEFINE INPUT PARAMETER ip-lot LIKE tr_lot.
DEFINE VARIABLE v-lot AS CHARACTER NO-UNDO.
FOR EACH tr_hist WHERE tr_serial = ip-lot
AND (tr_type = "ISS-WO"
OR tr_type = "ISS-SO") NO-LOCK:
FIND FIRST tt-lot WHERE tt-serial = ip-lot
AND tt-plot = tr_lot
NO-LOCK NO-ERROR.
IF NOT AVAILABLE tt-lot THEN
DO:
CREATE tt-lot.
ASSIGN
tt-serial = ip-lot
tt-item = tr_part
tt-type = tr_type
tt-trnbr = tr_trnbr
tt-plot = tr_lot
v-lot = tr_lot
.
IF tr_nbr <> "" THEN
ASSIGN
tt-pwo = tr_nbr.
ELSE
ASSIGN
tt-pwo = "REPETITIVE".
FOR EACH wo_mstr NO-LOCK WHERE wo_nbr = tt-pwo
AND wo_lot = tt-serial:
ASSIGN
tt-qowo = MAX(wo_qty_ord - wo_qty_comp - wo_qty_rjct,0).
END. /*FOR EACH wo_mstr */
IF tr_type = "ISS-SO" THEN
DO:
ASSIGN
tt-qsh = ABSOLUTE(tr_qty_chg)
tt-shdt = tr_ship_date.
END. /*IF tr_type = "ISS-SO" */
/* Trace to next level */
RUN lotTrace(v-lot).
END. /*IF NOT AVAILABLE tt-lot */
END. /*FOR EACH tr_hist */
END PROCEDURE.


Another query, is there any way to overcome this error other than increasing the -s parameter value(if necessary).
 

TomBascom

Curmudgeon
I don't have your data so I can't say exactly...

When you post code use [ CODE ] tags. It makes it a million or so times more readable.

Are you actually getting a -s error? If you are then the obvious thing to do would be to try increasing it and see if that cures the problem. If it does then that is good. The next step would be to determine if it was a one time need or if the data is such that you will often need to increase it.

You might also consider that all recursive procedures can be transformed into iterative procedures (and vice versa) and think about maybe rewriting this code if it is going to be an ongoing problem. (Don't take that as "don't use recursion", I like recursion and think that it is an elegant solution for many problems. But this might not be one of them.)
 
It generally takes a large volume of data to cause a stack overflow with a recursive call like the one you posted. Have you examined the data to make sure it's not faulty? Say, for example, the data relationship could be incestuous with a grandchild parenting its grandparent, resulting in an endless loop of procedure calls.

I suppose you could use a defensive function along these lines:

Code:
FUNCTION headingForDisaster
RETURNS LOGICAL
  ( /* parameter-definitions */ ) :
/*------------------------------------------------------------------------------
  Purpose:  
    Notes:  
------------------------------------------------------------------------------*/
DEFINE VARIABLE iLoop  AS INTEGER    NO-UNDO.
DEFINE VARIABLE iCount AS INTEGER    NO-UNDO.
 
    DO iLoop = 1 TO 9:
        IF PROGRAM-NAME(iLoop) = THIS-PROCEDURE:FILE-NAME THEN
            iCount = iCount + 1.
    END.
 
    RETURN (iCount > 1).
 
END FUNCTION.

If this returns TRUE, the recursive procedure has called itself more than once (in this example, but you could tweak it). So, in your recursive procedure you could:

Code:
IF headingForDisaster() THEN
    RETURN.

But of course, how would you decide on what the "best" depth of maximum allowed recursion should be? I would spend some time looking at your data to see how deep the rabbit hole goes.
 
Top