天色崩溃的应用程序?我如何能赶上不可捕获的异常? [英] Partly crashing application? How can I catch uncatchable exceptions?

查看:103
本文介绍了天色崩溃的应用程序?我如何能赶上不可捕获的异常?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用C#编写一个程序,在Windows CE设备上运行(在Compact Framework的)。它处理最少的用户操作(点击按钮),使用串行端口和TCP / IP通讯。

I have a program written in C#, running on a Windows CE device (on Compact Framework). It processes minimal user actions (button clicks), uses serial port and TCP/IP communication.

但问题是有时软件关闭自身。
在后台的应用程序(或应用程序的一部分)似乎仍在运行(至少在一个记录的情况下,它是),因为它使用串行端口,所以重新启动应用程序并不能帮助。因为它发生在大多数的情况下,在没有用户交互,我不能重现该问题,没有串口通信和网络通信都是我还活着的消息,该软件只是崩溃看似没有道理。 (我尽量做到在调试模式下碰巧知道至少是在代码中的问题,如果它是一个软件错误,但到目前为止,我还没有运气。)

The problem is sometimes the software shuts down on its own. In the background the application (or parts of the application) seems to be still running (at least in one documented case it was) because it uses the serial port, so restarting the application doesn't help. I can't reproduce the problem since it happens in most of the cases when there is no user interaction, no serial port communication and the network communication is all "I am still alive" messages, the software just crashes seemingly without reason. (I try to make it happen in debug mode to know at least where is the problem in the code if it is a software bug but I have had no luck so far.)

由于我运行的想法,问题是:什么错误或异常或OS操作或硬件故障可能会导致这样的行为呢?

Since I'm running out of ideas, the question is: what bug or exception or OS action or hardware malfunction can cause such a behaviour?

问题已经看到的相同类型的不同设备,因此它不应该是一个硬件错误。 (或所有我的硬件都有同样的错误。)例外情况处理,所以它不应该是一个例外。未处理的异常被处理过,所以它不应该是一个未处理的异常无论是。 (我的猜测是,它是由引起 StackoverflowException ,因为我不知道,不能被捕获其他任何异常,但没有递归的代码,至少不是心甘情愿,所以它不应该是一个可能性,无论是。)

The problem has been seen on different devices of the same type, so it shouldn't be a hardware error. (Or all my hardware has the same error.) Exceptions are handled, so it shouldn't be an exception. Unhandled exceptions are handled too, so it shouldn't be an unhandled exception either. (My guess is that it is caused by a StackoverflowException because I don't know any other exceptions that can't be caught, but there isn't recursion in the code, at least not willingly, so it shouldn't be a possibility either.)

推荐答案

颇有些例外不能被捕获以及这些从.NET版本的.NET版本不同。而一些例外可以被捕获和记录,但不能从(内存除外)恢复。但是,它是可以调试它们(这些被称为第一个机会异常,第一次有机会永远是为调试,第二次机会的代码,这要归功于JeroenH指出这点)。下面是在CodeProject一个职位,说明这一点原则。

Quite some exceptions cannot be caught and which these are differs from .NET version to .NET version. And some exceptions can be caught and logged, but cannot be recovered from (memory exceptions). However, it is possible to debug them (these are called first chance exceptions, the first chance is always for the debugger, the second chance is for the code, thanks to JeroenH for pointing this out). Here's a post at CodeProject that explains this principle.

你应该做的是选择在Visual Studio中的一些候选例外您怀疑可能发生,并且调试器附加到正在运行的实例。

What you should do is select some candidate exceptions in Visual Studio that you suspect might occur, and attach the debugger to the running instance.

有非托管资源,你有(串口)意味着你可以有非托管泄漏(不使用的IDisposable + 使用正确)和非托管异常。这些异常只能用一个空抓陷入(即,甚至没有异常规格,这是的在try / catch块非托管例外)的母公司

Having unmanaged resources as you have (serial port) means you can have unmanaged leaks (not using IDisposable + using properly) and unmanaged exceptions. These exceptions can only be caught with an empty catch (i.e., without specification of even Exception, which is not the parent of unmanaged exceptions) in a try/catch block.

PS:当例外finally块或终结上调可能会出现一些不确定的行为/析构函数。此外,并非许多例外传播跨线程边界,并终止所有的线程。

PS: some undefined behavior can occur when exceptions are raised in finally blocks or in finalizers/destructors. Also, not many exceptions propagate across thread boundaries and terminate all threads.

为了让事情有点更明确的,也有少数例外,该CLR(及其规范)定义为非捕。基本上,这些都是跨线程边界的所有异常。这些异步异常,锁内发生时,会导致国家腐败。最有名的是 OutOfMemoryException异常 ThreadAbortException StackOverflowException 。当 OutOfMemoryException异常 StackOverflowException 发生在同步码,这是不可能的,你可以纠正国家和CLR将终止您的应用程序

To make things a little clearer, there are a few exceptions that the CLR (and its specification) define as non-catchable. Basically, these are all exceptions that cross thread boundaries. These asynchronous exceptions, when occurring within a lock, will result in state corruption. Best known are OutOfMemoryException, ThreadAbortException and StackOverflowException. When the OutOfMemoryException or StackOverflowException occurs in synchronous code, it's unlikely that you can correct state and the CLR will terminate your application.

另外还有的 ExecutionEngineException BadImageFormatException 这在可验证代码不应该发生的,不应该被抓住。例外,如 TypeLoadException MissingMemberException 有时可以抓住,有时不是(如果链接的组件丢失,这是。马上就很难赶上这些了,你不应该,但如果你使用反射,你应该抓住这些)

In addition there's the ExecutionEngineException and BadImageFormatException which should not happen in verifiable code and should not be caught. Exceptions such as the TypeLoadException and MissingMemberException can sometimes be caught and sometimes not (if a linked assembly is missing, it'll be hard to catch these, and you shouldn't, but if you use reflection, you should catch these).

在短期:异常应该在线程被抓它们发生在你将不能够,如果他们在另一个线程正好赶上例外,因为它们不会传播(与例外的 ThreadAbortException )。您的应用程序异常后保持活着(至少,你认为),所以它是合乎逻辑的假设该异常不能在你试图赶上它的线程发生。使用调试>例外窗口中,您可以选择任何异常,就当它们发生代码打破。

In short: exceptions should be caught in the thread they happen in. You will not be able to catch exceptions if they happen in another thread, because they are not propagated (with the exception of the ThreadAbortException). Your application stays alive after an exception (at least, you think), so it is logical to assume that the exception doesn't happen in the thread where you're trying to catch it. Using the Debug > Exceptions window, you can select any exception and break on the code when they happen.

这是加在托管和非托管异常音符。你抓不到使用赶上(例外五)非托管异常,因为非托管异常不从异常继承。相反,使用空抓,这将捕获你的任何非托管异常。这个包裹在你的应用程序和线程入口点的方法,你应该能够赶上多数开捕异常。

An added note on managed and unmanaged exceptions. You cannot catch an unmanaged exception using catch (Exception e), because the unmanaged exception does not inherit from Exception. Instead, use an empty catch, which will trap any unmanaged exception for you. Wrap this around your application and thread entrypoint methods and you should be able to catch the majority of catchable exceptions.

这篇关于天色崩溃的应用程序?我如何能赶上不可捕获的异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