0

I currently have a console application written in C# for production server environment. It's quite simple, but I've been testing it for +- 3 months now on my own server (semi-production, but not a disaster if the program fails). I've been getting stack overflow errors every few weeks or so, though.

Of course, pasting my entire source code here would be quite a long piece, so I will try to explain it the best I can: the program is in an infinite while loop (this is probably the cause of the issue), and it checks every second a few small things and prints to the console every so often (if no activity, every 15min, otherwise up-to every second).

Now why and how can I fix the stack overflow errors? Being able to run it for a couple weeks without issue may seem like a lot, but it is obviously not in a server production environment. My guess is that it's the fact I'm using a while loop, but what alternatives do I have?

Edit: here's a portion of the code:

int timeLoop = 0;
while (true)
{
  // If it has been +-10min since last read of messages file, read again
  if (timeLoop > 599)
  {
    Console.WriteLine(DateTime.Now.ToString("HH:mm:ss") + " Reading messages...");
    messagesFile = File.ReadAllText(@"messages.cfg");
    messages = messagesFile.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
    timeLoop = 0;
  }

  // For each message, check if time specified equals current time, if so say message globally.
  foreach (string x in messages)
  {
    string[] messageThis = x.Split('~');
    int typeLoop = 0;
    if (messageThis[2] != "no-loop")
      typeLoop = Convert.ToInt16(messageThis[2].Remove(0, 5));
    DateTime checkDateTime = DateTime.ParseExact(messageThis[0], "HH:mm:ss", null);

    if (typeLoop == 0)
    {
      if (checkDateTime.ToString("HH:mm:ss") == DateTime.Now.ToString("HH:mm:ss"))
        publicMethods.sayGlobal(messageThis[1]);
      }
      else
      {
        DateTime originalDateTime = checkDateTime;
      do
      {
        checkDateTime = checkDateTime.AddHours(typeLoop);
        if (checkDateTime.ToString("HH:mm:ss") == DateTime.Now.ToString("HH:mm:ss"))
          publicMethods.sayGlobal(messageThis[1]);
      } while (checkDateTime.ToString("HH:mm:ss") != originalDateTime.ToString("HH:mm:ss"));
    }
  }

  timeLoop++;
  Thread.Sleep(1000);
}

Also, I forgot that I actually have this code on Github, which probably helps a lot. I know you shouldn't be using any links to code and have them here, so that's why I included the snippet above - but if you are interested in helping me out the repository is located here. Another note - I know that doing it like this is not very accurate on timing - but this is not much of an issue at the moment.

13
  • 10
    Do you have a stack trace? Does anything call itself recursively? Commented Nov 27, 2013 at 13:39
  • 5
    this exception won't be fixed for you if there is not any code Commented Nov 27, 2013 at 13:39
  • 6
    I can confirm that while loops, in and of themselves, do not cause stack overflows. Commented Nov 27, 2013 at 13:40
  • 1
    Look for a recursive call -- a while loop does not cause a stack overflow. Commented Nov 27, 2013 at 13:41
  • 1
    Try to print out what is being called, either way somewhere control leaves the while loop and goes to another method, or maybe you initialize more and more local variables than you have memory for? Or you start more & more threads that don't end thus limiting stack space each thread untill you encounter an error. Really, we don't have enough information to help you Commented Nov 27, 2013 at 13:46

1 Answer 1

2

BattleEyeClient.Connect can call itself in some (failing) circumstances, and this method can be called by sayGlobal - so you probably want to change this code block (from line 98):

        catch
        {
            if (disconnectionType == BattlEyeDisconnectionType.ConnectionLost)
            {
                Disconnect(BattlEyeDisconnectionType.ConnectionLost);
                Connect();
                return BattlEyeConnectionResult.ConnectionFailed;
            }
            else
            {
                OnConnect(loginCredentials, BattlEyeConnectionResult.ConnectionFailed);
                return BattlEyeConnectionResult.ConnectionFailed;
            }
        }

Maybe keep track of how many reconnection attempts you make or transform this section of code so that it is a while loop rather than a recursive call during this failure mode.


Even worse, of course, is if that recursive Connect call succeeds, this catch block then returns BattlEyeConnectionResult.ConnectionFailed which it probably shouldn't.

Sign up to request clarification or add additional context in comments.

1 Comment

I've seen the stackoverflow error mostly when this happened I recall, so this is probably it! Thank you, I will try this out.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.