一尘不染

如何防止和/或处理StackOverflowException?

c#

我想防止或处理我正在编写StackOverflowExceptionXslCompiledTransform.Transform方法中从调用中得到的a
Xsl Editor。问题似乎在于用户可以编写一个Xsl script无限递归的,并且只会在调用该Transform方法时炸毁。(也就是说,问题不仅是典型的程序错误,通常是此类异常的原因。)

有没有一种方法可以检测和/或限制允许的递归次数?还是有其他想法可以防止此代码对我产生负面影响?


阅读 500

收藏
2020-05-19

共1个答案

一尘不染

从Microsoft:

从.NET Framework 2.0版开始,try-
catch块无法捕获Exception对象,并且默认情况下终止了相应的进程。因此,建议用户编写其代码以检测并防止堆栈溢出。例如,如果您的应用程序依赖于递归,请使用计数器或状态条件终止递归循环。

我假设异常发生在内部.NET方法中,而不是您的代码中。

您可以做几件事。

  • 编写代码,检查xsl的无限递归并在应用变换(Ugh)之前通知用户。
  • 将XslTransform代码加载到一个单独的进程中(麻烦,但工作较少)。

您可以使用Process类来加载将转换应用到单独流程中的程序集,并在失败后向用户警告失败,而不会终止您的主应用程序。

编辑:我刚刚测试,这是怎么做的:

主流程:

// This is just an example, obviously you'll want to pass args to this.
Process p1 = new Process();
p1.StartInfo.FileName = "ApplyTransform.exe";
p1.StartInfo.UseShellExecute = false;
p1.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;

p1.Start();
p1.WaitForExit();

if (p1.ExitCode == 1)    
   Console.WriteLine("StackOverflow was thrown");

ApplyTransform流程:

class Program
{
    static void Main(string[] args)
    {
        AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
        throw new StackOverflowException();
    }

    // We trap this, we can't save the process, 
    // but we can prevent the "ILLEGAL OPERATION" window 
    static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        if (e.IsTerminating)
        {
            Environment.Exit(1);
        }
    }
}
2020-05-19