This article may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist. To maintain the flow of the article, we've left these URLs in the text, but disabled the links.


MIND


This article assumes you're familiar with Visual Basic.

Using Compuware's NuMega DevPartner for Visual Basic
Ken Spencer and Charles Caison

Debugging troubles? Wish you could track down that pesky bug in your Visual Basic code, or just understand your project better? NuMega DevPartner can help you become a Visual Basic guru in no time.
Compuware's NuMega DevPartner for Visual Basic® consists of four products that work with Microsoft® Visual Basic to help you build excellent applications. The products in the suite are CodeReview, SmartCheck, TrueTime, and FailSafe. You would typically use each of these tools in that order to obtain data that will help you produce bulletproof applications.

CodeReview
      CodeReview helps you analyze your source code before it is executed. It scans your code for missing help features and accelerator keys, bad coding styles, and other problems. It also looks for usability, performance, and programming style considerations that could adversely impact your application. CodeReview will not overwrite or modify any part of your project. It simply reads project files, then displays events (CodeReview lingo for bugs) in the Results window. When CodeReview finds an event in your application, it provides information about the event: an overview, description, type (usability, performance, and so on), explanation, effect it will have on your application, and how to fix it. Occasionally, it will point you to documents on the Microsoft Web site or in the Visual Basic help files for more information.
      CodeReview should be used early in the development cycle to eliminate problems as they arise. The basic process of using CodeReview is to select the project to analyze, let CodeReview analyze the project, review the findings, and make changes to your project if you accept CodeReview's suggestions.
      To start CodeReview, select it from the Start | Programs | NuMega | CodeReview menu. The CodeReview wizard helps you complete a project review. The tabbed steps on the wizard dialog guide you through the process of loading a project, selecting files to review, choosing processing options, and running the review. By default, the wizard appears when you start CodeReview.
      Click the Project button to select and load the project to process, then click Next. The File List listbox will display the files in the Visual Basic project. Choose the files you want to process, click Next, then Finish.
      CodeReview will read through the files that you have selected and provide you with feedback. In my experience with Windows-based software, the word "Warning" has usually been associated with moderately important messages. The word "Error" has been used for the most severe messages. Because CodeReview avoids all use of the words "bug," "problem," and "error," then the word Warning, by default, indicates the most severe of messages. Other notification types include (in descending severity levels) Caution, Alert, and Notice. Figure 1 shows the Event dialog with the severity levels and descriptions.

Figure 1: Event Severity Levels
Figure 1: Event Severity Levels


      The Results window displays an overview of the events that CodeReview found, while the Code window displays the code that CodeReview used to generate the event. If you want to restart the review process without the wizard, choose Start from the Run menu. You can save review information to a disk file by choosing Save from the File menu.
      You can adjust CodeReview's settings by selecting Options from the Tools menu. The settings on the General tab control the program environment. You can click the Review tab and adjust the settings to control how the review is run. When you select Default to Interactive Mode, CodeReview runs reviews, pausing on each event. If you deselect it, CodeReview runs the review in batch mode. The interactive mode is best for step-tracing through a project. In batch mode, CodeReview processes all files without pausing, which is useful for generating a to-do list. Enable Display Quality Metrics to display code line and other metrics about the review. If you select the "Make more responsive to user input, but slower" checkbox, CodeReview divides its time between executing the review and checking for user input. If you deselect this checkbox, CodeReview will not check for user input as often and will run faster.
      You can decide which event classes to include in the review by using Report Types on the View menu. The Report Levels option on the View menu allows you to determine which notification types to include in the review. You can also choose which file types to include in the review using File Selections on the View menu.
      CodeReview lets you enable or disable messages using the Message Manager by selecting it from the Tools menu. Each item in the list represents a message that can be displayed in a review. To prevent a message from appearing in a review, double-click True in the Enabled column, which sets it to False.
      CodeReview supplies a number of macros and special characters (no, not the same special characters that format message text) that help you define rules. Before you define rules on your own, look at the existing rules in the database to see how they are used there. You are better off creating a new rule than editing a rule that is provided with CodeReview, because if you mess up an existing rule, the only way to restore it is to reinstall CodeReview.

