如何强制应用程序崩溃时AccessViolationException检测 [英] How to force an application crash when AccessViolationException is detected

查看:549
本文介绍了如何强制应用程序崩溃时AccessViolationException检测的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们产生崩溃使用自动化的崩溃报告工具(即 http://crashrpt.sourceforge.net )报告。

We use an automated crash reporting tool (namely http://crashrpt.sourceforge.net) for generating crash reports.

因此​​,如果一块非托管code未能通过访问 NULL 指针,例如,应用程序崩溃,崩溃报告工具启动,我们得到有用的堆栈跟踪用于诊断和分组的问题。

So if a piece of unmanaged code fails by accessing a NULL pointer for example, the application crashes, the crash reporting tool activates and we get usable stack trace for diagnosing and grouping issues.

的问题是,.NET似乎干扰崩溃处理的情况。其中一个样本如下:

The problem is that .NET seems to interfere with crash handling in some cases. One sample is the following:

this.Dispatcher.BeginInvoke((ThreadStart)delegate
{
  // Send message to unmanaged control for performing a specific task.
  User32.SendMessage(...);
}, DispatcherPriority.Input);

如果非托管的组件,然后与访问冲突失败,内部.NET方法抓到什么实际上应该是一个崩溃的 AccessViolationException 和重新包装它在 TargetInvocationException 第一,然后崩溃(它不会做,没有使用方法调用)。

If the unmanaged component then fails with an access violation, internal .NET methods catch what should actually be a crash as AccessViolationException and rewrap it inside a TargetInvocationException first, then crashes (it would not do that without using method invocation).

这是非常不方便的,因为本地堆栈信息完全丢失。剩下的就是独立的确切位置在哪里的非托管部分失败以下堆栈:

This is highly inconvenient, because the native stack information is completely lost. What remains is the following stack, independently of where exactly the unmanaged part has failed:

kernelbase!RaiseException+0x6c
clr!RaiseTheExceptionInternalOnly+0x276
clr!RaiseTheException+0x86
clr!RaiseTheExceptionInternalOnly+0x30a
clr!RealCOMPlusThrow+0x2f
clr!ThrowInvokeMethodException+0xac
clr!RuntimeMethodHandle::InvokeMethod+0xa64
mscorlib_ni+0x2d37b1
mscorlib_ni+0x2cf92a
windowsbase_ni+0xd77b1
windowsbase_ni+0xd768a
windowsbase_ni+0xc2d5c
windowsbase_ni+0xc2c98
mscorlib_ni+0x302346
mscorlib_ni+0x302301
windowsbase_ni+0xc2b9b
windowsbase_ni+0xd640b
windowsbase_ni+0xd65ca
windowsbase_ni+0xd798b
windowsbase_ni+0xd78db
windowsbase_ni+0xd7756
windowsbase_ni+0xd768a
windowsbase_ni+0xd5cae
windowsbase_ni+0xd71e1
user32!InternalCallWinProc+0x23
user32!UserCallWinProcCheckWow+0x100
user32!DispatchMessageWorker+0x3ef
user32!DispatchMessageW+0x10
windowsbase_ni+0xddca8
windowsbase_ni+0xd5636
windowsbase_ni+0xd5325
windowsbase_ni+0xb27d3
presentationframework_ni+0x2721b7
presentationframework_ni+0x271e0f
presentationframework_ni+0x271baa
clr!CallDescrWorkerInternal+0x34
clr!CallDescrWorkerWithHandler+0x6b
clr!MethodDescCallSite::CallTargetWorker+0x152
clr!RunMain+0x1aa
clr!Assembly::ExecuteMainMethod+0x124
clr!SystemDomain::ExecuteMainMethod+0x614
clr!ExecuteEXE+0x4c
clr!_CorExeMainInternal+0xdc
clr!_CorExeMain+0x4d
mscoreei!_CorExeMain+0x10a
mscoree!ShellShim__CorExeMain+0x7d
mscoree!_CorExeMain_Exported+0x8
kernel32!BaseThreadInitThunk+0xe
ntdll!__RtlUserThreadStart+0x72
ntdll!_RtlUserThreadStart+0x1b

如何才能prevent那和强制应用程序立即崩溃时的非托管组件失败?

How can we prevent that and force the application to crash immediately when the unmanaged component fails?

推荐答案

试试这个:

this.Dispatcher.BeginInvoke((Action) delegate 
{
    User32.SendMessage(...);
}, DispatcherPriority.Input);

应用程序应该崩溃,你想让它的方式。

The application should crash the way you want it to.

大多数我见过的调用示例 Dispatcher.BeginInvoke()与匿名委托使用动作

Most of the examples I've seen that call Dispatcher.BeginInvoke() with an anonymous delegate use an Action.

  • <一个href="https://richnewman.word$p$pss.com/2012/12/03/tutorial-asynchronous-programming-async-and-await-for-beginners/" rel="nofollow">https://richnewman.word$p$pss.com/2012/12/03/tutorial-asynchronous-programming-async-and-await-for-beginners/
  • http://tech.pro/tutorial/800/working-用最WPF的调度
  • https://richnewman.wordpress.com/2012/12/03/tutorial-asynchronous-programming-async-and-await-for-beginners/
  • http://tech.pro/tutorial/800/working-with-the-wpf-dispatcher

为什么会出现这种情况?

Why does this happen?

看来,CLR code,在一路下滑:

It seems that the CLR code, way down in:

at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.DispatcherOperation.InvokeImpl()

调用一个动作使用反射直接,最其他代表被调用。

invokes an Action directly, most other delegates are invoked using reflection.

反射机制,将包裹在异常的 TargetInvocationException

The reflection mechanism will wrap exceptions in a TargetInvocationException.

请参阅这个答案另一个问题来解释。

See this answer to another question to explain.

其他特殊情况的代表,这将不换的例外是: DispatcherOperationCallback SendOrPostCallback ,虽然工作,他们必须调用一个参数。

Other special case delegates which will not wrap exceptions are: DispatcherOperationCallback and SendOrPostCallback, though to work they have to be called with a single argument.

this.Dispatcher.BeginInvoke(DispatcherPriority.Input,
    (SendOrPostCallback)(delegate(object o)
    {
        throw new AccessViolationException(o.ToString());
    }), "test");

这篇关于如何强制应用程序崩溃时AccessViolationException检测的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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