C# 如何在捕获StackOverflowException之前检测并记录错误

C# 如何在捕获StackOverflowException之前检测并记录错误,c#,stack-overflow,C#,Stack Overflow,我的服务器有一个StackOverflowException。它有20000多行代码,我找不到它被抛出的地方。。。因为try/catch不起作用,我无法获取错误。。。有什么方法可以获取错误日志吗UnhandledExceptionEventHandler未记录它,因此。。。如何在服务器崩溃之前检测并记录错误?您也可以建议我如何找到StackOverflowException:) 我正在使用.NET Framework 4.5 未处理的ExceptionEventHandler代码: AppDom

我的服务器有一个
StackOverflowException
。它有20000多行代码,我找不到它被抛出的地方。。。因为try/catch不起作用,我无法获取错误。。。有什么方法可以获取错误日志吗
UnhandledExceptionEventHandler未记录它,因此。。。如何在服务器崩溃之前检测并记录错误?您也可以建议我如何找到
StackOverflowException
:)

我正在使用.NET Framework 4.5

未处理的ExceptionEventHandler代码:

AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(Program.UnhandledExceptionEventArgs);
private static void UnhandledExceptionEventArgs(object sender, UnhandledExceptionEventArgs e)
{
    Exception ex = (Exception)e.ExceptionObject;
    Console.WriteLine(ex.ToString());
}
图片:


根据,它建议在递归调用中放置一个递归计数器。为所有递归调用选择一个值,该值似乎太高,用正确的逻辑无法达到,比如10000 next deep。当你检测到这个数字那么高时,记录函数名、程序状态、函数堆栈,然后用它来调试为什么它会这么高的问题。

一般来说,你不能
StackOverflowException
是少数无法捕获的异常之一

如果异常发生在您自己的代码中,最好的解决方案是将您的算法从递归调用转换为使用堆分配的
Stack
跟踪深度状态的算法,这还允许您捕获堆栈容量超过阈值的情况(
If(Stack.Count>=4000)break;

enum Result {
    Found,
    NotFound,
    Aborted
}

public static Result DepthFirstSearch(Node node) {

    Stack<Node> stack = new Stack<Node>();
    stack.Push( node );

    while( stack.Count > 0 ) {

        Node n = stack.Pop();
        if( IsNodeWeWant( n ) ) return Result.Found;

        foreach(Node child in n.Children) stack.Push( child );

        if( stack.Count >= 4000 ) return Result.Aborted;

    }
    return Result.NotFound;
}

但是,如果异常发生在您的代码之外(并且您在输入之前无法验证数据以中止操作),那么您唯一的选择就是创建一个子进程来承载错误代码。您可以使用某种形式的IPC或共享内存进行通信(尽管您不能直接共享POCO,至少在没有序列化的情况下是如此)。

如果您有SO错误(没有双关语),你很可能有一些递归调用正在进行,但没有退出。你不能调试它吗?我在VPS上运行它,目前不想使用更多的RAM,可能它会阻塞其他错误,因此这很糟糕。是否可能运行另一个porgram,或者我只能使用visual studio调试它?我如何使用该堆栈?@user3290224我已经用示例更新了我的答案s、 我复制并粘贴了该示例,发现错误:错误1:找不到类型或命名空间名称“Node”(是否缺少using指令或程序集引用?)|错误2:当前上下文中不存在名称“IsNodeWant”|错误3:可访问性不一致:返回类型“ConsoleApplication1.Program.Result”比方法“ConsoleApplication1.Program.DepthFirstSearch(Node,int)更难访问internet和“Node”支持3.0和情人..我的程序使用4。5@user3290224不要复制和粘贴我的代码。我的代码是如何实现算法的示例。
节点
不是一个真正的类,但用于演示如何以安全的方式对任意图形节点结构执行深度优先遍历。
enum Result {
    Found,
    NotFound,
    Aborted
}

public static Result DepthFirstSearch(Node node, Int32 depth) {

    if( depth >= 4000 ) return Result.Aborted;

    if( IsNodeWeWant( node ) ) return Result.Found;

    foreach(Node child in node.Children) {
        Result result = DepthFirstSearch( child, depth + 1 );
        if( result != Result.NotFound ) return result; // return Found or Aborted
    }
}