实时异常处理带堆栈跟踪






2.33/5 (5投票s)
轻松处理所有异常
引言
异常处理是应用程序生命周期中的主要活动,特别是对于 VB6 平台,它本身对异常处理的支持不多。本文可能有助于您专注于调试应用程序部署版本的最佳方法,并找出客户端计算机上的确切问题。
本文旨在为您提供以下内容:
- 系统的错误处理方法
- 系统异常(例如访问冲突)处理
- 自动创建日志信息,以及
- 崩溃报告器,包括堆栈跟踪(是的!:-)
背景
调试器如何工作?
Windows 提供了一个名为 DebugActiveProcess
的 API 来调试您的应用程序。调试器会自动从 Windows 接收来自客户端进程的所有异常通知。请注意,调试进程会暂停客户端应用程序的所有线程。
客户端进程可以调用 OutputDebugString
API 来与调试器通信。通常,应用程序调试器处理通过 OutputDebugString
发送的 string
。如果应用程序没有调试器,则系统调试器处理 string
。如果系统调试器也未激活,则 string
将被丢弃。

Using the Code
如何调用调试器?
ClsErrorhandler
类的 StartDebug
方法通过传递当前进程 ID 作为参数来调用调试器。
StartDebug(sDebuggerPath, sLogFilePath, sCrashStartApplication)
使用 ErrorHandler 类
LogEvent 方法
应用程序可以调用 LogEvent
方法将信息传递给调试器。 LogEvent
方法支持以下四个功能:
序号 | 类型 | 用法 |
1 | LogMessage |
表示来自应用程序的日志消息 |
2 | vbError |
表示应用程序存在问题,但应用程序可以继续执行 |
3 | ApplicationError |
表示自定义应用程序错误,但应用程序可以继续运行 |
4 | ApplicationCriticalError |
表示严重错误,调试器将调用崩溃应用程序 |
错误处理
Visual Basic 提供了 On Error 语句来处理错误。在每个过程的开始使用它。 TypeName
函数返回类模块和窗体模块的名称。对于标准模块,您必须手动传递名称。
Private Sub CmdErrorHandle_Click()
On Error GoTo Errorhandler
Dim Dummy As Integer
'Raise Division by zero error
Dummy = 10 / Dummy
Exit Sub
Errorhandler: ObjErrorHandler.LogEvent TypeName(Me) & _
"::CmdErrorHandle_Click", Err, ApplicationCriticalError
End Sub
LogEvent
方法自动格式化从应用程序收到的 Error
对象中的错误消息。
lLastDllError = LError.LastDllError
'Call appropriate Module to get the error message from error number
If lLastDllError > 12000 Then
sDLLMessage = DebugErrorDescriptionWininet(lLastDllError)
If sDLLMessage <> "" Then lsAPIError = "WinInet Error _
(" & lLastDllError & ") " & sDLLMessage
ElseIf lLastDllError > 0 Then
sDLLMessage = DebugErrorDescriptionWindows(lLastDllError)
If sDLLMessage <> "" Then lsAPIError = "Windows Error _
(" & lLastDllError & ") " & sDLLMessage
End If
'Get VB error message
If LError.Number <> 0 Then
lsMessage = "Error (#" & Trim$(Str(LError.Number)) & "-" _
& lLastDllError & ")-" & LError.Description & ", " & vbNewLine
End If
If lsAPIError <> "" Then lsMessage = lsMessage & lsAPIError & ", " & vbNewLine
'Get the module which generates error
If LError.Source <> "" Then sSource = " (generated by " & LError.Source & " Module)"
将 Windows 错误代码转换为错误消息
'Convert the Windows error number to meaningful error message.
Public Function DebugErrorDescriptionWindows_
(Optional ByVal lErrNumber As Long = -1) As String
Dim strBuffer As String * 257
Dim dwLength As Long
If lErrNumber = -1 Then lErrNumber = GetLastError
dwLength = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM Or FORMAT_MESSAGE_IGNORE_INSERTS _
Or FORMAT_MESSAGE_MAX_WIDTH_MASK, ByVal 0&, lErrNumber, LANG_ENGLISH, _
ByVal strBuffer, 256&, 0&)
If dwLength > 0 Then DebugErrorDescriptionWindows = Left$(strBuffer, dwLength)
End Function
将 DLL 错误代码转换为错误消息
Public Function DebugErrorDescriptionWininet(lErrNumber As Long) As String
Dim strBuffer As String * 257
Dim dwLength As Long
Dim hModule As Long
Dim bLoadLib As Boolean
'Get the handle if dll is already loaded by current process
hModule = GetModuleHandle("wininet.dll")
If hModule = 0 Then
'if DLL is not loaded already, load it now
hModule = LoadLibrary("wininet.dll")
bLoadLib = True
End If
dwLength = FormatMessage(FORMAT_MESSAGE_FROM_HMODULE, _
ByVal hModule, lErrNumber, 0&, ByVal strBuffer, 256&, 0&)
If dwLength > 0 Then DebugErrorDescriptionWininet = Left$(strBuffer, dwLength - 2)
If bLoadLib Then FreeLibrary hModule
'if DLL is loaded for this function then unload it
End Function
引发自定义错误
要引发自定义应用程序错误,请使用您的错误描述调用 LogEvent
方法,并将 ApplicationError
作为日志类型传递。
ObjErrorHandler.LogEvent "Pass your custom error message here", , ApplicationError
存储应用程序日志
要引发自定义应用程序消息,请使用您的消息调用 LogEvent
方法,并将 LogMessage
作为日志类型传递。
ObjErrorHandler.LogEvent "Sample Log Current Time : " & Now, , LogMessage
崩溃报告
如果调试器在应用程序中发现崩溃,它将自动执行应用程序提供的崩溃报告器。

IDE 中的错误处理
如果您想在开发阶段调试代码,您可以启用 ShowMessageBox
属性。
ObjErrorHandler.ShowMessageBox = True

堆栈跟踪 & 符号文件
VB6 编译器提供了通过项目属性窗口的“创建符号调试信息”选项来创建符号文件(扩展名为 PDB)的选项。通过使用此符号文件,调试器将函数地址映射到名称。

默认情况下,为了避免安全问题,调试器记录的是客户端计算机上的函数地址,而不是函数名称。收到客户端的报告后,您可以使用 Stack Converter 工具将地址转换为函数名称。

但是,如果您愿意,您可以在客户端计算机上部署符号文件 (.pdb),并可以调用 DebugSendTrace
方法来记录带有函数名称的完整堆栈跟踪。
关注点
没有其他要求可以将此可执行文件与您现有的应用程序一起发布。您也可以将此工具与 Power Basic 和 VC++ 应用程序一起使用。但是,此调试器主要针对 VB6 应用程序进行了设计和测试。
历史
- 2008 年 2 月 2 日发布版本 1.0