Click here to Skip to main content
Click here to Skip to main content
Go to top

Real Time Exception Handling with Stack Trace

, 2 Feb 2008
Rate this:
Please Sign up or sign in to vote.
Handle all the exceptions easily

Introduction

Exception handling is the major activity in application life cycle and especially for VB6 platform which doesn't provide much support for exception handling natively. This article might help to focus on the best way to debug the deployment version of your applications and to find out the exact problem on client machines.

This article aims to provide you the following:

  1. Systematic method of error handling
  2. System exceptions (Ex Access Violation) handling
  3. Automatic creation of log information and
  4. Crash reporter including stack trace (Yes! Smile | :)

Background

How Debugger Works?

Windows provides an API named DebugActiveProcess to debug your applications. The debugger automatically receives the notifications from Windows for all exceptions of client process. Note that, debugging a process pauses all the threads of client application.

The client process can call OutputDebugString API to communicate with debugger. Normally application debugger handles the strings sent through OutputDebugString. If the application has no debugger, the system debugger handles the string. If the system debugger is also not active, string will be discarded.

Flow.jpg

Using the Code

How to Call Debugger?

StartDebug method of ClsErrorhandler class calls debugger by passing current process id as a parameter.

StartDebug(sDebuggerPath, sLogFilePath, sCrashStartApplication)

Using ErrorHandler Class

LogEvent Method

The application can call LogEvent method to pass the information to debugger. LogEvent method supports the following four functionalities:

S.No Type Usage
1 LogMessage Indicates as log message from application
2 vbError Indicates problem with application, but application can continue to execute
3 ApplicationError Indicates custom application error, but application can continue the operation
4 ApplicationCriticalError Indicates severe error and debugger will call crash application

Error Handling

Visual Basic provides On Error statement to handle the errors. Use this at the start of each procedure. TypeName functions return the name of class module and Form modules. For standard modules, you have to pass the name manually.

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 method automatically formats the error message from Error object received from the application.

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)"

Convert Windows Error Number to Error Message

'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

Converting DLL Error Number to Error Message

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

Raising Custom Errors

To raise custom application errors, call LogEvent method with your error description and pass ApplicationError as log type.

ObjErrorHandler.LogEvent "Pass your custom error message here", , ApplicationError 

Store Application Log

To raise custom application messages, call LogEvent method with your message and pass LogMessage as log type.

ObjErrorHandler.LogEvent "Sample Log Current Time : " & Now, , LogMessage 

Crash Report

If debugger found crash in application, it will automatically execute the crash reporter provided by the application.

crash.jpg

Error Handling in IDE

If you want to debug your code during the development phase, you can enable the ShowMessageBox property.

ObjErrorHandler.ShowMessageBox = True
Error.jpg

Stack Trace & Symbol File

The VB6 compiler provides the option to create symbol file (with extension PDB) through Create Symbol Debug info option of project properties window. By using this symbol file debugger maps the function address to names.

Project_properties_symbol.jpg

By default, address of functions are logged by debugger instead of function names on client machine to avoid security problems. After receiving report from the client, you can use Stack Converter tool to convert addresses to function names.

stack.jpg

But if you prefer, you can deploy symbol file (.pdb) on your client machine and can call DebugSendTrace method to log full stack trace with function name.

Points of Interest

There are no additional requirements to release this executable with your existing application. You can use this tool with Power basic and VC++ applications also. But this debugger has been designed and tested mainly for VB6 applications.

History

  • Release version 1.0 on 02/02/2008

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)

Share

About the Author

Sabarinathan A
Technical Lead Tech Mahindra
India India
I have been programming for last 10 years on various platforms including .NET, Visual Basic 6, Oracle and SQL server.
 
I decided to write articles when I have free time hoping to share my thoughts with you.
 
To know more about me visit http://sabarinathanarthanari.com
Follow on   Twitter

Comments and Discussions

 
QuestionBug Finder PinmemberAntonio Petricca7-Jun-13 0:13 
AnswerRe: Bug Finder PinmemberSabarinathan Arthanari21-Jun-13 3:24 
QuestionDebugger.exe and ProcedureFinder.exe PinmemberSteven Campbell8-Feb-08 6:16 
GeneralRe: Debugger.exe and ProcedureFinder.exe PinmemberSabarinathan Arthanari10-Feb-08 22:57 
Thank you for showing interest on this article. Because of license restrictions i can't release the source code of these executables.
 
Stack trace created based up on the techniques from Matt Curland's code to allow VB to determine the program's Instruction Pointer, Stack Pointer and Base Pointer and then use dbghelp.dll to translate these into readable descriptions.
 
To know how to develop debugger refer: http://www.codeproject.com/KB/vbscript/VB_Debugger2.aspx[^]
 
Sabarinathan Arthanari
As a child of God (Truth/Love), I am greater than anything that can happen to me -Dr APJ Abdul Kalam.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140916.1 | Last Updated 2 Feb 2008
Article Copyright 2008 by Sabarinathan A
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid