问题描述
我们产生崩溃使用自动化的崩溃报告工具(即 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检测的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!