Difference between revisions of "Debugging"

From HashVB
Jump to: navigation, search
(Preliminary debugging information)
 
m (Reverted edit of 195.6.54.153, changed back to last version by Dee)
 
(9 intermediate revisions by 3 users not shown)
Line 1: Line 1:
 +
{{VB6}}
 
So, something is not working as it should do. There are a number things you can use to try and track the problem down.
 
So, something is not working as it should do. There are a number things you can use to try and track the problem down.
  
 
Please note that you should use [[Option Explicit]] in all your VB programs. This will cause you to declare all variables but will eliminate numerous problems with spelling mistakes in variable names and type conversion issues.
 
Please note that you should use [[Option Explicit]] in all your VB programs. This will cause you to declare all variables but will eliminate numerous problems with spelling mistakes in variable names and type conversion issues.
 +
 +
=In the VB development environment=
  
 
==Breakpoints==
 
==Breakpoints==
Line 28: Line 31:
  
 
The immediate window will allow you to view the output of the Debug.Print statement as well as running lines of code typed in.
 
The immediate window will allow you to view the output of the Debug.Print statement as well as running lines of code typed in.
 +
 +
=In the compiled program=
 +
 +
We've all said "It works here..." at some point. Bugs that only happen when compiled or running on a remote machine are the worst to track down as you can't use any of the techniques above. You still have a few things that may be of use to you though.
 +
 +
