VB.NET在WinCE5.0中异常转储试验

1.目的:

在CE系统上,当程序发生异常特别是不可重现的异常时,通过事后调试协助快速定位问题

2.原理:

在windows系统中,当应用程序出现严重错误无法运行时,系统会启动JIT调试器,JIT调试器可以做两类事情:1)直接附加到出错进程上通过调试来分析、定位问题。2)收集、记录错误发生时的现场数据提供事后分析。在WinCE上,希望利用第二种方式:也就是使用WER(Windwos Error Reporting)功能生成转储文件(dump文件)来进行事后分析。

3.实现

3.1捕获异常

转储文件是对特定进程、线程在内存中运行状态的快照,只有在异常发生时产生的快照才对我们查找问题有意义,因此首先需要捕获异常,捕获异常为我们生成转储文件提供了时机以及必要的上下文环境,例如只有在异常被捕获的状态下,Native的GetExceptioninformation和CLR的GetExceptionPointers才能获取到PEXCEPTION_POINTERS指针。我把捕获异常的方式分成3种:

3.1.1语法

编程语言都提供了异常捕获的语法关键字,例如对于C++和VB .NET:

C++ SEH

vb .net

__try __except

try catch

在try 块中发生异常以后,程序跳转到异常处理块中,在异常处理块中我们可以进行异常转储。


使用VB.NET的try catch得到异常转储的时机(仅仅是个时机)

3.1.2未处理异常过滤器或事件

Windows Native

Windows CLR

SetUnhandledExceptionFilter

Application..::.ThreadException

_AppDomain..::.UnhandledException

l SetUnhandledExceptionFilter

一个应用的所有进程和线程设置一个顶级异常处理函数

l Application..::.ThreadException

UI线程产生的异常处理事件

l _AppDomain..::.UnhandledException

非UI线程产生的异常处理事件

WinCE不提供SetUnhandledExceptionFilter

cf .net 不提供Application..::.ThreadException和_AppDomain..::.UnhandledException

3.1.3 JIT调试

如果所有其它异常捕获机制都没有生效,系统根据注册表的设置尝试使用JIT调试器来分析问题。windows认的jit调试器是Dr.Watson,它将为出错程序生成一个转储文件

WinCE从5.0开始加入WER模块(windowserror reporting),也是为出错的程序生成转储文件

这种方式下系统自动生成dump。

EVC程序可以生成dump,VB.NET程序无法生成dump。

3.2获取异常结构体指针

因为3.1.2和3.1.3都不可行,因此采用3.1.1的方式继续尝试。在捕获异常以后,要想保存转储文件,需要先获取异常结构指针。系统提供了以下函数

Windows Native

Windows CLR

GetExceptioninformation

GetExceptionPointers

WinCE提供了GetExceptioninformation,但GetExceptioninformation并不是函数,而是一个宏,并且只允许在异常处理过滤表达式中调用,这意味着VB.NET代码无法通过P/Invoke调用GetExceptioninformation。

cf .net不提供GetExceptionPointers

结论是VB.NET无法获取异常结构体指针

3.3生成转储文件

在Windows中获取到正确的异常结构指针以后,就可以调用MiniDumpWriteDump保存转储文件,但是在CE5.0并没有MiniDumpWriteDump,它使用了CaptureDumpFileOnDevice和ReportFault。

Windows Native

WinCE 5.0

MiniDumpWriteDump

CaptureDumpFileOnDevice

ReportFault

VB.NET适用性:

1. 虽然wince提供了ReportFault,但是因为3.2的结论,导致VB.NET无法调用ReportFault(异常结构指针参数无法获取)。

2.CaptureDumpFileOnDevice通过试验可以产生dump,但是这个函数的参数是进程号和线程号,也就是说它无法保存异常发生时的状态。尝试了在VB.NET程序中P/InvokeCaptureDumpFileOnDevice,分析产生的dump文件发现堆栈信息缺少了托管代码的部分:

4.总结:

1)EVC程序既可以使用JIT也可以使用编程方式实现异常转储

2)VB.NET程序无法实现异常转储

相关文章

Format[$] ( expr [ , fmt ] ) format 返回变体型 format$ 强...
VB6或者ASP 格式化时间为 MM/dd/yyyy 格式,竟然没有好的办...
在项目中添加如下代码:新建窗口来显示异常信息。 Namespace...
转了这一篇文章,原来一直想用C#做k3的插件开发,vb没有C#用...
Sub 分列() ‘以空格为分隔符,连续空格只算1个。对所选...
  窗体代码 1 Private Sub Text1_OLEDragDrop(Data As Dat...