SmartCheck
      SmartCheck is a runtime bug checker and automatic error correction tool. It analyzes fatal errors, tells you what went wrong, and suggests possible solutions. It displays and logs your events as they occur. The events include problems with:


      SmartCheck also provides a detailed explanation of vague Visual Basic error messages such as "Invalid procedure call or argument." It can review your code for platform-specific calls and will provide you with information about the calls specific to certain versions of Windows. This is useful if you're worried that your app won't run properly under some versions of Windows.
      SmartCheck can be run within the Visual Basic environment, as a standalone application, or from the command line. You must compile your Visual Basic-based program to native code using Visual Basic 5.0 to take full advantage of the package; when you build a Visual Basic 5.0-based program in native mode with debug information, SmartCheck can treat the program much like Visual C++ would. The debug information allows SmartCheck to correlate program addresses with a source file and line number.
      To set the correct native compilation settings for an application, open your project in Visual Basic 5.0 and select Properties on the Project menu. Select the Compile tab and pick Compile to Native Code, No Optimization, and Create Symbolic Debug Info. To run SmartCheck within the Visual Basic environment, select Start with SmartCheck from the Run menu (or click the SmartCheck toolbar button). The NuMega SmartCheck message box appears to remind you to set your compile options for native code. SmartCheck does two things: first, it displays its own user interface; second, it automatically compiles and runs your program.
      When an event occurs in your program, SmartCheck dynamically logs it and displays it in the Program Results window. This is where most of the information is provided. It shows three panes that list events and errors when they occur. The Event pane (see Figure 2) shows errors and events generated by your program. The Details pane shows details about the item selected in the Event pane. You can see the arguments passed to built-in Visual Basic functions in the Details pane of the Program Results window. The Source Code pane, as you'd expect, displays the source code of the item selected in the Event pane.

Figure 2: Event Pane
Figure 2: Event Pane
      The Program Transcript window displays program debug and other events. It shows all the components loaded by your program in order. The Program Transcript window is always available (but minimized) when you check your program with SmartCheck. It displays the following debugging events: Create process, Exit process, Create thread, Exit thread, Load DLL, Unload DLL, Exception, and Output debug string. These events are signaled by the operating system as you debug your program.
      When your application starts, you can see the creation of a thread (a process that is part of the larger application), followed by the occurrence of a _Load event and the display of the corresponding icon. You are now in runtime mode and should use your program as you normally would, testing various application features.
      You can see in Figure 3 that SmartCheck displays events after an application starts. Each event is listed on a separate line. You can have SmartCheck add sequence numbers to the lines in the Program Results window to make it easier to keep track of your place when executing complex programs. To set sequence numbers, select Sequence Numbers on the View menu. Gaps in sequence numbers indicate that additional events occurred as part of a specific event. The first event that occurs is the creation of a thread, represented by the green highlight in the Event pane.
      Next, some initial comments are shown that explain a problem that was found even before the main form was loaded. On line 6 you can see the _Load event for the main form of the application. Because that line is selected in the Event pane, you can see details about it in the Details pane. In this case, the details consist of the path to the file that contains the _Load event code. Lines 7 and 8 show events that are subordinate to the main window's _Load event. The _Load event listed on line 7 represents the _Load event of the application splash screen, which has code to hide itself when a timer event occurs. You can see that event represented on line 8. Lines 6 and 9 represent the same _Load event of the application's main form. Line 6 shows program control flowing out of the event procedure, while line 9 shows program control flowing back into it.
      At this point, you should push your application by testing all of its features. When SmartCheck detects an error, you can press Explain to get detailed help on it. You can also view your program source code and a call stack by clicking the blue arrow on the Program Error Detected window. The call stack shows where program control was passed as it led up to the error. The topmost line in the call stack displays the procedure that contains the line where the error was detected. The second line from the top of the call stack displays the procedure that called the procedure where the error was detected. Each successive line in the call stack backtracks the transfer of program control in the same way. You can click any line in the call stack or the Program Results window to see the source code associated with the call.
      You can see summary counts for all your program events by choosing Event Summary on the View menu when the Program Results window is active. This summary will show you the number of times specific events and errors occurred in your application.
      The Event View toolbar allows you to quickly switch your SmartCheck results to show errors and leaks only, errors and specific Visual Basic events, or all events. If you select Show Errors and Specific Visual Basic Events, SmartCheck will list those events indicated on the Specific Events dialog box.
       Figure 4 shows the Specific Events dialog and some of the events that you can select. The dropdown listbox contains three entries that correspond directly to the three buttons on the Event View toolbar. If you use this dropdown listbox to select which of the three types of events to view, your selection will be reflected on the toolbar. These selections are also on the View menu. If you select Show Errors and Specific Visual Basic Events, you can check which of the events you want to view in the listbox containing Visual Basic events. To save your settings, check the "Apply to all new windows" checkbox.
