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

标签 c# stack-overflow

我的服务器出现StackOverflowException。它有超过 20,000 行代码,我找不到它被抛出的位置...因为 try/catch 不起作用,我无法获取错误...有什么方法可以获取错误日志吗? UnhandledExceptionEventHandler 没有记录它,所以...我怎样才能在它使我的服务器崩溃之前检测到它并记录错误?您也可以建议我如何找到 StackOverflowException :)

我使用的是 .NET Framework 4.5

UnhandledExceptionEventHandler代码:

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());
}

图片:

Error message

最佳答案

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

如果异常发生在您自己的代码中,最好的解决方案是将您的算法从递归调用转换为使用堆分配的 Stack<T> 的算法跟踪深度状态,并且还允许您捕获堆栈容量超过阈值的情况( 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;
}

如果您觉得必须使用递归调用,请向您的方法添加一个名为“深度”的附加整数参数(每次递归调用都会增加)。在你的函数中,你可以检查你的深度,并在出现堆栈溢出之前中断。

示例:

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
    }
}

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

关于c# - 如何在 StackOverflowException 捕获之前检测并记录错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22082794/

相关文章:

c# - 相对无特征物体的图像配准技术

将字符数组从主机复制到设备后,CUDA: "Stack Overflow or Breakpoint Hit"和未指定的启动失败错误

javascript - JSON .each 上的调用堆栈溢出

c# - 数据绑定(bind)、属性更改事件

c# - 如何在 WinRT XAML C# 中克隆 UIElement?

c# - 防止对 MVC 的蛮力攻击

c# - 我应该如何调用重载的扩展方法?

node.js - 如何在API导入请求期间避免 "Allocation failed - JavaScript heap out of memory"

c++ - 将数组传递给 C++ 中的函数时如何避免堆栈溢出?

linux - 用户态stack-overflow漏洞利用时如何绕过stack canary?