skip to Main Content

I have an ASP.NET Core 3.1 MVC application. In my controller, I am performing XSLT transformation. I have a transformation that is causing stack overflow exception, shutting my whole (VS-hosted) server down.

I know what is wrong with my transformation, so I do not want to fix it (I’ll do it later), for now I want to be able to correctly handle scenarios where a stack overflow causes unpredicated behavior. My idea is to create a new child thread, and in this thread process the XSLT, if the thread runs for too long, I would like to kill it in the parent thread.

Now that’s for theory, in practice, when I do this, parent thread gets locked out, debugger is not moving forward and everything crashes. Below is one of many examples of code that I have tried – I tried Task.Run() and CancellationToken approach, I tried it with Task.Wait(1000), I tried new Thread(()=>MyFunction()) approach, I tried calling xslt.Transform() as you see below, but I also tried to wrap 100% of transformation codebase in a separate method, pass immutable props to it and have 100% of activity to happen on that thread. I tried cross-referencing variables (as you see below with transformedMessage = (...)), I tried returning transformed message and awaiting for it from Task / Joining a thread. Lastly, I also tried for loop with a Thread.Sleep on parent thread, to see if I can manually abort that child thread after few loops.

I tried a lot, and none of my approaches work – Visual Studio always, first hangs for few minutes, then throws stack overflow exception on that xslt.Transform – I am definitely missing something here in my approach.

A long post, so here is the question: Why does a child thread with a stack overflow exception blocks parent thread from continuing being processed? Perhaps it has something to do with .Net core/MVC and the way VS built in server handles things? Is this a bug in VS/.Net core, or I am unaware of something when it comes to parallel processing?

using (var tokenSource = new CancellationTokenSource(1000)) {
    try {
        var token = tokenSource.Token;
        var task = Task.Run(()=>{
            xslt.Transform(xri, args, xwo);
            transformedMessage = sw.ToString();
        }, token);
        await task; //don't focus on this, it's just one of many versions I have tried, debugger does not even reach this point
    } catch (TaskCanceledException) {
        throw new TimeoutException("Timeout");
    }
}

2

Answers


  1. Stackoverflow exceptions are unrecoverable exceptions. You cannot handle it, and need to fix that issue. You can spawn new threads to avoid the stack overflow in the first place, but stackoverflows are terminal and crash the process.

    Login or Signup to reply.
  2. As others have stated stack overflows are special. You need to fix the root cause. Here’s what the docs have to say about it…

    Starting with the .NET Framework 2.0, you can’t catch a StackOverflowException object with a try/catch block, and the corresponding process is terminated by default. Consequently, you should write your code to detect and prevent a stack overflow.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search