Figure 4: Selecting Events
Figure 4: Selecting Events

      By default, SmartCheck filters out events that you are not aware of when you write Visual Basic-based code. You can see under the hood of Visual Basic with the NuMega SmartCheck Settings dialog box. Select Program | Settings from the SmartCheck menu. Next, select the Error Detection tab, then click the Advanced button to display the Advanced Settings dialog box. Finally, deselect the "Suppress system API and OLE calls" checkbox. After you run your program, select Show All Events on the View menu to drill down into your Visual Basic calls. This will help you see the system interactions behind your Visual Basic-based code. When the program results window is displayed, use Specific Events on the View menu to show additional details such as API calls from C, C++, and system code, and OLE method calls.
      You can make SmartCheck run faster with your program by using the checkboxes in the Performance Optimizations section on the Advanced Settings dialog box. Database programs run faster with "Suppress system API and OLE calls" selected. Programs that perform lots of background processing in timer loops benefit from "Cache program events." You can improve performance by enabling "Defer program results until program terminates" (but SmartCheck won't display the latest output).
      You can see your handled errors by selecting the Reporting tab on the Settings dialog box and enabling "Report handled Visual Basic runtime errors." You must also ensure that "Show errors and specific events" is selected on the Specific Events dialog box (under Specific Events on the View menu) and that "Handled errors (On Error, Resume)" is selected on the Specific Events dialog box.
      You may also want to ensure that SmartCheck only reports events in the files or modules that you choose by selecting the Files to Check tab on the Settings dialog box. Use the Component listbox to select the component that you want to check. Use the Associated Source Files listbox to select the files to check and to exclude. Don't exclude system components like comctl32.ocx, oleaut32.dll, ole32.dll and msvbvm50.dll, as these are required by SmartCheck. If you are debugging a regular Visual Basic-based application, your component will be the EXE file that is associated with your application.
      You can also check third-party ActiveX® components for errors and leaks. This includes the Visual Basic 5.0 runtime library DLL (msvbvm50.dll). Often, additional information about a bug in your program can be found by observing the invalid parameters and API failures that occur in msvbvm50.dll. To see these errors, select the Error Detection tab on the NuMega SmartCheck Settings dialog box, click Advanced, and select "Report errors even if no source code is available." The level of reporting and functionality is more limited in this case. SmartCheck cannot show errors occurring in modules that don't have debug information and it cannot pinpoint the line number on which the error occurs without the source code. If you do this, you'll likely see many OLE interface leaks at the end of your program. Some of these are from the OLE interfaces that represent Visual Basic controls, while others are from the OLE system DLLs.

TrueTime
      TrueTime is a performance analysis and evaluation tool that handles performance tuning. It collects and displays performance data about a single execution of your Visual Basic-based application, called a session. TrueTime can provide you with the following types of information for your procedures:

  • Percentage of time spent in a function
  • Percentage of time spent in child functions (functions called by the function you are observing)
  • Number of times a function is called
  • Average minimum/maximum execution times for a function
  • Average amount of time spent in the function and child functions
  • Actual (real-time) amount of time spent in the function and its children, including threads of other applications
      With this data, you can identify and locate performance problems and examine relationships among functions to improve your code. TrueTime works, even if you do not have the source code, by gathering data about calls made to external components. For example, if your application calls a system or third-party DLL, TrueTime can gather performance information about the functions that your application calls in the DLL.
      To start using TrueTime with your application, you must use Visual Basic 5.0 to build your application and you must instrument it (NuMega vernacular for "tell TrueTime to add code for gauging the performance of your application") with TrueTime code. To instrument your application, start Visual Basic and open the project you want to instrument. On the Tools menu, select Run with TrueTime. TrueTime will then instrument and run your application. After you quit your application, TrueTime will display a session file that contains the performance information for that session. To save this session file as part of the active project, select Save on the File menu. You can use various session files to compare different performance scenarios.
      To start the application, select Run with TrueTime on the Tools menu. TrueTime will display a dialog with a progress bar to indicate how much of the application has been instrumented. After TrueTime finishes the instrumentation, it opens TrueTime and starts your application. You can use your application as you would normally while TrueTime silently watches and records what your application does.
      When you quit the application, TrueTime displays the main window and other windows. Figure 5 shows the TrueTime interface. The Project pane contains a tree view of the session files associated with the active NuMega project. The Output window contains a list of the events and errors TrueTime encountered while running your application. The Session window is located directly above the Output window and contains both the Filter and Session Data panes. The two panes display data about a session.
      The Filter pane contains a tree view of the source files and system images that your application used during the session. It also contains filters (at the bottom of the tree) that you can use to view a specific group of functions. A number next to each file name discloses the amount of time spent in that file as a percentage of the time spent in the whole session.
      The Session Data pane (not to be confused with the Session window) contains tabs that you can select to receive summary information. These include the Function List tab, Source tab, and Session Summary tab. When the Function List tab is selected, the Session Data pane displays the details of the item currently selected in the Filter pane.
      A great way to start analyzing your program's data is to find out which 20 functions in your application occupy the most time. Select the Function List tab in the Session Data pane and click the "% in Function" column heading to sort it in descending order. Click the Top 20 Source Functions filter near the bottom of the hierarchy in the Filter pane. The function names are listed with the file name and the function name separated by colons. The functions called the most are at the top of the list; those called the least are at the bottom. To filter the data further, click the icon that represents your application in the Filter pane, then click any of the files shown to display only the functions accessed from that file. As you do, notice that many of the same items appear as when you selected the Top 20 Source Functions filter. The ones that appear now are the only ones that are contained in the file that you selected.
      In the same way, you can see what functions were called on behalf of your application by opening the System icon. The icons displayed below System represent the components that were used by your application but aren't part of your Visual Basic-based project source files. When you click a component icon in the Filter pane, the procedures that are part of that component appear in the Function List in the Session pane.
      Several data columns are available for each function listing. You can click the Columns button on the Session toolbar to select the columns to display on the Function List tab.
      The Source tab displays the source code for the selected file with session data about each executed line of code in the source file. The Source tab shows the name of the file that is currently displayed. You can change the file displayed on the Source tab by double-clicking any of your project source files in the Filter view.
Figure 6: Detail Dialog
Figure 6: Detail Dialog

      If you select a line in a function, you can display the Detail dialog by right-clicking and selecting Go to Detail, then selecting the function name from the context menu that appears. You can also display it by clicking the Details button on the Session toolbar. Figure 6 shows the Detail dialog. The lime green square represents the function cmdOK_Click in the pie charts. The text data in the topmost section is exactly the same as on the Function list tab.
      The Parents section contains data about functions that called cmdOK_Click. You can see that the function CallWindowProcA called cmdOK_Click once. The percentage of time spent in cmdOK_Click relative to CallWindowProcA was 0.11 percent. In other words, of the total amount of time that it took CallWindowProcA and all of its children to process, 0.11 percent of that time was spent processing cmdOK_Click.
      The Children section contains data about the functions that were called by cmdOK_Click. You can see the names of the child functions, how many times each was called, and the time each child function used relative to the amount of time that cmdOK_Click and all of its child functions spent executing. Notice that cmdOK_Click is not on the list of child functions, but it is included on the pie chart as the lime green slice. You can move the mouse over the slice representing cmdOK_Click to determine the percent of time cmdOK_Click used relative to its child functions.

FailSafe
      FailSafe is the most comprehensive tool in NuMega DevPartner. It is an analysis and recovery tool that continues to monitor an application even after it has been deployed. It can even keep an application alive by intercepting GPFs and other errors that might otherwise crash an app. User events are recorded, as well as the class, type, number, and description of errors. A call tree shows the events and routines, complete with argument values, that lead up to the error, helping you to isolate where and why these problems occurred. FailSafe generates log files about what goes on in an application at runtime. FailSafe can even email the log to you so that you can review it periodically. You can use the log to recreate the steps that led up to the error, then analyze the error with SmartCheck.
      Many very useful tools are included with FailSafe that can give you great insight into applications, supporting files, and even the operating system itself. As powerful as they are, they are surprisingly easy to use. Here are some of my favorites:

  • Process Monitor shows the exact sequence that OCXs, VBXs, DLLs, and EXEs are loaded by an application.
  • System Spy shows class information, handle, and other internal Windows structure data.
  • GPF Monitor traps and displays unhandled General Protection Faults in Windows.
  • ExeCheck dependency checker scans a program to show statically linked connections to support files such as VBX, OCX, DLL, DRV, EXE, FON, and HLP files.
  • Version Spy shows file version number information for EXE, OCX, VBX, DLL, DRV, FON, or any other file with Windows version number information.
       Figure 7 shows the System Spy; Figure 8 shows ExeCheck. To execute either one, select it from the Tools menu. When you do, you will probably find yourself receiving valuable information from these tools within minutes.
Figure 7: System Spy
Figure 7: System Spy

      To use FailSafe, instrument your application, compile your app with the newly added FailSafe tracing code, capture trace data from an instrumented project, then profile the trace. When you start FailSafe, the New Window dialog appears. Use this dialog to open a Trace window, a Profile window, or the AutoProcessor window. A Trace window displays information captured from instrumented programs. A Profile window displays profiles of information captured from instrumented programs. In the AutoProcessor window, you add and remove FailSafe instrumentation to or from a project file.
      Start the process by clicking the AutoProcessor button. FailSafe displays a message box. Click Yes to tell FailSafe that you will be either adding or removing instrumentation. The AutoProcessor Wizard appears with the Step 1 tab selected. Click Next to move between each step. Use the Project button to select a Visual Basic-based project. In Step 2, choose whether to add or remove instrumentation and line numbers. Next, choose the files that you want to process and a template to use. Templates, which tell FailSafe how to process your project, are selected via a dropdown listbox. For example, if you are instrumenting beta and debugging builds of ActiveX components, you should use the LITE template. If you want full-featured debugging, use the MAXIMUM template. After you select a template, click Finish. FailSafe will give you the opportunity to back up your project and will tell you when it has completed instrumenting the project.
Figure 8: ExeCheck
Figure 8: ExeCheck

      Next, you need to configure FailSafe to capture data from the instrumented program. To start the Trace Wizard, select File | New to display the New Window dialog box. Click the Visual Tracer button. FailSafe will display a dialog box asking if you will be setting up a trace. Click Yes and the Visual Tracer Wizard will appear.
      Now set up the trace window. To capture a new trace, leave the field blank and choose Next. Click Next again to skip adding Breakpoints or Filters or changing the display. These are advanced options and are safe to skip.
      Next, you should choose how the trace will be captured. No Delay will force your program to update the FailSafe Trace window before your program continues. Delayed writes trace data to a buffer and then lets your program continue. Minimize On Launch will minimize FailSafe when starting to capture trace information. This can help improve performance. Choose Next to move to the next step.
      Now choose a program to trace and whether to capture the trace output to disk. To trace an instrumented executable, choose Program to select it. To trace a project running under Visual Basic, leave this field blank. To have the trace written both to disk and to the trace window, choose Capture to specify an output file name. When you're finished, choose Next to move to the next step. Choose Finish to start capturing trace information with the selected options.
      After you let FailSafe collect trace information on your application, it is time to profile it. Select File | New to open the New Window dialog. Click the Visual Profiler button. If FailSafe asks if you would like help profiling a project, click Yes. The Visual Profiler Wizard will appear. Select the item that you want to profile from the Active Trace Window, select a trace file on the list, or click the File button to select a trace file to profile. For now, select Active Trace Window from the dropdown listbox, then click Next. Now, select the type of graph to be used and the column to sort data. For the graph type, select Area, 2-D. Select Module in the Sort Options dialog box. You can change these after the graph is generated.
      Choose the command for the FailSafe area you want to access. When prompted, choose either Yes to use the wizard for that window or No to open that window directly, then click Next. Click Finish to begin profiling the contents of the Active Trace Window. If FailSafe asks you to confirm that you want to profile the contents of the Active Trace Window, click Yes.
      The results of profiling are displayed in the Profile of Trace window. There are several types of data provided. The columns show information about your project (see Figure 9). A column at the top of the window is graphed at the bottom of the window. To chart a different column, simply double-click the column. To cross-reference the column with a module or a procedure, double-click the numeric data column first, then double-click the module or procedure column. For example, if you want to chart Hits by Module, double-click the Hits column to chart that data, then double-click the Module column. A chart showing Hits by Module will be displayed.

Conclusion
      As we've shown, with DevPartner you can obtain many useful pieces of information that can help you improve the performance of your Visual Basic-based application. After you have your data in front of you, put it to work. DevPartner for Visual Basic gives you the tools you need to understand what your application is doing and to tune that application to perform at its best.

From the July 1998 issue of Microsoft Interactive Developer.