Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how can i get catch the root of a stackoverflow exception on recursive code

I have the following recursive code and i am getting a stackoverflow exception. I can't figure out the root cause because once i get the exception,i dont get the full call stack in Visual studio.

The idea is that there are org teams that roll up into larger "Main" teams.

Does anyone see a flaw on this code below that could be the culprit?

    private Unit GetUnit(Unit organisationalUnit)
    {
        if (organisationalUnit.IsMainUnit)
        {
            return organisationalUnit;                
        }

        if (organisationalUnit.Parent == null)
            return null;

        return GetUnit(organisationalUnit.Parent);
    }
like image 262
leora Avatar asked Jul 13 '10 12:07

leora


3 Answers

  1. You might have a unit which is its own parent, or barring that you might have a cycle of parents (e.g. A-B-C-A). That is, the problem might be with the data, not with the code per se.
  2. Verify that the getters of IsMainUnit and Parent don't call GetUnit.
like image 173
Anton Tykhyy Avatar answered Oct 23 '22 16:10

Anton Tykhyy


Does the root always have Parent == null? Tried checking

if (organisationalUnit.Parent == organisationalUnit)
    return null;

?

like image 21
Mau Avatar answered Oct 23 '22 17:10

Mau


You could try this to debug it better. It won't affect your production code.

using System.Diagnostics;

private Unit GetUnit(Unit organisationalUnit, int depth)
{
    debug.assert(depth < 10, "Reached an unexpected high recursion depth"); 

    if (organisationalUnit.IsMainUnit)
    {
        return organisationalUnit;                
    }

    if (organisationalUnit.Parent == null)
        return null;

    return GetUnit(organisationalUnit.Parent, depth + 1);
}

private Unit GetUnit(Unit organisationalUnit)
{
    return GetUnit(organisationalUnit.Parent, 0);
}

On second thought...

It's mostlikely that you have a circular reference somewhere.

A.parent = B;
B.parent = C;
C.parent = A;

You could try to pass a set of previous visited nodes and check whether or not you've visited this node before.

The thing with recursion is that you have to be sure that it will end and an unchecked circular reference is a situation where it wouldn't end.

like image 2
Sjuul Janssen Avatar answered Oct 23 '22 15:10

Sjuul Janssen