【问题标题】:Getting error from window service with Exception code: 0xc0000005使用异常代码从窗口服务获取错误:0xc0000005
【发布时间】:2020-03-20 21:26:43
【问题描述】:

我们在服务器上遇到错误,我们的服务在服务器中自动停止。 随机应用程序在大约 1 小时内崩溃,错误如下 -

错误的应用程序名称:Chubb.Studio.Event.Processor.exe,版本: 0.0.0.0,时间戳:0x5c0ab1b7 错误模块名称:KERNELBASE.dll,版本:6.3.9600.19425,时间戳:0x5d26b6e9 异常代码: 0xc0000005 故障偏移量:0x0000000000001556 故障进程 ID: 0x115c 故障应用程序启动时间:0x01d5a35fd202f96d 故障 申请途径: E:\WindowsService\DevInt\Chubb.Studio.EventProcessor\Chubb.Studio.Event.Processor.exe 错误模块路径:C:\Windows\system32\KERNELBASE.dll 报告 ID: 762c15d4-0f5b-11ea-8120-005056a27597 故障包全名: 错误的包相关应用程序 ID:

我们的代码看起来像 -

   protected override void OnStarted()
    {
        //IntializeEventsExecution();
        Task task = Task.Factory.StartNew(() => IntializeEventsExecution());

        base.OnStarted();

    }

    public void IntializeEventsExecution()
    {
        StartEvents();

    }

    public void StartEvents()
    {
        var eventList = GetEventTopics();
        Parallel.ForEach(eventList,
           new ParallelOptions { MaxDegreeOfParallelism = eventList.Count },
           (item, state, index) =>
           {
               StartProcessingEvent(eventList[(int)index]);
           });
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="index"></param>
    public void StartProcessingEvent(EventTopic topic)
    {
        try
        {
            Task task = Task.Factory.StartNew(() => ExecuteProcessingEvent(topic));
            task.Wait();                
        }
        catch (Exception)
        {
        }
        finally
        {

            new _processingDelegate(StartProcessingEvent).Invoke(topic);

        }
    }

【问题讨论】:

  • 我认为您需要做更多的工作才能让这里的任何人提供帮助。 Windows 服务可能很难调试,因为您并不总是得到有用的错误。您将需要添加大量具有非常好的日志记录的 try-catch,以便您可以准确找出服务失败的原因。
  • 0xC0000005 是 STATUS_ACCESS_VIOLATION 这意味着某些代码正在读取或写入不允许的内存。

标签: c# windows-services


【解决方案1】:

正如 Klaus 在评论中所说,STATUS_ACCESS-VIOLATION 异常是由进程读取或写入不属于它的内存引起的。鉴于这是 C#,最可能的原因是错误使用了 P/Invoke 或使用了 unsafe code

调试此类模糊问题的最佳方法是通过逐个删除 P/Invoke 调用来隔离问题,直到不发生异常。很难更精确,因为异常触发的原因可能与原因(内存或堆栈损坏)相距甚远。

This SO answer 很好地列出了托管代码中访问冲突的可能原因。

托管应用中的访问冲突通常发生在其中一种情况下 原因:

  • 您 P/Invoke 将句柄传递给托管对象的本机 API,并且本机 API 使用该句柄。如果你得到一个集合和 在本地 API 运行时进行压缩,托管对象可能 移动,指针变为无效。
  • 您 P/Invoke 的缓冲区太小或小于您传入的大小,并且 API 超出了读取或写入速度
  • 传递给 P/Invoke 调用的指针(IntPtr 等)无效(-1 或 0),并且本机在使用前未对其进行检查
  • 您 P/Invoke 本机调用,本机代码耗尽内存(通常是虚拟的)并且没有检查失败的分配和 读取/写入无效地址
  • 您使用了一个未初始化的 GCHandle,或者它以某种方式指向一个已经完成并收集的对象(所以它不是 指向一个对象,它指向一个对象所在的地址 曾经)
  • 您的应用程序使用了一个句柄来处理因睡眠/唤醒而无效的内容。这更深奥,但肯定会发生。例如, 如果您正在使用存储卡运行应用程序,则整个应用程序 未加载到 RAM 中。使用中的部件被需求页面用于 执行。这一切都很好。现在,如果您关闭设备电源, 驱动程序全部关闭。当您重新启动电源时,许多设备只需 重新安装存储设备。当您的应用需要请求页面时 更多的程序,它不再是它原来的地方,它死了。相似的 安装存储上的数据库可能会发生这种行为。如果你有一个 打开数据库句柄,在睡眠/唤醒周期后连接 句柄可能不再有效。

【讨论】:

    猜你喜欢
    • 2018-05-23
    • 1970-01-01
    • 2013-06-14
    • 2020-04-05
    • 1970-01-01
    • 2012-12-03
    • 2010-12-19
    • 2013-01-29
    相关资源
    最近更新 更多