I use the following code to send a string to the [[#Immediate window|debug window]] (for when running in the IDE) as well as log it to a file and send it to [[OutputDebugString]]:
 +
 +
Public Sub DebugLog(ByVal Text As String)
 +
  Debug.Print Text
 +
  #If Debugging Then
 +
  OutputDebugString Text & vbCrLf
 +
 +
Dim FileNum As Integer
 +
  FileNum = FreeFile
 +
  Open "C:\" & App.Name & "-" & CStr(App.ThreadID) & ".log" For Append As #FileNum
 +
  Print #FileNum, Text
 +
  Close #FileNum
 +
  #End If
 +
End Sub
 +
 +
If you call this procedure throughout your code where the problem is, you can see exactly what the program is doing at that point. You can also send the values of variables to this procedure to log them.
 +
 +
The log file can then be sent to you for analysis or you can use a utility like [http://www.sysinternals.com/Utilities/DebugView.html DebugView] from [http://www.sysinternals.com/ SysInternals] to monitor it live while it is running. You can also use this over a lan connection.
 +
 +
Please note that you will need to add "Debugging = -1" in the conditional compile option in project properties. If this is not set or is 0, the debug logging is disabled. Additionally, OutputDebugString will block while other applications are calling it so it is not a good idea to leave this in a production version.
 +
 +
== Advanced debugging ==
 +
 +
If you are having problems with access violations or random crashes that are very difficult to narrow down, you still have an option available.
 +
 +
Microsoft has a debugging suite called WinDbg which is part of the Platform SDK tools and it is available from [http://www.microsoft.com/whdc/devtools/debugging/default.mspx Microsoft's site].
 +
 +
To make full use of its powerful features, you need to enable "Create Symbolic Debug Info" in a projects compile settings and create a map file by adding a LINK environment variable containing "/map /mapinfo:lines". This will create a .pdb and a .map file along side your .exe file when compiling. These are specific to a build of your .exe file so you need to copy them to the machine you perform the debugging on.
 +
 +
Once your app is running, you can start up WinDbg and "Attach" to your process. This will cause it to "pause" your application until you type <code>g<enter></code> into the command window. This tells it to continue.
 +
 +
When your application crashes, you will get an error displayed in the command window showing what happened where. If you then select call stack from the view menu, you will see where the error occurred, and if it is in your code, it will highlight the VB line. Viewing the Locals window will show you all the variables and their values.
 +
 +
When you have finished investigating, type <code>g<enter></code> into the command window and it will carry on.
 +
 +
''Please note that you can't "detach" from your process without terminating it.''
 +
 +
=Further information=
  
 
If you have tried these and still can't see what is going wrong, feel free to ask in #VB on [http://www.undernet.org Undernet] at [irc://irc.undernet.org/vb irc.undernet.org].
 
If you have tried these and still can't see what is going wrong, feel free to ask in #VB on [http://www.undernet.org Undernet] at [irc://irc.undernet.org/vb irc.undernet.org].
 +
 +
=See also=
 +
 +
* [http://evil-geni.us/~irbme/Public/programming/debugging.pdf Debugging Visual Basic 6 Code (PDF)]
 +
* [http://www.microsoft.com/whdc/devtools/debugging/default.mspx Windows Debugging tools]

Latest revision as of 13:16, 8 March 2006

float
 This article is based on Visual Basic 6. Find other Visual Basic 6 articles.

So, something is not working as it should do. There are a number things you can use to try and track the problem down.

Please note that you should use Option Explicit in all your VB programs. This will cause you to declare all variables but will eliminate numerous problems with spelling mistakes in variable names and type conversion issues.

In the VB development environment

Breakpoints

Breakpoints will pause the execution of the program where that point is encountered. This allows you to use the Info tips and the Watch/Locals window to monitor variables at certain points in the program and step through the code.

You can toggle a breakpoint on any executable line by pressing F9 or clicking adjacent to the line in the grey bar on the left. If you need to immediately pause a running program, you can use CTRL+Break or press the pause button in the VB IDE. You can also use the Stop statement which will break a running program but if left in a compiled program, it will be a fatal error and terminate the program.

Single stepping

Single stepping is a feature of the Visual basic environment that allows you to step through the code a line at a time using the F8 key.

Info tips

While in break mode, VB allows you to hover over a variable or expression to see its value. This will also call a function and show the result.

Watch/Locals window

The Watch and Locals windows allow you to see the state of various variables and expressions while stepping through the code or in break mode. It also allows you to add a watch to break when a variable changes value or becomes true.

Immediate window

The immediate window will allow you to view the output of the Debug.Print statement as well as running lines of code typed in.

In the compiled program

We've all said "It works here..." at some point. Bugs that only happen when compiled or running on a remote machine are the worst to track down as you can't use any of the techniques above. You still have a few things that may be of use to you though.

I use the following code to send a string to the debug window (for when running in the IDE) as well as log it to a file and send it to OutputDebugString:

Public Sub DebugLog(ByVal Text As String)
  Debug.Print Text
  #If Debugging Then
  OutputDebugString Text & vbCrLf

Dim FileNum As Integer
  FileNum = FreeFile
  Open "C:\" & App.Name & "-" & CStr(App.ThreadID) & ".log" For Append As #FileNum
  Print #FileNum, Text
  Close #FileNum
  #End If
End Sub

If you call this procedure throughout your code where the problem is, you can see exactly what the program is doing at that point. You can also send the values of variables to this procedure to log them.

The log file can then be sent to you for analysis or you can use a utility like DebugView from SysInternals to monitor it live while it is running. You can also use this over a lan connection.

Please note that you will need to add "Debugging = -1" in the conditional compile option in project properties. If this is not set or is 0, the debug logging is disabled. Additionally, OutputDebugString will block while other applications are calling it so it is not a good idea to leave this in a production version.

Advanced debugging

If you are having problems with access violations or random crashes that are very difficult to narrow down, you still have an option available.

Microsoft has a debugging suite called WinDbg which is part of the Platform SDK tools and it is available from Microsoft's site.

To make full use of its powerful features, you need to enable "Create Symbolic Debug Info" in a projects compile settings and create a map file by adding a LINK environment variable containing "/map /mapinfo:lines". This will create a .pdb and a .map file along side your .exe file when compiling. These are specific to a build of your .exe file so you need to copy them to the machine you perform the debugging on.

Once your app is running, you can start up WinDbg and "Attach" to your process. This will cause it to "pause" your application until you type g<enter> into the command window. This tells it to continue.

When your application crashes, you will get an error displayed in the command window showing what happened where. If you then select call stack from the view menu, you will see where the error occurred, and if it is in your code, it will highlight the VB line. Viewing the Locals window will show you all the variables and their values.

When you have finished investigating, type g<enter> into the command window and it will carry on.

Please note that you can't "detach" from your process without terminating it.

Further information

If you have tried these and still can't see what is going wrong, feel free to ask in #VB on Undernet at irc.undernet.org.

See also