Overview

Navigation: »No topics above this level«

Overview

 Return to chapter overview

Hi, welcome to the Thread Validator help manual.

This help manual is available in Compiled HTML Help (Windows Help files), PDF, and online.

Windows Help | https://www.softwareverify.com/documentation/chm/threadValidator.chm
PDF | https://www.softwareverify.com/documentation/pdfs/threadValidator.pdf
Online | https://www.softwareverify.com/documentation/html/threadValidator/index.html

Tutorials for Thread Validator are available at https://www.softwareverify.com/tutorial/thread-validator-tutorial/.

Before reading this manual, it's worth taking a quick look at the notation used.

Read background information

The overview section covers things like:

· the capabilities of Thread Validator

· how it works

· what's supported

· how to purchase

If you've already purchased, thank you!

Learn about getting started

You can skip the background information, but do make sure you're aware of how to prepare your target program in the getting started section.

Dive right in

The quick start section shows how to launch your application.

To find your way around the rest of the features and settings then read about the user interface, or browse the examples.

If you're already feeling confident you can learn about some of the advanced features such as comparing sessions.


Notation used in this help

Navigation: Overview >

Notation used in this help

 Return to chapter overview

instructionStep Instruction instructionStep steps

Menu action instructionStep steps

Throughout the help you'll find instruction steps like this:

·Filter... instructionStep shows the session comparison private filters dialog

or

menu Settings Menu instructionStep Edit Settings... instructionStep Data Collection in the list instructionStep Trace Hooks

This is a shorthand notation for performing consecutive steps in the user interface.

The first example indicates that the action of clicking the Filter... will result in showing the dialog described.

The second example directs you to open the Settings menu (from the menu bar in this case), and then choose the Settings item, and in the dialog that appears, open the Data Collection option via the list and select the Trace Hooks child entry.

Right mouse button menu

Where you see this mouse menu the instruction is to use the right mouse button menu (a.k.a. popup menu or context menu) and select the menu option that follows this symbol.

For example: use [image] Edit Source Code...

interactive Interactive images

Shown next to a picture, the hand symbol interactive indicates the image is interactive and can be clicked on in order to jump directly to the help section most relevant to the part of the image under the cursor.

externalLink External Links

You may see this symbol externalLink after some links. Those links lead to an external website (shown in your default browser), as opposed to jumping to another section in the help. Naturally, if you have no internet access, these links will be unavailable.

For example: Software Verifiy Limited externalLink

note Notes

warningnote Warning notes

Notes pertaining to the current topic are indicated by the note symbol. Notes may include exceptions to a rule, items to watch out for, or other asides to the main topic.

Notes that act as warnings will use the similar warningnote symbol, for example where there's a danger of crashing your application. Don't panic though - there aren't many of these!

seeAlso See also

Where there are other pages in the help that have more detail on the topic at hand, or if there is additional reading that is not already linked within the content, you will find these sections linked after the seeAlso symbol.


Introducing Thread Validator

Navigation: Overview >

Introducing Thread Validator

 Return to chapter overview

What is Thread Validator?

Thread Validator is an automatic deadlock detector for Windows.

It works with versions of Windows from NT® 4.0 and above, running on the Intel i386 (and compatible) family of processors.

For the purposes of this documentation, we'll call Thread Validator just 'Thread Validator'.

What does Thread Validator do?

Thread Validator can:

·detect deadlocks

·detect potential deadlocks

·find bad lock strategies

When deadlocks, potential deadlocks and bad lock strategies are detected, you can examine the order in which each lock was acquired, complete with a stack trace for each lock.

·perform deadlock postmortem analysis

If your program deadlocks you can attach to it with Thread Validator and ask for a complete stack trace for each thread in the application.

Typically if you try to do this with a debugger, each deadlocked thread just shows one or two stack entries inside NTDLL.DLL and no stack entries for your program, so you don't know which part of your program deadlocked.

Thread Validator uses proprietary stack-walking routines to walk the entire stack, so that a complete stack trace can be displayed for deadlocked threads.

The results are displayed as a variety of comprehensive but easily explorable tabulated and hierarchical formats.

Source code editing is provided with colour coded lines so that you can see at a glance which functions consume more time than others.

The performance overhead is very low and there is no need to recompile or relink the target program.

Thread Validator can also be used as part of a regression testing strategy by Quality Assurance teams.

The main sections of Thread Validator

The user interface is split into tabbed report sections (plus Tutorials), each presenting or analysing locks in the target program at different levels of granularity.

Here's a summary of those sections, each of which is covered in full in The User Interface section.

Summary

A high level overview of all threading activity, showing data on threads, locks, contentions, recursions, waits, errors and thread coverage.

Locks

Master tab for three different tabs, each providing a different view of all the locks, waits and threads in the application.

Wait Chains

Displays information about the lock wait chains

Threads

This display provides a graphical view of thread activity over time.

Analysis

Master tab for four different tabs providing query, thread coverage, object creation data, and object handles.

Diagnostic

Logs diagnostic information collected by the stub, including functions that could not be hooked.


Why Thread Validator?

Navigation: Overview >

Why Thread Validator?

 Return to chapter overview

Adapts to everyone's workflow

Thread Validator allows you to find otherwise hard to isolate errors using an intuitive colour-coded user interface.

Data can be collected using a variety of different query methods. When faced with a large amount of data you can search or filter the data.

If you want to see the source code that caused a deadlock, just double click on the display entry to view source code in the adjacent window.

Alternatively, to edit the code, double click on a code fragment shown and the appropriate source code file will be loaded into Thread Validator's colour-coded editor, or into Microsoft® Visual Studio®, or you can choose your preferred awesome editor.

You can save sessions, reload them at a later date and still interact with the analysis data.

You can also export session data to HTML or XML which can be used to create reports targeted to the appropriate audience: the management team; quality assurance team; or to create detailed stack trace reports for the software engineers.

Designed with principles

Thread Validator and the other products in our suite of tools have been created with the following principles in mind:

·must not adversely effect the program's behaviour

Any hooks placed into the target program's code must not affect the registers or the condition code flags of that program. The program must behave in the same way when being inspected by Thread Validator as without.

·must be reliable and avoid causing the target program to crash

Since we can't know exactly which DLLs and other components are present on every computer that Thread Validator is installed on, every hook can be enabled or disabled, and/or installed or not installed.

Thus if a new DLL is released in the future that causes problems with certain functions, you can disable the hooks for those functions, and continue using Thread Validator until a fix for the new DLL's behaviour is available.

·must have as little impact on the target program's performance as possible

Thread Validator has very little effect on the target applications performance, but you can also enable and disable as many or as few threading hooks as you wish.

For example:

If you're only interested in monitoring performance of a particular area of code, you can pick only that directory to be hooked.

If you're only interested in a selection of in-house DLLs, choose only those modules to be hooked.

·must have a user interface independent of the target program

Thread Validator's user interface is independent of the target program.

This means:

If the target program crashes, the user interface will not crash - you will still have data to work with.

If the target program is stopped in the debugger, Thread Validator's user interface will continue to work.

In the unlikely event that the Thread Validator's own user interface crashes, your target program will not crash.

·must be flexible

We know our users like choices! Where there are multiple ways of presenting the data, the user is given a choice over how that display works, so that not all users have to work with the same settings.


What do you need to run Thread Validator?

Navigation: Overview >

What do you need to run Thread Validator?

 Return to chapter overview

Compilers

The following makes of compiler are supported:

·Microsoft® Visual Studio®

·Borland C++

·Borland Delphi

·Intel

·Metrowerks

·MinGW

·QtCreator

·Fortran (various)

seeAlso Supported compilers for more details regarding versions and caveats.

User Privileges

Thread Validator uses the CreateRemoteThread() Win32 function. You must have access privileges that allow you to create threads in other programs.

Typically Administrator and Power User user types have the appropriate privileges. Ordinary user accounts can be easily modified to have the required privileges.

seeAlso Learn more about user privileges in the section on User Permissions.

Registry Access Privileges

Thread Validator requires read and write access to:

·HKEY_CURRENT_USER\Software\SoftwareVerification\ThreadValidator

·HKEY_USERS\.DEFAULT\Software\SoftwareVerification\ThreadValidator.

This is used when working with services

If read and write access is not allowed:

·Thread Validator will use default settings (thus any user selections will not apply)

·Error messages will be displayed when Thread Validator tries to access the registry key

These error messages can be suppressed if they are not desired. For example, if you're not working with services, then there's no requirement to access the second registry key, and all error messages relating to it can be ignored.

seeAlso The question relating to creating Power User accounts for Windows XP.

Operating System

Any 'modern' windows machine is suitable to run Thread Validator.

At a minimum, Thread Validator requires Windows NT® 4.0 or better.

Thread Validator will not run on the following platforms, because the CreateRemoteThread() Win32 function and named pipes are not available:

·Windows 95®

·Windows 98®

·Windows Me®

Any newer operating systems do not need any additional service packs but we generally recommend being up to date where possible anyway.

For older systems, we recommend using the minimum service pack levels below:

·Windows NT 4.0: Service Pack 6

·Windows 2000: Service Pack 2


Buying Thread Validator and Support

Navigation: Overview >

Buying Thread Validator and Support

 Return to chapter overview

The best way to purchase Thread Validator is online from Software Verify Limited externalLink - just click the Purchasing link at the top of the website.

Purchase options

There are options for single or multiple licenses, per-user or floating licenses, and although you can of course purchase it as a single product, you can save significantly by buying Thread Validator as part of a suite of products. All the details are online.

Pre-purchase questions?

If you have any pre-purchase questions not answered in this help manual, or niggling little doubts about something, we can be contacted as below.

email: sales@softwareverify.com (recommended)

web: https://www.softwareverify.com externalLink

or by old fashioned post:

Software Verify Limited

Suffolk Business Park

Eldo House

Kempson Way

Bury Saint Edmunds

IP32 7AR

United Kingdom

After sales support

If you need support after purchase, check our frequently asked questions and then drop us a line below with as much detail as possible about your problem.

email: support@softwareverify.com


How does Thread Validator work?

Navigation: Overview >

How does Thread Validator work?

 Return to chapter overview

The Stub and the UI - more than the sum of its parts

Thread Validator has two main parts - the stub and the user interface.

The stub is typically injected into the target program and communicates with the Thread Validator user interface.

The stub is injected into the target program using the CreateProcess() or CreateRemoteThread() Win32 function. Communication between the stub and the user interface is via named pipes. There is no human readable data sent between the two parts of the program. Both the stub and the user interface are multi-threaded. If required the stub can be linked into the program so that it doesn't need to be injected into the program.

The stub walks the entire program image detecting the start of each source code line using PDB and/or MAP files.

The stub rewrites the DLL import address table to make functions call into the stub's hooks. Each function is checked to see if it can safely be hooked without corrupting the code for another line or function, or changing the function of the program. The line is hooked if possible, otherwise the user interface is informed of the function hook failure.

The stub monitors thread and lock related data and stores the information in data structures to be displayed by the user interface.


Supported Compilers

Navigation: Overview >

Supported Compilers

 Return to chapter overview

Thread Validator will work with any portable executable (PE externalLink) file format and supports C++, Delphi, Fortran 95 and Visual Basic.

C/C++ runtime functions are provided by individual compiler vendors, not all of whom still maintain, support the products listed.

The following C / C++ compilers are supported by Thread Validator.

Microsoft http://www.microsoft.com externalLink

Thread Validator requires your application to be built using Microsoft® Visual Studio® 6.0 service pack 3 or later.

In practice, you may find that applications built with Developer Studio 4.2 and later can be used with Thread Validator.

·Microsoft Developer Studio 4.0

·Microsoft Developer Studio 5.0

·Microsoft Developer Studio 6.0

·Microsoft Visual Basic 6.0

·Microsoft Visual Studio 6.0 - service pack 3 or later

·Microsoft Visual Studio 7.0 / .net 2002

·Microsoft Visual Studio 7.1 / .net 2003

·Microsoft Visual Studio 8.0 / .net 2005

·Microsoft Visual Studio 9.0 / .net 2008

·Microsoft Visual Studio 10.0 / .net 2010

·Microsoft Visual Studio 11.0 / .net 2012

·Microsoft Visual Studio 12.0 / .net 2013

·Microsoft Visual Studio 14.0 / .net 2015

·Microsoft Visual Studio 15.0 / .net 2017

·Microsoft Visual Studio 16.0 / .net 2019

·etc...

Microsoft Developer Studio and Microsoft Visual Studio products support both C++ and Visual Basic.

seeAlso Visual Studio and Visual Basic 6 in the Getting Started section.

Intel http://www.intel.com externalLink

·Intel performance compiler - The Intel compiler uses the Microsoft runtime already installed on your computer rather than supply its own

·Intel Fortran

Intel use Microsoft's PDB proprietary symbol information format. If your compiler uses PDB symbol information Thread Validator will be able to use it.

Metrowerks

·Metrowerks CodeWarrior for Windows Version 8.0

·Metrowerks CodeWarrior for Windows Version 9.0

You will need to ensure the debug information is stored as CodeView information and not a custom Metrowerks debug format. Metrowerks symbolic information is embedded in the .exe/.dll as CodeView information. Please consult the documentation for CodeWarrior to include debug information (including filenames and line numbers) in the CodeView information.

Embarcadero https://www.embarcadero.com/ externalLink

This includes compilers formerly produced by Borland.

·C++ Builder 5.0 to C++ Builder 11

·Delphi 6.0 to Delphi 11

·Rad Studio

seeAlso C++ Builder and Delphi in the Getting Started section.

MinGW http://www.mingw.org externalLink

·MinGW (Minimalist GNU for Windows)

MinGW can create symbols in a variety of formats. If you configure MinGW to produce DWARF symbols, STABS symbols or COFF symbols Thread Validator can read them.

seeAlso MinGW compiler in the Getting Started section.

Qt (Digia, Nokia, Trolltech) http://qt.io externalLink

·QtCreator

seeAlso Ensure that debug information is created in DWARF, STABS or COFF formats.

Salford Software now maintained by SilverFrost externalLink

·Salford Software Fortran 95

Salford Software Fortran 95 uses COFF symbol information. If your compiler uses COFF symbol information Thread Validator will be able to use that information.

note Note: While Fortran 95 provides multi-threading capabilities, FORTRAN 90 Standard does not.

Compaq

·Compaq Visual Fortran 6.6

The Compaq Visual Fortran product may be compatible with Thread Validator. If you are using Compaq Visual Fortran and wish to use Thread Validator please contact us.

Other...?

If the compiler you are using is not listed here, please contact us for advice. We add compilers as we receive requests for them, and many of the above were added at the request of customers.


User Permissions

Navigation: Overview >

User Permissions

 Return to chapter overview

This section details the privileges a user requires to successfully run Thread Validator.

note Typically, Administrator and Power User user types will already have the appropriate privileges.

Why do user privileges matter?

Debugging tools such as Thread Validator are intrusive tools - they require specific privileges not normally granted to typical applications.

Thread Validator requires specific privileges to write to the default user profile in the registry.

This is so that when Thread Validator is working with services (or any application run on an account which is not the current user's account) it can read the registry and the correct configuration data.

If the account upon which a service or application is running is not the user's account, the fallback position is the DEFAULT account in HKEY_USERS\.DEFAULT.

You can enable and disable various warnings using the User Permissions Warnings dialog.

User privileges

Thread Validator requires the following privilege to allow debugging of applications and services:

Debug Programs (SE_DEBUG_NAME)

Ordinary users will need to be granted these permissions using the Administrative User Manager tool. The example below shows the NT4 User Manager - the Windows 2000 User Manager and Windows XP User Manager will be different but similar in principle.

In the User Manager select the user - in this case "Test User".

Choose: Policies Menu instructionStep User Rights instructionStep check Show Advanced User Rights instructionStep select Debug Programs in the Right drop down list

Click Add.... instructionStep Show Users

Select [ComputerName]\Test User in the top list. Click Add instructionStep OK instructionStep OK instructionStep Close the User Manager.

Registry access privileges

Thread Validator requires read and write access to:

·HKEY_CURRENT_USER\Software\SoftwareVerification\ThreadValidator

·HKEY_USERS\.DEFAULT\Software\SoftwareVerification\ThreadValidator.

This is used when working with services

If read and write access is not allowed:

·Thread Validator will use default settings (thus any user selections will not apply)

·Error messages will be displayed when Thread Validator tries to access the registry key

These error messages can be suppressed if they are not desired. For example, if you're not working with services, then there's no requirement to access the second registry key, and all error messages relating to it can be ignored.

You can modify the registry access permissions using the regedt32.exe tool Security menu (or similar). Ask your administrator to modify your registry access permissions if you can't do this yourself.

seeAlso What's the difference between Regedit and Regedt32? externalLink

Error notifications

When Thread Validator fails to gain access for read or write to the registry a message box is displayed indicating if the error is for the user interface (UI) or Services. The message indicates the name of the registry key that failed and the failure reason.

This simple message box is displayed during early startup and late close-down of Thread Validator:

Message boxes like the following are displayed when Thread Validator is not starting up or closing down. The messages differ in the registry key.

Detailed registry access error messages

The following detailed registry access error message is also displayed when failing to gain access to the registry keys.

Insufficient user privileges

The following dialog is displayed if a user has insufficient privileges to use the software correctly.

note Without the Debug Programs privilege, Thread Validator will not work correctly with Services, and may not work correctly with Applications.

seeAlso How to create Power User accounts for Windows XP.


Getting Started

Navigation: »No topics above this level«

Getting Started

 Return to chapter overview

For those that wish to 'dive in', this section will make you aware of how to prepare your target program before giving a quick start introduction.

Otherwise skip right on to the next chapter - The User Interface.

Diving in?

You're probably wanting to 'dive in' and start analysing the threads in your application, looking for deadlocks right away.

However, if you choose to read this manual first, you'll find out more about Thread Validator and how to leverage it to its full advantage.

For new users of Thread Validator, a configuration wizard appears the first time you run the application. This ends with a brief overview video.

We also recommend watching the tutorials online externalLink - it's an easy way to explore the functionality available.


Enabling Debugging

Navigation: Getting Started >

Enabling Debugging

 Return to chapter overview

To get the best from our tools you will need to enable debugging information for your compiler and your linker.

Detailed instructions are available for these IDEs / compilers:

· Visual Studio

· Visual Basic 6

· C++ Builder

· Delphi

· MingW, gcc, g++

· Dev C++

· Salford Software FORTRAN 95

· Metrowerks Code Warrior

Debug Information Formats

Thread Validator can understand debugging information in the following formats:

·Microsoft Program Database (PDB)

·Turbo Debugger Symbols (TDS)

·COFF

·DWARF

·STABS

The Intel Performance Compiler and Intel Fortran compilers produce symbols in Microsoft's PDB format.


Quick Start

Navigation: Getting Started >

Quick Start

 Return to chapter overview

If you are:

·an admin level user

·using Microsoft compilers

·on a modern OS

·already know that you create debug info in your debug and release product

...then you're more than likely good to go and dive in!

Otherwise, we recommend reading these topics from the Overview section before starting:

· What do you need to run Thread Validator?

· Supported Compilers

· User Permissions

Testing on the Example Program

You can test drive the capabilities of Thread Validator by launching the example program supplied with Thread Validator - nativeExample.exe.

The example program can be used in conjunction with the Thread Validator tutorials.

Ensure you have debugging information

Your application needs to be compiled to produce debugging information and linked to make that debugging information available.

We provide some details for enabling debugging information with Visual Studio, C++ Builder, Delphi, MinGW, and other compilers.

If you have no PDB debugging information but you do have a Microsoft format MAP file available, it must contain line number information by using the /MAPINFO:LINES linker directive.

Launching

To start your program click on the launch icon on the Session toolbar.

What you see next depends on the user interface mode (wizard or dialog style).

The Launch Wizard...

If you've just installed the software you will be shown the launch wizard:

Click Browse... to choose a program to launch instructionStep Next instructionStep Next instructionStep Next instructionStep Start Application...

...or the Launch Dialog

If you have switched to Dialog mode you will be shown the launch dialog:

Click Browse... to choose a program to launch instructionStep Launch

During launch

Thread Validator will start and inject the stub into the target program. Progress during this phase is displayed in the title header of the main window.

Once correctly installed in the target program, the stub will establish communications with Thread Validator and data can be collected and viewed until the target program exits.

When a deadlock or a bad lock strategy is detected, the data relating to this on each tab is displayed in the relevant colours.

Most tabs will update at intervals (unless set otherwise) to show data collected so far.

After exit - examining the output

When the target program exits, Thread Validator stops collecting more data but keeps all the session data active for you to explore. The data collection icons on the session toolbar are disabled, and the launch icons are enabled again.

Most tabs are automatically updated to reflect the final data, and the other tabs also continue to let you explore the data until the session is closed.

Ending the session

Even though the target program has exited, the session is still active and can be examined or saved until the session is closed:

menu File menu instructionStep Close Session

You can have more than one session open at a time.


The User Interface

Navigation: »No topics above this level«

The User Interface

 Return to chapter overview

The part of Thread Validator that you get to see and interact with, is the user interface, but that's only one half of the story.

Behind the scenes, the stub installs and controls the data hooks in the target program and interacts with the user interface.

This section describes the various functions of the user interface so that you can get the most from using Thread Validator.

Typical workflow

Typical usage of Thread Validator is very simple:

·Start your target program

·Examine the thread lock acquisition strategy of the program

·Close the program

·Analyse final data - saving or exporting data if needed

However, there is much more to Thread Validator than this simple workflow. For example, whilst your program is running, you can display data and gain insight into a specific bug you are looking at in the debugger, or you can monitor the program as a whole, looking out for potential deadlock issues and check coverage of thread related functions.

The user interface

The user interface consists of the menus, toolbars, status bar and the main display tabs.

Read on to find out about all those features, or click parts of the image below to jump directly to any of the menus, tabs or other sections of interest.


First Run Configuration

Navigation: The User Interface >

First Run Configuration

 Return to chapter overview

First run configuration

For new users of Thread Validator, a configuration wizard appears the first time you run the application.

The wizard collects a few details about environment, tools, update requirements (for non-evaluation users) and ends with a short video tutorial.

User interface mode

After the introductory page, the wizard presents options for configuring the how the launch, inject and wait dialogs present information to you.

·Wizard mode instructionStep guides you through the tasks in a linear fashion

·Dialog mode instructionStep all options are contained in a single dialog

Experienced users will find this mode quicker to use

These settings can be changed at any time via the User Interface Mode option on the Settings menu.

Symbol search path environment variables

After the introductory page, the wizard presents options for using environment variables for symbol search paths when finding PDB symbols.

You don't have to choose any of these options as Thread Validator will try to automatically determine symbol path information.

These environment settings can be changed at any time via the Configure Symbol Handling Environment Variables on the Symbol Server page of the Settings Dialog.

Symbol lookup

The next page of the wizard allows you to specify which IDE, Compiler or Linker you're using.

This is important as it affects how symbol lookup is performed. Visual Studio has various quirks in its history of symbol handling and we have to work around that.

The default settings are shown below, although the Visual Studio version may vary.

These lookup settings can be changed at any time on the Symbol Lookup page of the Settings Dialog.

Hook Insertion

The next page of the wizard allows you to specify which synchronization functions will be monitored.

Two check boxes control which groups of hooks are inserted into your application.

·Synchronization functions instructionStep inserts hooks for tracking synchronization objects into the target program

If enabled, the default behaviour is that critical section enter and leave events will be tracked. Additional functions can then be specified below.

·Functions working with waitable handles instructionStep hooks (below) for tracking functions that create, manage and destroy waitable handles will be inserted into the target program

A few additional functions (Sleep, and critical section related functions) are also monitored.

Specify which groups of functions should have data collected from them using the individual check boxes. (See note about memory below).

Any collected data can be viewed on the Active Objects and Analysis tabs.

Groups of items | Functions that...
·Critical Section | initialize, modify and destroy
·Event | create, open and destroy
·Mutex | create, open and destroy
·Semaphore | create, open and destroy
·Register Wait | register and unregister
·Waitable Timer | create, open and destroy
·Job Object | create, open and destroy
·Process | create, open and destroy
·Thread | create, open and destroy
·File | create, open and destroy files (of any type)
·Duplicate Handle | miscellaneous handle functions
·Change Notification | create, open and destroy file change notifications
·Timer Queue | create, open and destroy timer queues and timer queue timers

Other options:

·Sleep | Sleep and SleepEx For many applications, enabling Sleep will generate a lot of data, as various threads sleep from time to time.
·Collect NULL and Invalid Handles | information about failed handle creation When collecting waitable handles, you may also want to collect information about failed handle creation using this option.

·Select/Deselect All instructionStep switches all the above functions allocating waitable handles - i.e. not Sleep and invalid handles

note It's recommended that options in this section are only enabled if you need to monitor the data. If you subsequently find that memory consumption is very high, consider changing the settings here, or on the Historical Data tab.

These hook insertion settings can be changed at any time on the Hook Insertion page of the Settings Dialog.

Software update credentials

The software updates page of the wizard is only shown to non-evaluation users.

You can configure your software update credentials within the application and where updates are downloaded to.

You can test the login details to ensure they are valid:

·Test login details instructionStep click to check your entered details are valid (requires an internet connection)

Valid details will be confirmed:

Invalid details may mean you entered credentials for another application in the Validator suite, or they could have been entered incorrectly.

You should have received the correct credentials when you purchased Thread Validator.

If you experience problems, check with your system administrator or contact Software Verify.

These update credentials can be changed at any time from the Software Updates menu.

Software update download location

It’s important to be able to specify where software updates are downloaded to because of potential security risks that may arise from allowing the TMP directory to be executable.

We use the TMP directory as a default, but if you're not comfortable with that you can specify your preferred download directory. This allows you to set permissions for TMP to deny execute privileges if you wish.

An invalid directory, e.g. one that does not exist, will show text in red and will not be accepted until a valid folder is entered.

·Reset instructionStep reverts the download location to the user's TMP directory

The default location is c:\users\[username]\AppData\Local\Temp

The download location can be changed at any time from the Software Updates menu.

Build example projects

The next page of the wizard allows you to build the example projects that ship with Thread Validator.

The example projects demonstrate various application types containing bug you may wish to investigate with Thread Validator.

·Visual Studio... instructionStep opens the example projects solution with the version of Visual Studio selected

·Download... instructionStep downloads a prebuilt version of the example projects, unzips them and installs them in the examples folder in the Thread Validator installation directory

If you choose this option and you have not installed Thread Validator in the default location (assuming a 64 bit OS) the source file paths in the debug information will be incorrect - you will need to use the File Locations settings to inform Thread Validator of the correct location(s).

·Open example projects folder... instructionStep opens the folder that contains all example projects

Video overview of application

The final page of the wizard presents a short video overview of Thread Validator.

note The video has audio

More help is available via the Tutorials tab and the Help menu.

The video is also available on the product website. Visit https://www.softwareverify.com/products.php and find the product link for Thread Validator.

·Finish instructionStep closes the First Run Configuration dialog leaving the application ready to use


Menu Reference

Navigation: The User Interface >

Menu Reference

 Return to chapter overview

The menus provide access to all the major features in Thread Validator. The most common ones are also directly accessible via the toolbars.

The next few pages provide a convenient collection of links to the detailed help pages on each menu item.

Alternatively, click in the picture below to jump to the page for any menu:


File menu

Navigation: The User Interface > Menu Reference >

File menu

 Return to chapter overview

Files and sessions

The File menu allows you to:

·open, close and save sessions

·manage the launching of an application

·control the collection of data

·exit the application

Most of these actions (those with an icon to the left) are also available via the standard or session toolbars.

Near the bottom of the menu, a list of recently used filenames allows you to easily reload a previously saved session.

interactive Click on an item in the picture below to find out more:

note The last two items are not linked to topics. Exit is self explanatory and above that is a list of recently opened files that will vary for each user.


Launch menu

Navigation: The User Interface > Menu Reference >

Launch menu

 Return to chapter overview

The Launch menu allows you to:

·start applications and restart applications

·inject into running applications

·wait for applications to start then attach to them

·monitor services and ISAPI extensions

·stop monitoring an application

Most of these actions are also available via the standard or session toolbars.

interactive Click on an item in the picture below to find out more:


Edit menu

Navigation: The User Interface > Menu Reference >

Edit menu

 Return to chapter overview

Using the clipboard and selections

The Edit menu options can be used to:

·clear all selected items in a table or tree

·copy selected items (and relevant data where applicable) to the clipboard

·select all the items available

Selected data is formatted into one line per row with a single tab-space used to separate column data (tsv format).

note Select All will include the header row as well as the data, and Copy will include the column titles.

For example, after running the example application, Select All on the Locks Per Thread tab might show:

This would result in the following tab separated content being copied to clipboard:

Address Lock Recursion Contention C/L Ratio Wait Time Sequence Locked Waiting Owning Module

ThreadId:16216 (CTeststakView::threadProc_badB) 36 0 30 83.33% 2,188ms WrAlertByThreadId - StateWait Ctx:34 Name: CTeststakView::threadProc_badB

0x03233284 18 0 14 77.78% 2,862ms - - - 0x00404b63 : c:\program files (x86)\software verify\thread validator x86\examples\nativeexample\testsvw.cpp Line 1472

0x03233264 18 0 16 88.89% 3,227ms - - - 0x00404b5a : c:\program files (x86)\software verify\thread validator x86\examples\nativeexample\testsvw.cpp Line 1470

ThreadId:13284 (CTeststakView::threadProc_goodC) 9 0 1 11.11% 4,110ms 6,338 - Sleeping Ctx:9 Name: CTeststakView::threadProc_goodC

0x032332fc 3 0 0 0.00% - 6,267 Abandoned - 0x00404d18 : c:\program files (x86)\software verify\thread validator x86\examples\nativeexample\testsvw.cpp Line 1552

0x032332dc 3 0 0 0.00% - 6,266 Abandoned - 0x00404d0f : c:\program files (x86)\software verify\thread validator x86\examples\nativeexample\testsvw.cpp Line 1550

0x032332bc 3 0 1 33.33% 8,221ms 6,265 Abandoned - 0x00404d06 : c:\program files (x86)\software verify\thread validator x86\examples\nativeexample\testsvw.cpp Line 1549

ThreadId:12756 (TpCallbackIndependent) 0 0 0 0.00% - WrQueue - StateWait Ctx:41 Name: TpCallbackIndependent [Has thread stalled?]

ThreadId:10900 (CTeststakView::threadProc2) 2 0 1 50.00% 14,261ms WrAlertByThreadId - StateWait Ctx:4 Name: CTeststakView::threadProc2 [!DEADLOCKED] [Has thread stalled?]


Settings menu

Navigation: The User Interface > Menu Reference >

Settings menu

 Return to chapter overview

Settings and UI mode

The Settings menu allows you to:

·choose the user interface mode (wizards or dialogs)

·change settings for global data and how it is displayed

Global settings are also accessible via the session toolbar.

interactive Click on an item in the menu below to find out more:


Managers menu

Navigation: The User Interface > Menu Reference >

Managers menu

 Return to chapter overview

Managers and markers

The Managers menu provides tools for

· managing sessions including limiting the number that can be open

·managing watermarks and bookmarks

·exclude thread data using thread filters

interactive Click on the menu item in the picture to find out more:


Query menu

Navigation: The User Interface > Menu Reference >

Query menu

 Return to chapter overview

Query and Search

The query and search tools enable you to find particular thread data collected in each session.

Some of these options are also available from the Query toolbar.

interactive Click on an item in the picture below to find out more:


Tools menu

Navigation: The User Interface > Menu Reference >

Tools menu

 Return to chapter overview

Tools and Information

The Tools menu provides access to a few different tools including a couple not found on the Tools toolbar:

·A list of the modules loaded by your target application

·A list of the debug information status of modules loaded by your application

interactive Click on an item in the picture below to find out more:


Data Views menu

Navigation: The User Interface > Menu Reference >

Data Views menu

 Return to chapter overview

Data Views

The Data Views menu provides easy control of which tabs are displayed in the main view.

Selecting any of the items shows the relevant tab (if it's not visible already), and makes it the current selected tab.

·Hide All Views instructionStep hides all tabs except the one that's currently visible

·Show All Views instructionStep shows all the listed tabs, and in their normal order

·Reset All Views instructionStep shows only the most popular tabs, so excludes the Analysis, and the Line Times tabs

This is the default setting when you first use the software

When you hide a tab (by clicking the cross on the right of the tab header), you'll initially be reminded of where to go to show it again, but you can choose not to keep seeing this reminder.

Hidden views are remembered between sessions.


Software Updates menu

Navigation: The User Interface > Menu Reference >

Software Updates menu

 Return to chapter overview

Software updates

All three items in this menu are covered in the Software Updates topic.


Help menu

Navigation: The User Interface > Menu Reference >

Help menu

 Return to chapter overview

Help

The help menu provides access to this manual in different formats as well as tips and tutorials.

Interactive clickable image Click on an item in the picture below to find out more about each item in the Help topic:

seeAlso Check out the Frequently Asked Questions as well!


Toolbar Reference

Navigation: The User Interface >

Toolbar Reference

 Return to chapter overview

This reference section lists the various toolbars in Thread Validator, with quick links to their own section of the help manual.

The items are listed in left to right order.

You can click on any part of the pictures below to jump straight to the topic:

Standard toolbar

Interactive clickable image

toolbar-standard

· Load session

· Save session

· Help

Session toolbar

Interactive clickable image

toolbar-session

· Settings

· Inject into application

· Launch application

· Relaunch application

· Wait for application to start

· Stop application

· Enable collecting data

· Disable collecting data

Watermarks

Interactive clickable image

toolbar-watermarks

· Watermark manager

· Bookmark manager

· Add watermark at most recent trace

· Add bookmark at most recent trace

Query

Interactive clickable image

toolbar-query

· Search synchronization objects

· Find function

· Single thread critical section detector

· Display stack traces for all threads in application

Tools

Interactive clickable image

toolbar-tools

· Refresh view

· Refresh all views


The status bar

Navigation: The User Interface >

The status bar

 Return to chapter overview

Elements of the status bar

The status bar has three main sections, from left to right:

·the message line

·program information

·data collection statistics

The message line

Most of the time, you'll just see this:

When you hover your mouse over a toolbar button or a menu item for a short time, a help message appears in the status bar describing the button's action.

Data collection statistics

The data statistics counts give a guideline indicator of how data is being collected by the stub and sent to Thread Validator.

This collection data has a few counters and a collection status:

·Status indicating whether collection is currently on or off

·Data items sent from stub that are waiting to be processed

·Number of data items processed

·Number of data items not yet resolved

The boxes stay gray when the values are static, but will be coloured for a few seconds when the value changes:

objects-colours-red The value increased

objects-colours-blue The value decreased

Profiling status

The status of the flow trace indicates what is currently happening.

·Ready. Waiting to start a run, or a run has finished and is waiting for you to analyze the data.

·Starting. Starting a run (hooks being installed etc).

·Running. Target executable is hooked and running.

·Terminating. Target executable has entered ExitProcess but has not yet finished executing.

·Post Processing. Target executable has finished executing. There is data that still needs to be processed.

Target program name

This displays No active session when there is no session running, terminating or loaded.

When a session is running, terminated or loaded, this displays the name of the target program followed by a timestamp.


Keyboard Shortcuts

Navigation: The User Interface >

Keyboard Shortcuts

 Return to chapter overview

Keyboard shortcuts

The following shortcuts are available:

+ [image] Select All

+ [image] Copy

+ [image] Open session

+ [image] Save session

Help (contextual for current view or dialog)

Wait for application

Inject into process

Start application

Restart application

Monitor a Service

Monitor IIS and ISAPI


Icons

Navigation: The User Interface >

Icons

 Return to chapter overview

Some of the displays include an icon on the left border of the scrolled list/tree to indicate the type of data that is present on that line. The icons are shown below, with an explanation.

Icons used in settings, views and editors

Option enabled

Option disabled
Source code line indicator

Source code

Icons used in the data displays

Some of the displays include an icon on the left border of the scrolled list/tree to indicate the type of data that is present on that line.

Watermark placed by the user
iconH Critical section allocation

iconh-green-yellow Critical section deallocation

Trace message, or OutputDebugString() message

Trace from an exception
Trace from an ASSERT


The main display

Navigation: The User Interface >

The main display

 Return to chapter overview

The tab windows

The main display of Thread Validator consists of tabbed windows. Not all the tabs may be visible - see the Data Views menu to show any hidden tabs.

Each tab allows the data collected to be viewed, inspected and queried in different and complementary ways.

Typical usage might be to use the Summary, or various Locks tabs to monitor the thread activity in the target program, and then use another view to gain insights at a different granularity or about related functions and callstacks.

interactive Click on an item in the picture below to find out more about each of the tabbed windows, or use the list further below:

· Summary

· Locks

· Wait Chains

· Threads

· Analysis

· Diagnostic

· Tutorial

Hiding and showing tabs

Each tabbed window can be closed by clicking the small [x] on the right hand side of the tab. The window can be redisplayed from the Data Views menu.

Icons

Most windows use a small number of icons to indicate different types of data.


Summary

Summary Locks

Navigation: The User Interface > The main display >

Summary Locks

 Return to chapter overview

The Summary tab displays a dashboard showing high level information about the threading behaviour of the current application.

The Summary tab

The summary shows a visual overview with statistics of threads and locks with percentages where appropriate.

Each bar or dial summarises the thread, lock, wait or error information found in the main tabs.

· Threads

· Locks

· Contentions

· Recursions

· Waits

· Errors

· Coverage

Clicking on a bar or dial takes you to the corresponding main tab to explore in more detail.

Most of the bars take you to the All Locks summary tab, with each one sorting on a specific column related to the data at hand.

Examples:

·Clicking on the Contended locks bar shows the All Locks tab sorted by Contention Count

·The Max Contention Ratio bar shows the same tab sorted by Contention Ratio

·The Recursions Locks re-entered bar shows the All Locks tab sorted by Recursion Count

·The Coverage dial shows the Coverage tab

Understanding the bars

Each bar displays the name of the statistic underneath with its value.

Bars are filled to represent the fraction of the value it is related to.

In the example below, the bars show that:

·the number of contended locks is 6, shown as a fraction of the number of locks (in this case 51 which was displayed separately on the Locks panel)

·the number of contended threads is 7, shown as a fraction of the 12 threads being monitored in the application (displayed on the Threads panel)

·the total number of contentions is 676, of which one of the locks is responsible for 283 of those contentions

·the maximum contention ratio is 100%.

Understanding the dial

The Coverage dial displays:

·numeric statistics on visited and unvisited items, and those items with 100% coverage

·the unvisited/visited information as angular data

·the 100% coverage as inner radial data

·the partial coverage distribution as outer radial data

Example:

The following dial summarises thread coverage data on a total of 151 known files in a complex target program

note The radius of the inner area may grow or shrink as the target program runs, since the proportion of visited functions that have 100% coverage can go up or down.

Status summary area

Below the dials is a status area showing any comments or special notices related to the current session.

Underneath the comments you'll find the status of any data collection, error detection, filters, or session merging.

Clicking Edit... or View... opens a dialog to edit or view the relevant settings.

In most cases the settings shown are identical to the relevant page of the global settings dialog.

Comments:

·Debug modules

View... instructionStep Module debug information dialog

Data Collection:

·Locks and callstacks

Edit... instructionStep Collect settings

Hook Insertion:

·Locks and handles

Edit... instructionStep Hook Insertion Settings

Error Detection:

·Threading errors

Edit... instructionStep Detect settings

Filter Summary:

·DLLs Hooked | Edit... instructionStep Hooked DDLs settings
·Instrumentation logging | Edit... instructionStep Instrumentation Logging settings (If logging is off) View... instructionStep Instrumentation Log dialog (If logging is on)

Thread Coverage:

·Thread coverage collection | Edit... instructionStep Thread Coverage Settings
·Session manager status | Edit... instructionStep Session Chooser dialog
·Session merging status | Edit... instructionStep Auto Merge settings


Locks

Navigation: The User Interface > The main display >

Locks

 Return to chapter overview

The Locks tab contains three different sub tabs, each providing a different view onto the Critical Sections in use and the Waits that are taking place in the program.

All Locks

Displays all locks in use by the program. Also displays any waits in progress.

Locks Per Thread

Displays all locks in use by the program. Also displays any waits in progress. Data is grouped by thread.

Active Locks

Displays all locks that are currently locked by the program. Also displays any waits in progress.


All Locks

Navigation: The User Interface > The main display > Locks >

All Locks

 Return to chapter overview

The All Locks tab displays information about all critical sections, and WaitForXXXObject calls in the application being monitored.

interactive Read on, or click a part of the image below to jump straight to the help for that area.

The Locks View

The Locks view shows information about each critical section used by the target application.

Each critical section is shown once and the display can be sorted by different criteria by clicking on the appropriate column header.

The table highlights error and status conditions using the user defined lock colours. In the example above, red col-deadlock indicates a deadlock, yellow col-contended contention and cyan col-recursion recursion.

Lines highlighted in grey denote an active status, meaning that the critical section has been entered, while the white lines show sections where nothing of interest has happened yet.

What data is available?

The following table lists all the available columns of data:

Attribute

Description

·Address

Address of the critical section, the handle for a WaitForSingleObject call, or the number of handles for a WaitForMultipleObjects call.

·Lock

Number of times the critical section has been locked by any thread.

·Recursion

Number of times the critical section has been re-entered whilst locked by the current thread.

·Contention

Number of attempts a thread has made to acquire the critical section but has had to wait because it is owned by another thread.

·Wait Time

Total time spent waiting by all threads to gain access to this critical section.

·Sequence

The sequence id is an internal monotonic integer that is incremented for each synchronization object event. This integer allows you to identify the order in which events occurred.

Note that this can be misleading if the windows scheduler switches threads at the wrong time.

·Thread

Thread id (in decimal notation) of the thread that currently owns the critical section.
A number in brackets is the number of other threads waiting to gain access.

If the thread has been given a name, it is displayed.

·State

Current state of the thread, obtained by polling the operating system for data at regular intervals.
This information may not match the other data at all times, but it's very useful for identifying thread conditions when thread states don't change for long periods, e.g. long wait states and deadlocks.

·Owning Module

One or more of the following values if available, shown in order of priority with most important first:

·Symbol name (within 256 bytes of the critical section address) for the critical section

·Filename and line number of the code location that acquired the lock, determined from the callstack (if collected)

·Filename and line number of the critical section

·Name of the owning module, if the critical section is static data inside a module (DLL or EXE)

·Data indicating dynamic memory or stack space

Some of these details can be optionally hidden using the Display options.

Percentage bars and markers

All the cells in the table that show timing or count data have a percentage bar indicating the item's value relative to the maximum value in the column.

Not all bars are percentages. In the Sequence column, the markers indicate the relative position of the sequence id (see table above) with respect to the first sequence id and most recent sequence id.

Updating the display

·Update Interval instructionStep automatically updates the display at your choice of interval, from 0.1 to 60 seconds

This should be set depending on the complexity of your application.

note An update interval that is too short may mean Thread Validator spends too much time updating the display.

·Refresh instructionStep updates the display - as does the refresh button on the Tools menu and toolbar

Sorting the data

You can sort the data in the table by clicking in the table header.

See what data is available for descriptions of each column.

note Note that while your application is executing, the sorted data is live. Sorting may not complete correctly as the data may change during the sort. Only when your program has finished executing is the sorted data guaranteed accurate.

Display settings

The Locks Settings dialog controls a small number of highlighting and display options.

·Display... instructionStep show the Locks Settings dialog:

Highlighting settings:

·Highlight active instructionStep initialised (entered) critical sections are shown in the active colour (grey col-entered by default)

·Highlight contended instructionStep critical sections that have had to wait are shown in the contending colour (yellow col-contended )

·Highlight recursion instructionStep re-entered critical sections are shown in the recursion colour (cyan col-recursion )

The next three display settings control the display of Module, Filename and Class in the Owning Module data column.

Other options include:

·Reset instructionStep resets these values to their startup values (all checked)

·Apply instructionStep apply the settings to the Locks view without closing the dialog

Locks menu options

The following popup menu is available over the data area to add filters, examine more details or edit code.

Menu actions apply to the function for the row at the menu-click location.

Menu options: Information about lock or wait

·Information about lock/wait... instructionStep shows the relevant information dialog from those below, and depending on the type of item selected

These information dialogs do not block the application so you can show as many as you need, either from this tab or others, and leave them open to compare or investigate later.

Menu options: Lock acquisition order

·Lock Acquisition Order instructionStep shows the Locks and Waits in Sequence Order dialog

This dialog displays the order...

·in which critical sections are locked and waited upon

·that waits are entered into

·in which threads sleep and are suspended

Menu option: editing source code

·Edit Source Code... instructionStep opens the default or preferred editor to edit the source code

Menu options: creation callstack

·Show Creation Callstack... instructionStep shows the Critical Section Callstack dialog for the creation of this item, i.e. the locked or waiting critical section and thread

Menu options: contended / recursion callstack

The following menu item is only available over contended critical sections (highlighted in yellow col-contended by default)

·Show contended callstacks... instructionStep shows the Contended Critical Sections dialog for this item

This dialog can only be shown if the callstack information is still available. If not you'll hear a beep.

The following menu item is only available over recursing critical sections (highlighted in light blue col-recursion by default)

·Show recursion callstacks... instructionStep shows the Recursing Critical Sections dialog for this item

This dialog is very similar to the one for contentions, above.

As above, this dialog can only be shown if the callstack information is still available. If not you'll hear a beep.

·Show busy lock callstacks... instructionStep shows the busy Critical Sections dialog for this item

This dialog is very similar to the one for contentions, above.

As above, this dialog can only be shown if the callstack information is still available. If not you'll hear a beep.

·Show slow lock callstacks... instructionStep shows the slow Critical Sections dialog for this item

This dialog is very similar to the one for contentions, above.

As above, this dialog can only be shown if the callstack information is still available. If not you'll hear a beep.

·Show lock callstacks... instructionStep shows the Critical Sections dialog for this item

This dialog is very similar to the one for contentions, above.

As above, this dialog can only be shown if the callstack information is still available. If not you'll hear a beep.


Locks Per Thread

Navigation: The User Interface > The main display > Locks >

Locks Per Thread

 Return to chapter overview

The Locks Per Thread displays information about the critical sections and WaitForXXXObject calls used by each thread in the application being monitored.

interactive Read on, or click a part of the image below to jump straight to the help for that area.

The Locks Per Thread View

The view shows information about critical sections used by each thread in the target application.

In the example above, information for six threads are displayed, with each thread having with a summary header row identified by the ThreadId:nnn in the Address field.

An additional three threads (TpCallbackIndependent) are shown but have no associated locks or waits.

Thread rows will be highlighted orange col-threadinfo (thread information colour), or pale red col-stalled (the stalled thread colour) unless you customise these colours.

Each relevant critical section is shown once underneath each thread and the display can be sorted by different criteria by clicking on the appropriate column header.

The table highlights error and status conditions using the user defined lock colours. In the example above, red col-deadlock indicates a deadlock, and cyan col-recursion for recursion.

Lines highlighted in grey col-entered denote an active status, meaning that the critical section has been entered.

Unlike the All Locks tab, critical sections where nothing of interest has happened are not displayed.

Any WaitForXXXObject calls used by each thread in the application are also listed.

What data is available?

The following tables list all the available columns of data.

note Note that the thread header rows display different information to the critical section rows.

For critical section rows:

Attribute

Description

·Address

Address of the critical section, the handle for a WaitForSingleObject call, or the number of handles for a WaitForMultipleObjects call.

·Lock

Number of times the critical section has been locked by any thread.

·Recursion

Number of times the critical section has been re-entered whilst locked by the current thread.

·Contention

Number of attempts a thread has made to acquire the critical section but has had to wait because it is owned by another thread.

·Wait Time

Total time spent waiting by all threads to gain access to this critical section.

·Sequence

The sequence id is an internal monotonic integer that is incremented for each synchronization object event. This integer allows you to identify the order in which events occurred.

Note that this can be misleading if the windows scheduler switches threads at the wrong time.

·Locked

Shows "Locked" if the critical section is locked.

·Waiting

Shows "Waiting" if the critical section is waiting.

·Owning Module

One or more of the following values if available, shown in order of priority with most important first:

·Thread name only if the thread has been given a name, the thread name is also displayed

·Filename and line number of the code location that acquired the lock, determined from the callstack (if collected)

·Filename and line number of the critical section

·Name of the owning module, if the critical section is static data inside a module (DLL or EXE)

·Data indicating dynamic memory or stack space

Some of these details can be optionally hidden using the Display options.

For thread header rows, the information is typically a total for the thread as a whole, or an indication of thread state.

Attribute

Description

·Address

Thread Id

·Lock

The total number of locks acquired by this thread

·Recursion

The total number of context switches performed by this thread

·Contention

The total number of critical section contentions for this thread

·C/L Ratio

The percentage of the total contentions over the total number of locks for this thread

·Wait Time

The total number time spent waiting for access to critical sections

·Sequence

Not used

·Locked

Not used

·Waiting

The current state of the thread - as obtained by polling the operating system for data at regular intervals. As such this information may not match the other data at all times.

This information is very useful for identifying thread conditions when thread states do not change for long time periods (long wait states and deadlocks).

·Owning Module

Information about thread errors.

As an example, in the image at the top of this page the thread entry lines (starting with ThreadId::nnn in the Address column), you can see that the data for deadlocked threads reads [!DEADLOCKED] and the data for threads with recursions reads [!Locking errors], indicating serious errors for these threads.

Other messages might indicate that the thread is suspended, sleeping, stalled or has had an exit from a critical section that has not been entered.

If nothing of interest is happening the cell will just be left blank.

Percentage bars and markers

All the cells in the table that show timing or count data for critical sections have a percentage bar indicating the item's value relative to the maximum value in the column.

Not all bars are percentages. In the Sequence column, the markers indicate the relative position of the sequence id (see table above) with respect to the first sequence id and most recent sequence id. Thread header rows show the marker position for the highest sequence id of any locks in that thread.

Updating the display

·Update Interval instructionStep automatically updates the display at your choice of interval, from 0.1 to 60 seconds

This should be set depending on the complexity of your application.

note An update interval that is too short may mean Thread Validator spends too much time updating the display.

·Refresh instructionStep updates the display - as does the refresh button on the Tools menu and toolbar

Sorting the data

You can sort the data in the table by clicking in the table header.

See what data is available for descriptions of each column

note Note that while your application is executing, the sorted data is live. Sorting may not complete correctly as the data may change during the sort. Only when your program has finished executing is the sorted data guaranteed accurate.

Display settings

The Locks Settings dialog controls a small number of highlighting and display options.

·Display... instructionStep show the Locks Per Thread Settings dialog:

Highlighting settings:

·Highlight active instructionStep initialised (entered) critical sections are shown in the active colour (grey col-entered by default)

·Highlight contended instructionStep critical sections that have had to wait are shown in the contending colour (yellow col-contended )

·Highlight recursion instructionStep re-entered critical sections are shown in the recursion colour (cyan col-recursion )

The next three display settings control the display of Module, Filename and Class in the Owning Module data column.

Other options include:

·Reset instructionStep resets these values to their startup values (all checked)

·Apply instructionStep apply the settings to the Locks view without closing the dialog

Locks Per Thread menu options

The following popup menu is available over the data area to add filters, examine more details or edit code.

Menu actions apply to the function for the row at the menu-click location.

Menu options: Information about lock or wait

·Information about lock/wait... instructionStep shows the relevant information dialog from those shown for the same menu option on the All Locks tab

Menu options: Lock acquisition order

·Lock Acquisition Order instructionStep shows the Locks and Waits in Sequence Order dialog

This dialog displays the order...

·in which critical sections are locked and waited upon

·that waits are entered into

·in which threads sleep and are suspended

Menu option: editing source code

·Edit Source Code... instructionStep opens the default or preferred editor to edit the source code

Menu options: show ... callstacks

Each of these four options show the Critical Section Callstack dialog for the selected item's callstack

·Show Creation Callstack... instructionStep shows the callstack for the creation of this item, i.e. the locked or waiting critical section and thread

·Show Lock Callstack... instructionStep shows the callstack for the locked or waiting critical section and thread

·Show All Lock Callstacks (this thread)... instructionStep shows all callstacks for this critical section and only this thread

·Show All Lock Callstacks (all threads)... instructionStep as above but for any thread

The following menu item is only available over recursing critical sections (highlighted in light blue col-recursion by default)

·Show recursing callstack... instructionStep shows the Recursing Critical Sections dialog for this item

The critical section in question is shown at the top.

This dialog can only be shown if the callstack information is still available. If not you'll hear a beep.

The following menu item is only available over contended critical sections (highlighted in yellow col-contended by default)

·Show contended callstacks... instructionStep shows the Contended Critical Sections dialog for this item

This dialog is very similar to the one for recursions, above.

As above, this dialog can only be shown if the callstack information is still available. If not you'll hear a beep.

The following menu item is only available over recursing critical sections (highlighted in light blue col-recursion by default)

·Show recursion callstacks... instructionStep shows the Recursing Critical Sections dialog for this item

This dialog is very similar to the one for contentions, above.

As above, this dialog can only be shown if the callstack information is still available. If not you'll hear a beep.

·Show busy lock callstacks... instructionStep shows the busy Critical Sections dialog for this item

This dialog is very similar to the one for contentions, above.

As above, this dialog can only be shown if the callstack information is still available. If not you'll hear a beep.

·Show slow lock callstacks... instructionStep shows the slow Critical Sections dialog for this item

This dialog is very similar to the one for contentions, above.

As above, this dialog can only be shown if the callstack information is still available. If not you'll hear a beep.

·Show lock callstacks... instructionStep shows the Critical Sections dialog for this item

This dialog is very similar to the one for contentions, above.

As above, this dialog can only be shown if the callstack information is still available. If not you'll hear a beep.

·Show all lock callstacks (this thread)... instructionStep shows the Critical Sections dialog for this item

This dialog is very similar to the one for contentions, above.

As above, this dialog can only be shown if the callstack information is still available. If not you'll hear a beep.

·Show all lock callstacks (all threads)... instructionStep shows the Critical Sections dialog for this item

This dialog is very similar to the one for contentions, above.

As above, this dialog can only be shown if the callstack information is still available. If not you'll hear a beep.


Active Locks

Navigation: The User Interface > The main display > Locks >

Active Locks

 Return to chapter overview

The Active Locks displays information about the currently active critical sections and WaitForXXXObject calls in each thread of the application being monitored.

interactive Read on, or click a part of the image below to jump straight to the help for that area.

The Active Locks View

The view shows information about critical sections currently locked or waiting for each known thread in the target application.

The display and controls are the same as the Locks Per Thread tab, except that here only currently active locks are listed, rather than all previously active critical sections.

In the example above information for seven threads are displayed, with each thread having with a summary header row identified by the ThreadId:nnn in the Address field.

Thread rows will be highlighted in the thread information colour (orange col-threadinfo by default), or pale red col-stalled, the stalled thread colour unless you customise these colours.

Each relevant critical section is shown once underneath each thread and the display can be sorted by different criteria by clicking on the appropriate column header.

The table highlights error and status conditions using the user defined lock colours. In the example above, yellow col-contended indicates a contention, and cyan col-recursion for recursion.

Lines highlighted in grey col-entered denote an active status, meaning that the critical section has been entered.

Unlike the All Locks tab, critical sections where nothing of interest has happened are not displayed.

Any WaitForXXXObject calls used by each thread in the application are also listed.

note There may not be any critical sections listed for a given thread.

What data is available?

The columns displayed in the Active Locks view are identical to the columns on the Locks Per Thread tab.

note Note that like the Locks Per Thread, the thread header rows display different information to the critical section rows.

Display settings

The Active Locks Settings dialog below, is identical to the Display Settings on the Locks Per Thread tab.

Active Locks menu options

Like the display settings, the menu options are also the same as those on the Locks Per Thread tab.


Wait Chains

Navigation: The User Interface > The main display >

Wait Chains

 Return to chapter overview

The Wait Chains tab displays information about all the wait chains for the application being monitored.

The Display

Wait chain information is colour coded. Errors are displayed in red, healthy statuses in black and green. Software Verify threads are displayed in purple so that they are easily identifiable as "not your threads".

For any selected thread, that thread and related threads are shown with a yellow background. This is useful so easily identifying threads that are interacting with each other (in a deadlock or a complex wait), or which are not interacting with any other thread at all.

Information that is displayed about each thread:

Thread id

This is the numeric identifier assigned to the thread by the Windows operating system.

Thread Name

This is the name of the thread if the thread has been given a name using the SetThreadDescription() API. This is only available on Windows 10.

If a thread description is not available we use any thread name that is provided using the Microsoft Thread Naming Exception.

If a thread description is not available by either of the above two methods we attempt to provide a name for this thread by querying the thread's start address, and if successful we try to turn this start address into a useful symbolic name. Depending on the process and the operating system these operations may success, in which we display a name, or they may fail in which case we display nothing.

Thread Wait Chain

This is the wait chain for this thread. For each entry we show the process id and the thread id and if the object being waited upon has a name, we show that too. If process names and thread names have been enabled we show these as well. Some wait chains rely on waiting for other processes, which are more readily identified by process name than process id. Any deadlocks that are detected are shown in red.

Wait Time

This is how long the thread has been waiting.

Context switches

This is the number of context switches this thread has been involved in.

Status

The status of this thread. Is the thread running, waiting, sleeping, etc.

Reason

The reason for the status of this thread if the thread is waiting.

Priority

The thread priority.

Cpu Cycles

The number of cpu cycles spent executing this thread.

Thread Time

The amount of time spent executing this thread (returned by the GetThreadTimes() API).

CAUTION! This value can be misleading as it only counts whole thread quanta that complete, any thread that switches before it's quanta is complete doesn't add to this count.

Cpu Delta

The amount of cpu cycles spent executing this thread since the last time we updated the display.

CPU

The percentage of CPU that is being used by this thread (percentage relative to this process, not relative to all processes).

Controls

There is only one control for this display

·Hexadecimal instructionStep displays values in hexadecimal when selected, decimal when not selected

Context Menu

If you right click on the grid, a context menu is displayed.

·Lock Acquisition Order... instructionStep displays a dialog to allow you to view the order the locks in a wait chain were acquired.

In the image below, the locks are all involved in a deadlock over which context menu was displayed.

·Show All Callstacks... instructionStep for the selected lock (or all locks involved in a wait chain) the callstack for that lock is displayed.


Threads

Navigation: The User Interface > The main display >

Threads

 Return to chapter overview

The Threads tab lets you monitor the history of lock states in each thread in relation to other threads.

interactive Read on, or click a part of the image below to jump straight to the help for that area.

The Thread History View

The view is split vertically into two halves.

The top half monitors a history of lock activity in known threads on a horizontal time-line using sampled snapshots of the thread states.

The state of each thread is displayed as a coloured block, as defined by the lock colour settings.

For example, below is a sequence of 28 samples of three threads taking part in a good locking strategy which starts after the fifth sample.

Newest samples appear on the right of the display.

Selecting any one of the blocks displays the thread and critical section information in the Locks and Lock Order tabs in the lower half of the view.

When selecting a block, any cells that are related by critical section address or waited Win32 handle are also highlighted.

The interval at which thread states are sampled can be changed (see Update Interval in the next section).

The sampled data is stored in a buffer, the size of which can be specified, but which defaults to 1000 points.

The display can be zoomed from one cell per data item to displaying the entire data buffer on the screen.

Managing the time-line data

The options above the time-line graph (initially blank) let you controlling the recording and display of the sampled data.

·Start / Stop instructionStep control the recording of the sampled thread states

·Clear instructionStep remove all samples from the display and from the sample buffer

You don't have to stop recording before clearing the data

·Update Interval instructionStep automatically updates the display at your choice of interval, from 0.1 to 60 seconds

This should be set depending on the complexity of your application.

note An update interval that is too short may mean Thread Validator spends too much time updating the display.

Display settings

The Thread History Settings dialog controls a small number of recording and display options.

·Display... instructionStep show the Thread History Settings dialog:

·Auto Start instructionStep automatically start recording thread samples when you launch an application

·Don't scroll context menu instructionStep prevent the time-line from updating while its popup menu is open

Data samples are still recorded and are displayed when the menu is closed.

·Cell Size instructionStep choose the size of each cell displayed on the display

The name or id of the thread on the left hand side are also affected.

·Buffer Size instructionStep set the number of samples to keep track of in the time-line (default is 1000)

The buffer operates on a first-in first-out basis, so when the buffer is full, oldest samples are discarded in favour of new ones.

When the buffer is full an overflow warning and a count of lost samples is displayed as below:

·Reset instructionStep reset the above values to their defaults

Thread history menu options

Most of the menu options the same information and callstack options as on the Locks Per Thread tab and several others.

In this thread history view, the menu options apply to the selected sample block in the time-line display.

Three additional options are available, to highlight related blocks within the samples displayed.

·Highlight locked critical sections instructionStep highlight other blocks that locked critical sections or waits used in the selected block

·Highlight contended critical sections instructionStep highlight other blocks that contended critical sections or waits

·Highlight locked and contended... instructionStep highlight other blocks that locked or contended critical sections or waits

The Locks tab

The Locks tab in the bottom half of the view shows information about locked or waiting critical sections for each known thread in the target application.

Only the lock information at the selected sample point in the top graph is displayed. Selecting blocks at different points along the time-line will change the data shown.

The set of displayed information is the same as the Active Locks, except that here only locks active at the selected sample point are listed.

Thread rows will be highlighted in the thread information colour (orange col-threadinfo by default) or pale red col-stalled , the stalled thread colour unless you customise these colours.

Each relevant critical section is shown once underneath each thread and the display can be sorted by different criteria by clicking on the appropriate column header.

The table highlights error and status conditions using the user defined lock colours. In the example above, yellow col-contended indicates a contention, and cyan col-recursion for recursion.

Lines highlighted in grey col-entered denote an active status, meaning that the critical section has been entered.

Unlike the All Locks tab, critical sections where nothing of interest has happened are not displayed.

Any WaitForXXXObject calls used by each thread in the application are also listed.

What data is available in the Locks tab?

The columns displayed in the Lock tab view are identical to the columns on the Locks Per Thread tab (and the Active Locks tab).

note Note that like the Locks Per Thread, the thread header rows display different information to the critical section rows.

Locks tab menu options

The menu options are also the same as those on the Locks Per Thread tab.

Locks tab display settings

The thread history display settings are the same as the Locks Per Thread tab display settings.

·Display... instructionStep shows the Thread History Locks Settings dialog:

Highlighting related time-line data from the Locks tab

Selecting rows in the Locks tab of the lower view highlights related data in the sampled time-line view.

Selecting a row for a...

·Thread instructionStep highlights blocks if they use critical sections and Win32 handles used in the selected thread

·Critical section instructionStep highlights blocks if they use critical sections with the same address

·Single or multiple wait instructionStep highlights blocks if they use Win32 handles with the same handle value(s)

The Lock Order tab

The Lock Order tab in the bottom half of the view shows locks and waits in the sample in sequence number order.

The dialog displays the order...

·in which critical sections are locked and waited upon

·that waits are entered into

·in which threads sleep and are suspended

The data and menu options are very similar to the Locks and Waits in Sequence Order dialog, except that here the entries shown are those at the selected sample point in the time-line.

Selecting an entry (lock, wait or thread) will highlight the other locks, waits and threads that are related. For example selecting a lock will highlight all locks entries that have the same address, regardless of the thread they are used in. Also any other entries related to the same thread are also highlighted. This allows you to see where you hold locks and where the same lock is waiting. The source code showing where the lock is locked or waiting is shown on the right of the display.


Analysis

Navigation: The User Interface > The main display >

Analysis

 Return to chapter overview

The Analysis tab contains four different sub tabs, each providing a different ability to query threading data that isn't necessarily about Critical Sections or Waits (you can query those as well).

Query

The ability to query to find synchronization objects by address, object type, function (class and method), source file, module and thread.

Coverage

Code coverage for synchronization primitives - are your tests hitting all the right places to test your thread synchronization?

Active Objects

All the synchronization objects and waitable handles allocated by the application, including callstack and additional data about each handle.

Object Handles

All the synchronization objects allocated by the application.


Query

Navigation: The User Interface > The main display > Analysis >

Query

 Return to chapter overview

The Analysis tab shows groups of search results and allows you to find many types of related data for different synchronization objects.

If the Analysis tab isn't visible, use the Data Views menu to set which views are shown.

interactive Read on, or click a part of the image below to jump straight to the help for that area.

The Analysis Data

The Analysis tab has two parts separated by a resizing handle.

The top view is where the initial data to work with is displayed - i.e. the result of manual or predefined searches.

The lower display shows any related synchronization objects found using the popup menu options - e.g. other calls with similar addresses or callstacks.

Manual searches allow information about synchronization objects to be displayed based on:

·type (e.g. GDI handle object type)

·file

·function

·DLL

·address or handle value

·size

Predefined searches display:

·locked or waiting critical sections

·abandoned critical sections

·deadlocks or potential deadlocks

·bad lock strategies

·miscellaneous locking errors

·trace messages

The text on each line is the same and indicates:

·datatype (if known)

·address/handle value

·source file and line number (if available) for the function

To edit the source code, double click on any part of the lines of source code displayed or use [image] Edit Source Code...

The upper window - working data

The upper window will contain any results of queries made via the manual or predefined query options on the left.

These results become your 'working data', and will grow (with a header line between each group) as each set of results is added.

Using the relations option on the popup menu, you can then find related allocations or objects which are displayed as separate results in the lower window.

Collected data is displayed in a tree, optionally constrained by watermarks:

·the text on the line indicates the data type (if known), its size, address/handle value, and the source file and line number (if available) where the event occurred

·the colour of the background for the line indicates the status of the data, such as the thread is deadlocked col-deadlock, potentially deadlocked col-potdead, or involved in other errors such as a bad lock strategy col-miscerr

See the section on predefined queries for example views

Each item can be expanded showing some information about the item, such as thread id, timestamp and the callstack for the item.

Each line of the callstack shows the instruction address, module name, undecorated C++ function name and the source file and line number (if available) for that function.

The callstack itself can be expanded (see example below) to display the source code which can also be edited.

note Please note that not all data for the queries is acquired in the same manner. This is because of the measure taken to reduce the amount of memory needed to store data about the locking activity of the application. As a result, queries that you may expect to yield results may sometimes fail to do so because the information required for the query was not collected or was collected in such a manner that it is not available for the query.

The lower window - results within results

Having obtained related data in the lower window you can inspect it in the same way, filter it and promote it back up to the top window.

Analysis tab options - upper window

At the far left of the window are the same Watermark options as on the Active Objects tab.

Choose two watermarks to restrict the displayed data to lie between them.

·First Watermark instructionStep Choose a watermark from the list instructionStep Last Watermark instructionStep Choose another watermark instructionStep Refresh instructionStep updates the data shown in the display

There are two permanent default watermarks, called First watermark (before anything else) and Last watermark (after anything else).

Attempting to choose a first watermark later than the last watermark, or vice-versa will result in the alternate watermark automatically updating.

Analysis tab options - clearing data

The working data in the upper display can be cleared manually or automatically in different ways:

·Clear instructionStep manually remove all working data from the upper window only (the lower window has its own clear button)

·Auto Clear instructionStep clears any existing working data on each new search

·Promote Clears instructionStep automatically clears the working data each time data from the lower window is promoted to the top view

Running data queries

From the buttons at the left you can run some common or very specific queries to search for synchronization objects, thread errors, and messages.

Custom queries

Several of the main tabs have some comprehensive methods of querying synchronization objects or functions, and which are accessible from the main query menu and query toolbar.

The Analysis tab has dedicated buttons for two of these queries:

·Find... instructionStep Shows the Find Synchronization Objects dialog to use a variety of search criteria to search for objects and display them in the Analysis tab

·Functions... instructionStep Shows the Find Functions dialog but displays the results here in the analysis tab

Predefined queries

There are a selection of common predefined queries available at a single click:

·Locked instructionStep finds all locked critical sections

alysis-options-predefined-locked

·Waiting instructionStep all waiting critical sections and waiting handles

·Abandoned instructionStep finds abandoned critical sections (critical sections locked but not owned by any thread)

·Deadlocked instructionStep finds deadlock locations

note You'll need to enable the detection of deadlocks otherwise you'll just see this warning, with the option to edit the settings.

·Potential Deadlocked instructionStep finds locations for potential deadlocks

note You'll need to enable the detection of potential deadlocks otherwise you'll just see this warning, with the option to edit the settings.

search-for-potential

·Bad Lock Strategy instructionStep finds all critical sections involved in bad lock strategies

note To ensure this reports the maximum number of errors you'll need to enable the detection out of order critical sections and other locking errors.

·Misc Lock Errors instructionStep finds a variety of other synchronization errors not covered by the other predefined searches

·Trace Messages instructionStep shows any trace messages if you've switched the trace hook setting on

Analysis tab options - lower window

The lower window has its own comparatively simple set of options:

·Auto Clear instructionStep clears the lower window before adding a new relations search from the upper window

·Clear when Promote instructionStep clears the lower window when promoting these results to the upper window

·Clear Results instructionStep simply empties the lower window

·Filter Results instructionStep optionally filters the lower window data using the same filters as the upper window

·Use Watermarks on Results instructionStep applies the upper window's watermark settings to the lower window

·Include search in results instructionStep brings the upper window item that initiated the relations search along with the results

·Promote Results instructionStep pushes all or selected lower window results into the upper window.

This optionally adds to or replaces what's in the upper window already, depending on the state of the Promote Clears option in the upper window.

Analysis view popup menu

interactive The following popup menu is available over the upper window.

Menu option: relations

The relations menu has a sub-menu with many different options for choosing a set of related data to display in the lower analysis window.

Think of this as a sub-query on the working data - like searching for friends of friends on a social network!

Given an entry in the upper window, available relations are as follows:

·Same address | Finds any other critical sections using the same memory address
·Same handle ·Same object/handle type | Finds any other WaitForSingleObject using the same resource handle Critical sections and wait calls that have the same object type or handle type.
·Same location, same callstack different callstack all callstacks | Finds other critical sections that have the same usage location and: using the same callstack using different callstacks regardless of callstack
·Same source file ·Same DLL | All critical sections in the same source file... or the same DLL
·Same class | All critical sections from the same C++ class
·Entries prior ·Entries after | For critical section events, finds the previous 5, 10 or 20 events or the next 5, 10 or 20 events

Menu option: bookmarks and watermarks

Bookmarks allow you to find a data item easily at a later date, while watermarks are used above to show only those items between two points in time

·Add Bookmark... instructionStep adds a bookmark for the selected item

·Add Watermark... instructionStep adds a watermark for the selected item

Menu option: editing source code

·Edit Source Code... instructionStep opens the default or preferred editor to edit the source code

Menu options: collapse / expand trace

·Collapse or Expand Trace instructionStep simply shows and hides data item information, the same as using the expand-symbol or collapse-symbol buttons

·Collapse All instructionStep completely collapses all data items in the upper window, including any source code views that were open

·Expand All instructionStep expands all data items down to but not including the source code snapshots


Coverage

Navigation: The User Interface > The main display > Analysis >

Coverage

 Return to chapter overview

The Coverage tab lets you find untested parts of your program's thread synchronization code.

If the Coverage tab isn't visible, use the Data Views menu to set which views are shown.

interactive Read on, or click a part of the image below to jump straight to the help for that area.

Using the coverage information

Inspecting the coverage tells you which thread synchronization locations are or are not being tested.

Understanding the thread coverage helps you plan and improve your regression tests to include areas of code that perform thread synchronization but are not yet being visited.

The display shows two resizable panes, one with the coverage data, and the other shows source code when you click on a row in the table.

note In order to gather coverage statistics, you'll need to switch on the thread coverage setting, otherwise you'll just see the reminders below:

Colours used in the displays

Each file's row is coloured according to whether it has:

objects-colours-red no lines visited

objects-colours-yellow some lines visited

objects-colours-light-blue all lines visited

objects-colours-light-gray been filtered out for subsequent sessions (see below)

The % Visited column and the source code view uses the following colours:

objects-colours-light-green for the percentage of lines visited, or visited lines of source code

objects-colours-light-blue for unvisited lines

Coverage data

The data in each column is summarised below

·File

·Num Lines

·Num Visited

·Visit Count

·% Visited

·DLL

the statistics are gathered for each source code file found

number of lines in each file that allocate, reallocate or free memory and handles

the number of those lines that have been visited

total number of visits to those lines

the percentage of relevant lines visited (Num Visited / Num Lines)

the DLL responsible for the file

The Visit Count may be equal to the Num Visited if you have opted to keep the default thread coverage setting of counting visits to each allocation only once. You can change this setting on the fly to start counting multiple visits right away.

At the top of the table is a Totals line showing combined results for all files.

note The statistics here only cover lines that affect thread synchronization, unlike SoftwareVerify's sister tool C++ Coverage Validator externalLink which determines complete code coverage.

Sorting columns

Sorted columns are highlighted yellow in the table header. Click on the header to change the sorting column or its sort direction order.

Source code view

The source code view is syntax-highlighted with green visited and pale red unvisited lines.

The columns at the left show line numbers (in black) and visit counts (blue) for each thread synchronization line. Visit counts are also available via a tooltip.

Coverage options

interactive The following controls are displayed to the left of the coverage results

Filters

Unwanted results in the coverage can be excluded via the filters according to filename, directory or DLL.

Filters can be managed in the filters dialog or added via the menu options [image] below.

·Filters... instructionStep shows the Thread Coverage Filters dialog

The filters dialog is the same one as found on the thread coverage page of the global settings dialog where it is described in detail.

Window orientation

The data and source code panes can be arranged horizontally or vertically with the orientation button.

Updating the display

·Update Interval (s) instructionStep automatically updates the display at your choice of interval between 0.1 and 60 seconds - or not at all!

Adjust this depending on the complexity of your application.

·Refresh instructionStep updates the display - as does the refresh button on the Tools menu and toolbar, and the button on the popup menu

With an update interval set to No Update, you'll need to use this Refresh button to update the display when you wish.

Display settings

On the Coverage tab, there's only the one display option:

·Show Path instructionStep shows the short file name or the longer file path in the File column of the data

Coverage view popup menu

The following popup menu is available over the data area to add filters, refresh the view or edit source code.

Menu options: Filtering coverage

The first three menu options let you add filters at different levels of granularity.

note Filters become effective at the start of the next session. Adding a filter during a session will show the row in grey so that you can see which files are filtered, but the coverage results will continue to be included for the rest of the session.

·Filter coverage data by filename instructionStep adds a new filter to the Filters dialog, excluding the selected file from the results of a subsequent session

·Filter coverage data by directory instructionStep excludes all files in the same directory as the selected file

·Filter coverage data by DLL instructionStep excludes all files belonging to the same DLL as the selected file

Menu option: Refresh

·Refresh... instructionStep updates the statistics displayed in the table

Menu option: Editing source code

·Edit Source Code... instructionStep opens the default or preferred editor to edit the source code


Active Objects

Navigation: The User Interface > The main display > Analysis >

Active Objects

 Return to chapter overview

The Active Objects tab allows you to view and examine synchronization objects that are currently active.

interactive Read on, or click a part of the image below to jump straight to the help for that area.

The Active Objects View

The view shows information about all active synchronization objects.

Each object is listed with its callstack to enable you to drill down to the source code for the call.

When Thread Validator identifies miscellaneous error conditions, data about the conditions and callstack is displayed in this window.

That data can be filtered and restricted by watermarks to fine tune the displayed data.

Examining a data item

Each item can be expanded with the expand-symbol button ( and then collapsed with the collapse-symbol) to show more detailed information:

·thread id and the name, if assigned

·timestamp

·the callstack for the item

Each line of the callstack shows:

·instruction address

·module name

·undecorated C++ function name

·source file and line number (if available) for the function

Examining the callstack and code

One or more parts of the callstack can be expanded or collapsed using the expand-symbol or collapse-symbol to show the source code around the relevant line in the associated file.

If the source code can't be found, or the file location is invalid you'll be prompted for the file.

The line on which the allocation occurred is highlighted, e.g. green in this example:

To edit the source code, double click on any part of the lines of source code displayed or use [image] Edit Source Code...

Source file not found automatically?

If the source file isn't found automatically, you'll be prompted to provide the location manually with the Find Source File dialog

You can scan, search or browse for the source location depending on how much of an idea you have of the location:

·Browse... instructionStep uses an explorer to search manually

·Search All Drives... instructionStep does a full scan of your computer, showing the Searching For Source Files dialog

You can stop the search at any time

If a file is found, the filename is entered at the top of the Find Source File dialog.

If multiple results are found, pick the best one from the results dialog that appears:

·Search Folder... instructionStep prompts for a folder, and scans that using the same Searching For Source Files dialog as above

If multiple results are found, pick the best one from the results dialog (above)

Rather than repeatedly searching manually for locations, it's recommended to modify the automatic source file search paths:

·File Locations... instructionStep shows the File Locations Settings dialog so you can change the automatic search paths

Changing the search paths to include additional source locations means you'll get prompted less.

The file locations settings dialog is identical to the File Locations page of the global settings dialog.

If you don't want to be prompted with this dialog, then uncheck the first option below

·Ask for location of file if file cannot be found in search paths instructionStep shows this dialog each time you try to open a source file where the location is unknown

·Don't ask for location of file if line number is not valid instructionStep stops this dialog from showing when line numbers are invalid, e.g. zero or negative

The default is not to ask in this case.

Watermarks

The amount of data in the main display can be reduced by watermarks.

Here you can choose two watermarks allowing only the data between them to be displayed.

·First Watermark instructionStep Choose a watermark from the list instructionStep Last Watermark instructionStep Choose another watermark instructionStep Refresh instructionStep updates the data shown in the display

There are two permanent default watermarks, called First watermark (before anything else) and Last watermark (after anything else).

Attempting to choose a first watermark later than the last watermark, or vice-versa will result in the alternate watermark automatically updating.

Updating the display

·Display... instructionStep show the Active Objects Display Settings dialog

Choose the types of data to display and whether the data should be grouped or displayed individually.

·Refresh instructionStep refresh the list manually when you need to

·Group by callstack instructionStep groups information by related callstack (default)

note The number of items in an ungrouped table can get very long when there are many items with the same callstack.

Active objects menu options

The following popup menu is available over the data area to add bookmarks, watermarks and edit source code.

Menu actions apply to the function for the row at the menu-click location.

Menu option: bookmarks and watermarks

Bookmarks allow you to find a data item easily at a later date, while watermarks are used above to show only those items between two points in time.

·Add Bookmark... instructionStep adds a bookmark for the selected item

·Add Watermark... instructionStep adds a watermark for the selected item

Menu option: editing source code

·Edit Source Code... instructionStep opens the default or preferred editor to edit the source code

Menu options: collapse / expand trace

·Collapse or Expand Trace instructionStep simply shows and hides data item information, the same as using the expand-symbol or collapse-symbol buttons

·Collapse or Expand All instructionStep hides or shows all the available callstack information for every listed item


Object Handles

Navigation: The User Interface > The main display > Analysis >

Object Handles

 Return to chapter overview

The Objects view displays a list of all the waitable handles the target program is using (except those used by Thread Validator).

The Objects View

The display is a scrolled list displaying:

·type (e.g. GDI handle object type)

·handle value

·kernel address

·object flags

·object name (if available)

The list can be sorted in increasing or decreasing by clicking in the header of any column.

Updating the display

·Update Interval (s) instructionStep automatically updates the display at your choice of interval between 0.1 and 60 seconds - or not at all!

Adjust this depending on the complexity of your application.

·Refresh instructionStep updates the display - as does the refresh button on the Tools menu and toolbar

With an update interval set to No Update, you'll need to use this Refresh button to update the display when you wish.

Running 32 bit applications on 64 bit Operating Systems

When running 32 bit applications on 64 bit Operating Systems you may find that the Objects view does not display much information.

If there's little or no information, this is likely because it is not possible to get complete object information in this environment.

There are two solutions to this:

·Run your 32 bit application (and Thread Validator) on a 32 bit operating system

·Run your 64 bit application (and Thread Validator x64) on a 64 bit operating system.


Diagnostic

Navigation: The User Interface > The main display >

Diagnostic

 Return to chapter overview

The Diagnostic view displays all diagnostic information collected from the stub.

There are two subtabs. One for Diagnostic information and one for displaying any data captured from stdout and stderr.

Diagnostic

Diagnostic information

When Thread Validator's stub is injected into the target program, it logs diagnostic information to the main window for inspection.

Examples of diagnostic data collected are below, and may be displayed with a message, although you may not see some of these if all is well:

Hooking information | Other information
·Ordinal hook found ·Hook C++ constructor / destructor ·Function hook success or failure ·Delay loaded function hooked ·Possible hook found ·Function already hooked ·Hook at address | ·DLL load address ·DbgHelp searching ·Image source line ·Unknown instruction found ·Disassembly of troublesome code ·Failed to find Release/Debug CRT heap ·Symbol reader status

The locations of loaded DLLs are also displayed in the window for each LoadLibrary(), LoadLibraryEx() and FreeLibrary() in the target program.

note If for whatever reason, you don't want to collect diagnostic information, you can switch it off in the General > Instrumentation Logging page of the settings dialog

Filtering diagnostic information

By default, all information is displayed, but you can filter the messages to show only one type:

·All instructionStep the default option is to show everything

·Information instructionStep operating system and environment information, etc

·Error instructionStep notification of denied access and other error messages

·Hooks instructionStep hooking success and failure messages

·DLLs instructionStep DLL related information

·Symbols instructionStep symbol loading status messages

·DbgHelp debug instructionStep messages from DbgHelp.dll about the DLL symbol search processes

·Symbols and DbgHelp debug instructionStep both the previous two

As well as filtering different types of lines, you can also search for specific terms:

·Filter instructionStep enter some text and Apply Filter to show lines with the term in the Message column

note When identifying why symbols aren't loading, you'll find it's much easier when showing only the DbgHelp debug information.

Stdout and Stderr

The Stdout tab displays any data collected from stdout and stderr. seeAlso The option to enable this data collection is specified on the launch dialog/wizard.

The above image shows some data collected from a program that reverses the characters in each line passed to it.

·Copy instructionStep copy all data from the display on to the clipboard. For large amounts of data this can be time consuming.

·Clear instructionStep clear the display of any captured data.

·Display Most Recent instructionStep the display will be scrolled to ensure the most recently captured data is displayed.

Environment Variables

Environment variables tab displays environment variables from Thread Validator, environment variables from the program under test and environment variable substitution errors.

Choose which data you wish to view using the combo box at the top left of the tab.

Thread Validator environment variables

Target application environment variables

If you launched the target application from Thread Validator the target application’s environment variables will be similar to those in Thread Validator, but with some additional env vars to control .Net profilers and and some other SVL_ prefixed env vars to communicate various data to Software Verify components that are loaded.

If you launched the target application as a standalone application, or service and used one of our APIs to connect to Thread Validator, the environment variables shown will reflect those in force at the time the application/service was started, and the account that application/service is running on.

Environment variable errors

The environment variable errors display shows the name of the environment variable that could not be found, the string containing the environment variable, a comment indicating where the string came from (in this example, the command line), and a timestamp.

Child Processes

Information about child processes, and the appropriate launch parameters passed to CreateProcess (and related functions) are displayed on this tab.

A context menu is provided to allow you to perform some actions with the launched application data.

·Launch parent application and monitor this application... instructionStep the launch application dialog is displayed configured to launch the parent application and monitor this application

·Launch application... instructionStep the launch application dialog is displayed configured to launch and monitor this application

·Open directory... instructionStep Windows Explorer is launched to view the contents of the launch directory (the directory field is empty nothing will be shown)

·Open application directory... instructionStep Windows Explorer is launched to view the directory that contains the application (if the application specification has no path nothing will be shown)


Floating Licence

Navigation: The User Interface > The main display >

Floating Licence

 Return to chapter overview

The Floating Licence view displays information about the computers using the floating licence.

This view is only displayed if a floating licence has been purchased. Evaluation users will not see this view.

The screenshot above show two computers using the same 2 user floating licence, that has maintenance id 14679. Both computer users are licenced and can use the software.

On startup the software automatically checks to see if a floating licence is available, and acquires the licence if possible. This takes a few seconds to process, after startup of the software

An internet connection is required for floating licences to work. The licence server is managed and run by Software Verify.

Licence information

The information show in this display allows you to identify which of your colleagues are using the software and which versions of the software are in use.

·User

The user id (1 to number of licensed users).

·Computer Name

The name of the computer

·Computer User

The login name of the user of the computer.

·Identifier

The unique identifier for this licence, used on the licence server.

·ID

The maintenance id for the software.

·Software Tool

The software tool and version of the software that is running on that computer.

·Computer ID

The unique id for this computer.

·IP Address

This computer's IP address.

Unlicenced users

If any additional users are trying to get a licence for the software, but there are not enough licences, they will also be shown in the display, but with red text on a yellow background.

Please note that on the machine of an unlicensed user the status information will be different.

The software checks to see if a licence has been released on a periodic basis, so that if a licence is released by another user, it can be acquired by the next waiting user.

Releasing a licence

If you have finished using a licence and wish to let a team mate use the software, you have two choices.

You can close Thread Validator, releasing the licence as it closes.

Or you can keep Thread Validator running by manually releasing the licence. Do this by clicking the Release Licence button.

Acquiring a licence

If you have released a licence you will need to actively reclaim a licence when you wish to use Thread Validator again. You can start this procedure by clicking the Acquire Licence button.


User Interface Mode

Navigation: The User Interface >

User Interface Mode

 Return to chapter overview

Setting the user interface mode - Wizards or Dialogs?

For some key tasks, there are two user interface modes controlling the way in which options are presented to you:

·Wizard mode instructionStep guides you through the tasks in a linear fashion

·Dialog mode instructionStep all options are contained in a single dialog

Experienced users will find this mode quicker to use.

To set the user interface mode:

menu Settings menu instructionStep User Interface Mode... instructionStep select the desired mode in the User Interface Chooser dialog:

The user interface mode affects the following tasks:

· Attaching to an application (Injection)

· Launching an application

· Wait for application to start


UX Theme

Navigation: The User Interface >

UX Theme

 Return to chapter overview

The user interface provides three UX themes.

·Modern. The look and feel of current Software Verify tools.

·Classic. The look and feel of previous Software Verify tools.

·High Contrast. A higher contrast version of the Modern theme.

Setting the UX theme

To set the UX theme

menu Settings menu instructionStep UX Theme... instructionStep shows the UX Theme chooser dialog

Changing the UX theme will update some of the colours that you can modify with the colour settings dialog.


Settings

Navigation: The User Interface >

Settings

 Return to chapter overview

Thread Validator allows extensive control over which data is collected and how that data is displayed. Additional options control the way the application behaves.

These settings can generally be considered as being either Global settings or Local settings.

Global and local settings

Global settings affect all data collected and its display throughout Thread Validator.

Global settings are changed via the Settings Dialog and the following pages describe each available group of settings.

Local settings apply to controls and data displayed in each of the main display windows.

Local settings are found at the top of each relevant tab.

Other settings

There are a few more settings not included in the global settings dialog such as:

· User interface mode

· Session settings

· User permissions warnings


Global Settings

Navigation: The User Interface > Settings >

Global Settings

 Return to chapter overview

The Data Collection Settings dialog allows you to control all the global settings in Thread Validator that affect the way data is collected and displayed. There are also local display options on most of the main tabs.

note This section has a warning about use of the Reset button.

Opening the settings dialog

To view the settings dialog, choose Settings menu instructionStep Edit Settings...

Or use the option on the Session Toolbar:

Using the settings dialog

The dialog has a scrolled list on the left hand side, grouping the topics. When a topic is clicked, its related controls are displayed on the right hand side.

The default display of the dialog is shown below with the first topic selected.

After selecting a topic, you can also use the cursor up and down arrow keys to change the selected item.

Entering a character on the keyboard cycles though topics starting with that letter.

note Too many settings? It may seem that there is an overwhelming number of settings to worry about. Don't panic! The good news is that for new users, very few (if any) settings actually need to be changed to use the application in most cases, and even for experienced users, many groups of settings will not be needed. However, Thread Validator remains flexible for all our users in many different scenarios.

interactive Click on any item in the picture below to find out more about the settings for that group.

Restoring the default settings

The settings dialog has Reset All and Reset buttons near the bottom left of the dialog which you can use to reset all global settings back to their default values.

note This Reset All button resets nearly all global settings in Thread Validator, not just the settings visible on the current tab of the dialog.

note The Reset button resets just the settings visible on the current tab of the dialog.


Collect

Navigation: The User Interface > Settings > Global Settings > Data Collection >

Collect

 Return to chapter overview

The Collect tab allows you to specify the types of data that will be collected for display by Thread Validator.

Critical sections and Wait Monitoring

The first few tabs on the main window display information about critical sections and wait events.

Data for these tabs is collected by default, but collection can be turned off using the appropriate option below.

·Collect data for All Locks summary instructionStep collect data for the Summary and Locks Summary tab

·Collect data for overall Locks Per Thread summary instructionStep collect data for the Locks Per Thread tab

·Collect data for current Active Locks summary instructionStep collect data for the Active Locks (per thread) tab

note Even with all the options switched off you may still see thread 'header' rows, but no lock information under each one.

Instrumentation logging

The logging of DLLs, source files, classes, methods and functions that are not instrumented can help you understand the reason why part of your code isn't getting the coverage information you expect.

Once enabled, and a session has started, you can view a list of items that have not been instrumented via the Tools menu.

·Enable instrumentation logging instructionStep check to enable logging once the next session starts

Reset All - Resets all global settings, not just those on the current page.

Reset - Resets the settings on the current page.


Lock Callstacks

Navigation: The User Interface > Settings > Global Settings > Data Collection >

Lock Callstacks

 Return to chapter overview

The Lock Callstacks tab allows you to specify the types of data that will be collected for display by Thread Validator.

Lock Callstacks

The summary and overview information gathered with the Collect settings is very useful and has a relatively low impact upon the performance of the target application.

In some circumstances the information collected is enough to diagnose various threading problems, but other times you'll need more data.

Many threading problems are much easier to diagnose if a callstack is also associated with the data. Callstacks allow source code inspection and a greater level of understanding of the exact nature of the problem.

Thread Validator can store the most recent callstack or all callstacks associated with critical sections and wait events, contentions and recursions.

Information is stored on a per thread basis. If for example, a deadlock occurs, you can see which critical section was locked or waiting, and where this happened.

·Collect callstacks for critical sections and waits instructionStep collect the most recent callstacks for each of the checked items below, or not at all.

note Collecting callstacks can cause significant drops in performance depending on the nature of the target application.

·Keep all callstacks for...

·critical sections and waits instructionStep keep all callstacks per critical section so that analysis of the various callers can be performed

·contended locks instructionStep collect all lock contention callstacks

·recursing locks instructionStep collect all lock recursion callstacks

note Keeping all callstacks causes an even larger performance drop and increase in memory usage. It's recommended that all these option are only checked if you have a need for the information about all callstacks.

Reset All - Resets all global settings, not just those on the current page.

Reset - Resets the settings on the current page.


Detect

Navigation: The User Interface > Settings > Global Settings > Data Collection >

Detect

 Return to chapter overview

The Detect tab allows you to specify how the automatic detection of errors is handled.

Automatic detection of error conditions

Thread Validator regularly scans for various error conditions using the same data collected by the options on the Collect tab.

At the same time, thread status information from the operating system is collected to update symbolic and callstack information for use by the user interface.

·Deadlocks instructionStep automatically detect deadlocks

If your application has many threads, disable this option to prevent Thread Validator from using too much processor time.

When disabled, the Query menu option Deadlock Detection is enabled.

·Potential deadlocks instructionStep automatically detect potential deadlocks

If your application has many threads, disable this option to prevent Thread Validator from using too much processor time.

When disabled, the Query menu option Potential Deadlock Detection is also disabled (unlike Deadlocks above).

·Out of order critical sections instructionStep automatically detect out-of-order critical sections

·Other locking errors instructionStep automatically detect various other locking errors

Detection Intervals

Deadlock detection and thread status happens at regular intervals:

·Deadlock detect interval instructionStep the interval at which the automatic error detection will take place

Deadlock detection can be set for intervals of 1 to 60 seconds - or Never

·Thread status interval instructionStep the interval at which the status data collection will take place

Thread status can be determined at intervals of 1 to 60 seconds

note Automatic detection of these conditions may cause your application to run slightly slower.

Reset All - Resets all global settings, not just those on the current page.

Reset - Resets the settings on the current page.


Callstack

Navigation: The User Interface > Settings > Global Settings > Data Collection >

Callstack

 Return to chapter overview

Show/Hide Hidden Text

The Callstack tab allows you to specify how the callstack is collected, and how information about the callstack is displayed.

Callstack Monitoring

When Thread Validator stub collects callstacks for each hooked function, the stack traces can be very long.

Collecting longer stack traces means:

·collecting stack traces takes longer

·converting all the addresses in the stack trace to symbol names takes more time

·the target program runs slower

·more memory is consumed in the Thread Validator user interface

For this reason, you're able to specify whether you want complete or partial stack traces.

·Collect complete call stack instructionStep check for complete traces, uncheck to collect partial traces

Specify the exact depth you wish to capture with the Call stack depth option

Callstack Display

Data items recorded by Thread Validator can be displayed with parameter names as well as being automatically expanded.

·Show parameter names instructionStep check to show parameter names shown with the function name

·Expand call stack when trace expanded instructionStep check to automatically expand the entire callstack when examining a data item

Advanced Callstack

As the title suggests, these callstack options are advanced and not usually necessary to change unless you are experiencing incomplete stack traces.

Thread Validator collects callstacks by walking along the stack frames. When no more stack frames can be walked, Thread Validator uses DbgHelp StackWalk() to attempt to walk any remaining stack frames.

StackWalk() is much slower than Thread Validator's direct stack walking. Calling StackWalk() to attempt to walk any remaining stack frames may not result in any extra stack frames being walked, but will result in slower execution of your application.

On the other hand, not using StackWalk() may result in shorter callstacks being collected.

·When walking callstack, do not use StackWalk... instructionStep prevent Thread Validator using StackWalk()

You may have problems collecting some callstacks in release mode programs, and in some special cases in debug programs depending on your program.

In addition to the optimisation described above, Thread Validator provides three different methods of collecting callstacks for functions. These methods are in the Advanced section described below and are provided to allow you to tailor callstack collection to the task at hand.

As the title below suggests, the remaining options are for advanced use! An example might be if you find your program has a problem that can be identified, but for which the callstack cannot be collected properly.

Advanced callstack settings

·Callstack walk helper size instructionStep Specify the size of the cache used to optimize callstack walking

Thread Validator uses a cache to help it optimize the callstack walking process. The cache is used to avoid calling operating system functions to walk the callstack when the result has been previously calculated.

For applications generating many unique callstacks, this size may need to be increased.

All sizes are prime numbers, and the default size is 100003 which is large enough for most applications. If in doubt leave it at the default value of 100003

Callstack walking

Thread Validator provides three different methods of collecting callstacks for functions which you can choose to tailor callstack collection to the task at hand.

1) The standard Microsoft® DbgHelp StackWalk() function

This function is optimised for walking standard Intel i386 stack frames where the EBP register is pushed on to the stack at function entry and popped from the stack when the function exits. This is the typical stack frame for a program built in debug mode.

The DbgHelp StackWalk() function is also capable of reading frame pointer omission data (FPO_DATA) included in a PE file. FPO_DATA is included in optimised binaries that do not use the EBP register to identify the stack frame - this is typical of a program built in release mode.

doc-collapse-icon Missing data in your callstack? Although Microsoft have provided a very capable stack walking function, there are occasions when the StackWalk() function cannot continue walking along the stack, from one frame pointer to the next. When this happens collected stack traces often appear to have data missing, or look "too short". You may have noticed this when debugging release mode programs in Visual Studio®.

2) Alternative (custom) StackWalk() function

This proprietary method, although slower than Microsoft's stack walker, does not use stack frames to walk the stack, and so enables the stack walker to walk callstacks that DbgHelp StackWalk() cannot.

doc-collapse-icon What's different about this method? A detailed technical discussion of how this algorithm works is not appropriate here, but suffice to say that all addresses found on the stack are checked for validity, both for code sections, likelihood of CALL instruction taking place, target and source addresses of CALL instructions, removal of duplicate data, and so forth. The resulting callstacks often contain some bogus stack entries, which are obvious to the end user, but not possible to detect by the callstack verification algorithm (this is often due to CALL instructions relying on indirect indexes held in registers which have been changed by the time the stack walker has walked to this point in the callstack - such entries must be taken at face value because they may be valid).

3) Hybrid of the two

The third stack walk type is a hybrid of the other two.

The first method is used to collect all callstacks. Any callstacks that are too short (defined by a callstack length threshold) then have the callstack collected by the second method.

This provides the speed and power of the standard Microsoft stack walker, with the flexibility to collect callstacks that would otherwise be uncollectible when DbgHelp StackWalk() fails to collect the callstack.

The Advanced Stack Walk dialog shown below is accessed via the Advanced... button and is used to choose one of the three callstack collection options above:

·DbgHelp StackWalk instructionStep use the DbgHelp.dll StackWalk() function to walk all callstacks

You may have problems collecting some callstacks in release mode programs, and in some special cases in debug programs depending on your program.

·Alternative StackWalk instructionStep use the alternative stack walking function to walk all callstacks

All callstacks will be collected in both debug and release mode programs, but you may find that some callstacks contain incorrect entries.

·Hybrid StackWalk instructionStep use the hybrid method outline above

When the alternative stack walk is used you may find that some callstacks contain incorrect entries.

To specify when to use the alternative stack walking function, set a callstack depth.

Any standard callstacks that are shorter than the depth specified, will be collected using the alternative stack walking function.

seeAlso See also - recommended usage below

Alternative stack walk method - fast or slow?

·When using alternative stack walk, use fast option instructionStep uses a faster address verification scheme (recommended) or a slower one

Do extra consistency checks instructionStep When using the fast option, consistency checks can optionally be performed (recommended) to reduce the amount of incorrect addresses included in the callstack.

Alternative stack walk method - range of relative addresses

When the alternative stack walk is used, relative address CALL instructions have their target address computed to test if the target address is within a threshold of the previous callstack address.

This provides a form of source address to target address integrity to prevent invalid addresses be placed in the callstack.

·Relative CALL instruction byte range instructionStep set the threshold which the target address must be within, to fine tune the stack walk

A larger threshold reduces the accuracy of the stack walk by allowing too many invalid addresses into the stack.

A smaller threshold reduces the accuracy of the stack walk by rejecting valid addresses from being placed in the callstack.

The default is a reasonably large 8192 bytes.

Alternative stack walk method - caveats

When the alternative stack walk is used you may notice some unusual data on the display:

·<UNKNOWN> symbols in the middle of call stacks

This happens rarely, because the address is not valid but for some reason was not rejected by the alternative stack walk.

·Symbols in the middle of callstacks that you know cannot be correct

This may happen because the address is valid, but not for this position in the callstack, and the address passed the alternative stack walk address verification tests - this address was most probably the target of an indirect CALL instruction, and as such, could not be verified.

·Callstacks for data that make no sense

This again is rare, but occurs due to Thread Validator monitoring its own behaviour (which can happen in a few limited circumstances). These callstacks are filtered in both stack walk methods, correctly in the standard one, but not perfectly in the alternative method!

Recommend usage

We recommend that in all situations the stack walking method used is either DbgHelp StackWalk or Hybrid StackWalk.

Only if you find your program has a problem that can be identified, but for which the callstack cannot be collected, do we recommend using Hybrid StackWalk or Alternative StackWalk as appropriate.

Reset

The Advanced Stack Walk dialog has a button labeled Reset at the bottom left of the dialog. This resets only the settings on this dialog back to their default values.

Reset All - Resets all global settings, not just those on the current page.

Reset - Resets the settings on the current page.


Startup Data

Navigation: The User Interface > Settings > Global Settings > Data Collection >

Startup Data

 Return to chapter overview

The Startup Data tab controls how to manage Critical Sections in DLLs loaded prior to Thread Validator's stub being loaded.

DLLs that are already loaded

When Thread Validator attaches to an already running process or is injected at the start of an application's execution, other DLLs have already been loaded into the target application's address space.

Any of those DLLs that use critical sections will have initialized and may even have entered those critical sections.

Thread Validator monitors the initialization and destruction of critical sections and depends on knowing about their existence prior to usage in order to detect many of its thread errors.

If Thread Validator doesn't see the initialization but then does see the critical section being used, a possible error condition will be raised.

To prevent this you can acquire information about all critical sections when Thread Validator starts the target application (or attaches to it). For consistency, information about all threads in the application can be obtained at the same time.

note Typically, when launching the target application in the normal way, you don't need to acquire all critical sections at startup. However, if attaching to an already running application (using inject or wait for application), you should acquire all critical sections at startup.

Determining threads and critical sections existing at startup

Two options allow Thread Validator to determine all the threads or critical sections that exist when Thread Validator attaches to the target application:

·Acquire all threads at startup instructionStep check to determine all the threads that exist

·Acquire all critical sections at startup instructionStep check to determine all the critical sections that exist

Critical sections inside DllMain

If your DLLs initialize or destroy critical sections inside DllMain, there are two options for tracking these critical sections.

One method deals with Microsoft DLLs and the other with non-Microsoft DLLs.

·Acquire critical sections inside DllMain... instructionStep check to determine all the critical sections initialised when a DLL is loaded using LoadLibrary

(Microsoft DLLs) instructionStep when a Microsoft DLL is loaded

(non Microsoft DLLs) instructionStep when a non-Microsoft DLL is loaded

Reset All - Resets all global settings, not just those on the current page.

Reset - Resets the settings on the current page.


Hook Insertion

Navigation: The User Interface > Settings > Global Settings > Data Collection >

Hook Insertion

 Return to chapter overview

The Hook Insertion tab allows you to control which functions are monitored by Thread Validator.

Change hooks before a session

Before a session starts you can set which data items are hooked.

Hooking changes made mid session will come into effect on the next session, but you can enable or disable the data from installed hooks at any time using the hooks tab.

Hook Insertion

Two check boxes control which groups of hooks are inserted into your application.

·Synchronization functions instructionStep inserts hooks for tracking synchronization objects into the target program

If enabled, the default behaviour is that critical section enter and leave events will be tracked. Additional functions can then be specified below.

·Functions working with waitable handles instructionStep hooks (below) for tracking functions that create, manage and destroy waitable handles will be inserted into the target program

A few additional functions (Sleep, and critical section related functions) are also monitored.

Specify which groups of functions should have data collected from them using the individual check boxes. (See note about memory below).

Any collected data can be viewed on the Active Objects and Analysis tabs.

Groups of items | Functions that...
·Critical Section | initialize, modify and destroy
·Event | create, open and destroy
·Mutex | create, open and destroy
·Semaphore | create, open and destroy
·Register Wait | register and unregister
·Waitable Timer | create, open and destroy
·Job Object | create, open and destroy
·Process | create, open and destroy
·Thread | create, open and destroy
·File | create, open and destroy files (of any type)
·Duplicate Handle | miscellaneous handle functions
·Change Notification | create, open and destroy file change notifications
·Timer Queue | create, open and destroy timer queues and timer queue timers

Other options:

·Sleep | Sleep and SleepEx For many applications, enabling Sleep will generate a lot of data, as various threads sleep from time to time.
·Collect NULL and Invalid Handles | information about failed handle creation When collecting waitable handles, you may also want to collect information about failed handle creation using this option.

·Select/Deselect All instructionStep switches all the above functions allocating waitable handles - i.e. not Sleep and invalid handles

note It's recommended that options in this section are only enabled if you need to monitor the data. If you subsequently find that memory consumption is very high, consider changing the settings here, or on the Historical Data tab.

Reset All - Resets all global settings, not just those on the current page.

Reset - Resets the settings on the current page.


Hook Trace

Navigation: The User Interface > Settings > Global Settings > Data Collection >

Hook Trace

 Return to chapter overview

The Hook Trace tab allows you to control which debug or trace functions are monitored by Thread Validator.

Trace Message Monitoring

Thread Validator can collect the output from various debug and trace functions or macros, including:

·AfxTrace()

·TRACE()

·OutputDebugString()

The TRACE() macros ultimately get routed via OutputDebugString(), so to avoid duplicate output Thread Validator doesn't allow both to be collected at the same time.

Collection is enabled via the main hook option, with output available on the Analysis tab.

·Hook trace messages instructionStep collect TRACE() or OutputDebugString() messages

Once hooking is enabled (not the default), choose either:

·OutputDebugString instructionStep collect OutputDebugString() messages

Collect OutputDebugString call stack instructionStep optionally also collect the callstack for each message

·Trace (TRACE(), AfxTrace()...) instructionStep collect TRACE() messages

Collect TRACE call stack instructionStep optionally also collect the callstack for each message

Thread Stall Detection

Thread Validator can detect stalled threads by monitoring the time a thread's context switch count is unchanged.

When the time for which a thread's context switch count is unchanged exceeds a threshold, the thread is considered stalled.

In reality, there may be many reasons why a thread may be (or appear to be) stalled. It may be due to:

·a time consuming wait operation on a handle object

·a wait on an owned critical section

·a call to Sleep() or SleepEx()

·the thread having been suspended

·the thread being in a deadlock

Once a thread has been marked as stalled, then if the context switch count starts to change the thread will be marked as non-stalled.

Stalled threads are displayed using a different colour col-stalled, as defined on the Lock Colours settings dialog.

·Detect stalled threads instructionStep enable thread stall detection

·Time threshold (mS) instructionStep enter the threshold time (in milliseconds)

The default is 10 seconds (10000ms)

Reset All - Resets all global settings, not just those on the current page.

Reset - Resets the settings on the current page.


Historical Data

Navigation: The User Interface > Settings > Global Settings > Data Collection >

Historical Data

 Return to chapter overview

The Historical Data tab allows you to control how many of the most recent stack traces are kept by Thread Validator.

Historical Data

There may be occasions when you want control over when to keep or discard information on older data. This may depend on:

·your computer's RAM capacity

·virtual memory storage

·the task you are trying to complete

·the target program being inspected

Two options allow you to Discard stack traces for...

· ...destroyed/closed synchronization objects and handles instructionStep discard information about these freed handles

When selected you can specify How many freed traces to keep. The default is 10,000.

Data is discarded on a first deallocated, first discarded basis, so most recent deallocations are always kept.

· ...TRACE messages and informational traces instructionStep discard older information about these items, including Sleep()

When selected you can specify How many traces to keep. The default is 10,000.

note Note that the less information kept about deallocated data, the smaller the memory requirements placed on your computer.

Reset All - Resets all global settings, not just those on the current page.

Reset - Resets the settings on the current page.


Hooks

Navigation: The User Interface > Settings > Global Settings > Data Collection >

Hooks

 Return to chapter overview

The Hooks tab allows you to enable and disable every hook that Thread Validator uses (except for buffer checking hooks).

All the hooks can be enabled and disabled as a whole.

Hook Groups

The picture above shows the hook groups expanded to show that all their functions are enabled (ticked).

Tick or untick any synchronization hook to enable or disable its status. Use the top level items (Critical Sections, Events, etc) to set all the items in the corresponding group.

Enabling or disabling these hooks after the session has started doesn't modify behaviour during the current session.

· Enable All instructionStep enables all the hooks in all the groups

· Disable All instructionStep disables all the hooks in all groups

For a full list of the hooks, see the hook reference.

· Use these hooks instructionStep toggle the use of all selected hooks without losing the checked states

Useful if you've set up a mixture of hook states and want to temporarily disable them for a session.

Reset All - Resets all global settings, not just those on the current page.

Reset - Resets the settings on the current page.


Thread Coverage

Navigation: The User Interface > Settings > Global Settings > Data Collection >

Thread Coverage

 Return to chapter overview

The Thread Coverage tab allows you to control collection of coverage statistics for synchronization functions.

What is thread coverage?

Calculating thread coverage involves parsing your source code to determine all thread synchronization locations and then matching that data with information from the callstacks of each allocation in your session.

Some of these activities are time consuming, so the default is not to collect thread coverage statistics, but to let you optionally control the behaviour as below.

Controlling thread coverage data collection

·Collect thread coverage data instructionStep enables the collection of thread coverage data

The Coverage tab (example shown below) shows the thread coverage statistics for each file that contains thread synchronization statements. This allows you to check how well you're testing your thread synchronization code.

note See the section at the end of this page about tracking waitable handles.

When the collection of thread coverage data is enabled, the are some additional options to tune the performance.

·Count visits to synchronization locations once instructionStep only count line visits once per line when this is selected (default)

Normally each line is counted just once (faster).

Although this option means they can be counted for all visits to each line, this will be noticeably slower for large applications.

·Cache thread coverage data instructionStep enable caching of coverage statement information (default)

Calculating the coverage statements for each file can be time consuming, especially for large applications as it requires parsing the source code each time the application is run to determine where the thread synchronization locations are.

Caching the coverage statement information improves this by only recalculating it when the source code is modified.

·Include 3rd party files in thread coverage statistics instructionStep include 3rd party files as specified in File Locations

For most activities you'll want to keep this option deselected.

·Include files with no thread coverage statements in statistics instructionStep includes relevant source code files

Some source code files do not perform any thread synchronization operations. As such these files may be viewed as unwanted data on the coverage report, so the default is not to include these.

·Include files that cannot be read in statistics instructionStep includes source code filenames referencing files that do not exist on your computer

Typically these are third party files in pre-built DLLs. By default they are not included in the statistics.

·Clear Coverage Cache... instructionStep delete any existing thread coverage cache files stored on your computer

Thread coverage filters

Thread coverage calculation is quite likely to include some third party source files or header files that are out of your control, e.g. from STL, third party files in pre-built DLLs, etc.

There may also be some files that create waitable handles but which you know will never be used in a thread synchronization operation.

If you don't want results to include such files, you can specify a number of filters to exclude them.

Coverage filters need to be set before the session starts in order to affect results.

·Configure Filters... instructionStep shows the Thread Coverage Filters dialog that lets you manage the list of filters...

This dialog is the same one accessed via the local Filters button on the Coverage tab.

The Filters dialog has some basic controls for managing the filters:

·Add... instructionStep adds a new filter, as in the example above

·Edit... or double click an item in the list instructionStep opens the Thread Coverage Filter dialog to modify the enabled state, type or target of the selected filter item

You can also enable/disable an item via the yellow checkbox on each item in the list.

·Remove instructionStep deletes all selected filters in the list, or press

·Remove All instructionStep clears the list of filters

·Enable All instructionStep sets all filters active

·Disable All instructionStep sets all filters inactive (but does not remove them from the list)

Each filter can only be one of the three types: filename, directory or DLL. However, you can mix and match multiple filters of any type.

For example, to add a new filter:

·Configure Filters... instructionStep Add... instructionStep choose a filter type filename, directory or DLL instructionStep Browse... (or enter a path directly) instructionStep choose a relevant item to add instructionStep OK instructionStep OK

To help recognise types of filters in the list, each item is prefixed by some bracketed flags as follows

[File] - file

[Dir] - directory

[DLL] - DLL

Thread coverage auto merge

Different runs of your application may execute different parts of your application, in which case you might want to merge the results of one run with the results of another.

·Configure Auto Merge... instructionStep shows the Auto Merge dialog that lets you configure merging of thread coverage results

The automatic merging works by merging the results of each individual thread coverage session into a central session.

The central session is stored on disk in a file you specify, or in a file using the name of the session, e.g. TestThis.exe would get saved in TestThis.tvm in the same directory as Thread Validator resides.

·Enable auto-merging of thread coverage statistics instructionStep switches the merging feature on (default is off)

Depending on how many applications you are performing thread coverage on, you may want your thread coverage data to go to one central location or to a different location for each application under test.

·Name of auto-merge session is based on the name of the application under test instructionStep saves the central session in a file named according to the application under test in this session (the default)

By default, the auto-merge session will be stored in the same directory as Thread Validator, but you can change this:

Directory for auto-merge session instructionStep saves the auto-merge session in the specified directory

For example, if you run the application nativeExample.exe, and specify a central session directory of e:\threadCoverageResults, the central session will be saved in a file named e:\threadCoverageResults\nativeExample.tvm.

·Name of central session is specified instructionStep save the auto-merge session in a filename and path of your choice (enter or Browse... to a file)

Auto-merge session reset

The auto-merge results can be automatically cleared by certain triggers, or not cleared at all.

When performing thread coverage analysis sometimes you will uncover a bug in your software and need to modify the software, and/or run different executables. When this happens, line numbers and/or files often change, and you usually wouldn't want to merge thread coverage data from the modified software with existing coverage data.

The triggers for clearing the merged session results are:

·When any source file is modified (the default)

·When the application under test changes

·No clearing of merged session results occurs under any circumstance

If you don't want an automatic trigger, there's also a manual trigger:

·Clear Auto Merge Results instructionStep click to clear auto-merged results at any time of your choosing

Not tracking waitable handles?

If you choose to collect thread coverage data, and close the settings dialog (or switch to another settings page), you may get the following offer to improve coverage by tracking waitable handles.

·Yes instructionStep switches on the Hook Insertion setting for tracking functions working with waitable handles

If you haven't actually enabled any of the waitable handles, a warning will appear:

OK instructionStep displays the Hook Insertion settings to choose which waitable handles you want to track

Pick which waitable handle functions you're intertested in for coverage and click OK

Alternatively if you don't want to get coverage after all, Cancel and then uncheck Collect thread coverage data to prevent these warnings.

Reset All - Resets all global settings, not just those on the current page.

Reset - Resets the settings on the current page.


Applications to Monitor

Navigation: The User Interface > Settings > Global Settings > Data Collection >

Applications to Monitor

 Return to chapter overview

If your target program launches other child applications then the Applications to Monitor page lets you choose which ones to monitor.

Monitoring child applications

You may have a case where the program you need to start is not the one you are interested in.

Your program may launch child applications and it may be one of those that you want to monitor with Thread Validator.

An example might be for unit testing where a test program spawns one or more child applications, or it might launch the same application multiple times.

The applications to monitor

The main list of Applications to monitor shows programs you may want to launch and the child applications they subsequently start - i.e. the you may be interested in monitoring.

Once a definition has been added, you can then use the Application to Monitor setting on the Launch Dialog or wizard to choose which of these child applications you actually want to monitor in a given session.

Managing the applications to monitor

The list contains a set of definitions - each one being for a different launch program.

For each launch program you can set the child applications you might want to monitor later.

An application is defined by its type (native and .Net, or .Net Core), the application executable name, and for .Net Core applications an additional application DLL that is used to identify the application.

·Add instructionStep add a new module definition using the Application to Monitor dialog below

·Edit instructionStep modify a selected definition in the list, using the Application to Monitor dialog again

·Remove instructionStep removes any selected definitions in the list

·Remove All instructionStep clears the list

·Set Defaults instructionStep reset the list of known applications to those as configured with a new install of Thread Validator

The defaults are currently setup for Microsoft's Visual Test software vstest.console.exe.

The Application to Monitor dialog

The Application to Monitor dialog lets you define or edit a launch program and it's child applications.

The values you specify here are the ones used on the launch dialog and launch wizard to customize which application actually gets monitored.

·Application to Launch instructionStep Edit... to select the initial starting application that will be launching the applications you want to monitor

Any executable names found in the selected program will automatically be displayed in the list of Applications to Monitor.

If you don't wish to use these automatic names you can Remove them.

·Add instructionStep add an additional application that you know will be started by the launch program

Child applications that you add are used without the path.

Excluding the path gives more scope for matching launched application names if they are launched with a different path.

·Remove instructionStep removes any selected applications in the list

·Remove All instructionStep clears the list

·Default application to monitor instructionStep choose the appropriate item to be the default item

The default application will be selected on the launch dialog (or wizard) whenever the start program is specified as the one at the top of this dialog.

The Application and DLL dialog

The Application and DLL dialog lets you define or edit a launch program and a launch DLL.

·Application type instructionStep choose the type of application

oNative and .Net

o.Net Core (Framework Dependent)

o.Net Core (Self Contained)

·Application to monitor instructionStep edit or Browse... the application EXE to monitor.

This can be an executable name or the full path to the executable. For example test.exe or c:\unitTests\test.exe.

For native applications this is the application executable.

For .Net Framework applications this is the application executable.

For .Net Core Framework-dependent applications this is most likely going to be c:\program files\dotnet\dotnet.exe.

For .Net Core Self-contained applications this is the application executable.

·DLL to monitor instructionStep edit or Browse... the application DLL to monitor. This field is only needed for .Net Core applications.

This can be an executable name or the full path to the executable. For example test.dll or c:\unitTests\test.dll.

For native applications this is not used.

For .Net Framework applications this is not used.

For .Net Core Framework-dependent applications this is the application dll. (the name of the dll that you would pass to dotnet.exe on the command line).

For .Net Core Self-contained applications this is the dll that has the same name as the application executable. (for theApp.exe, the dll name is theApp.dll).

Example Dialogs

Native

.Net

.Net Core (Framework-dependent)

.Net Core (Self-contained)

Reset All - Resets all global settings, not just those on the current page.

Reset - Resets the settings on the current page.


Display Behaviour

Navigation: The User Interface > Settings > Global Settings > Display >

Display Behaviour

 Return to chapter overview

The Display Behaviour tab allows you control how which displays are shown when a program starts executing and when a program finishes executing.

The default options are shown below:

Thread Validator can change the current display to any of the following displays.

·Summary instructionStep the main display

·Locks : All Locks instructionStep all locks in the application

·Locks : Locks per Thread instructionStep locks displayed per thread that uses them

·Locks : Active Locks instructionStep locks that are currently locked

·Wait Chains instructionStep locks and waits and their relations to each other

·Threads : Locks instructionStep thread history, plus locks for a given time segment

·Threads : Lock Order instructionStep thread history, plus the order locks were acquired for a given time segment

·Analysis : Query instructionStep perform queries on the locking data

·Analysis : Coverage instructionStep code coverage for locking primitives

·Analysis : Active Objects instructionStep locking primitives and handles and the callstack for the creation of the handle

·Analysis : Object Handles instructionStep handles open in the target application

·Diagnostic : Diagnostic instructionStep diagnostic information

·Diagnostic : Stdout instructionStep text collected from stdout

·Diagnostic : Environment Variables instructionStep environment variables from the program under test

·Diagnostic : Child Processes instructionStep processes launched by the program under test

Program Starts Executing Behaviour

When Thread Validator starts monitoring the behaviour of an application the current display can automatically be switched to any of the displays listed above.

There is also the option not to change the display.

Program Finished Executing Behaviour

When Thread Validator has finished processing all the information from the target application the current display can automatically be switched to any of the displays listed above.

There is also the option not to change the display.

The type of display that may interesting for collected data depends on the type of program that was executed. Native, .Net or Mixed mode. To accommodate this we provide one setting for each of the three program types.

Reset All - Resets all global settings, not just those on the current page.

Reset - Resets the settings on the current page.


General Colours

Navigation: The User Interface > Settings > Global Settings > Display >

General Colours

 Return to chapter overview

The General Colours tab allows you to specify the colours that will be used to display source code and non-error data.

The default colours are shown below:

The colours are used for highlighting the source code on most of the main tabs, as well as in some of the statistics.

Changing display colours

For each colour you can choose a predefined colour or make your own:

·Use the drop-down list colour-combo instructionStep pick one of 16 predefined colours below

·Click the colour-dotdotdot-button button instructionStep edit the colour using the standard colour dialog:

Highlighting data that won't be shown on the next run

You can use some settings, such as the Thread Coverage settings to exclude files or directories of source code from being analyzed or displayed.

If you've already got coverage data being displayed, and you filter out some of that data, it is not removed from statistics in the current session.

However, the data that would be excluded is highlighted using the Selected colour (light grey in the above example).

Reset All - Resets all global settings, not just those on the current page.

Reset - Resets the settings on the current page.


Lock Colours

Navigation: The User Interface > Settings > Global Settings > Display >

Lock Colours

 Return to chapter overview

The Lock Colours tab allows you to specify the colours that will be used to represent each type of data item collected by Thread Validator.

The default colours are shown below:

Changing lock colours

For each colour you can choose a predefined colour or make your own:

·Use the drop-down list colour-combo instructionStep pick one of 16 predefined colours below

·Click the colour-dotdotdot-button button instructionStep edit the colour using the standard colour dialog:

Reset All - Resets all global settings, not just those on the current page.

Reset - Resets the settings on the current page.


Data Display

Navigation: The User Interface > Settings > Global Settings > Display >

Data Display

 Return to chapter overview

The Data Display page allows you to specify how numeric data is formatted in the various displays.

Numerical data format

Numeric data on the displays can contain some pretty big values, up to 2^64-1 if needed!

Long values are hard to read without grouping digits. To improve readability Thread Validator can delimit each group of three digits, so 1234567 becomes 1,234,567 for example.

·No separators / Use separators instructionStep Choose whether to group digits

The format used to delimit digit groups is set to User Default, which uses your computer's current locale, but you can change the format to suit another language if you wish.

·Language instructionStep Format numbers according to the default locale, or choose another language

Numerical data alignment

Numeric data on the displays can be aligned left or right, with right aligned numbers being more easily compared.

·Left alignment / Right alignment instructionStep Choose preferred alignment

Reset All - Resets all global settings, not just those on the current page.

Reset - Resets the settings on the current page.


Hooked DLLs

Navigation: The User Interface > Settings > Global Settings > Filters >

Hooked DLLs

 Return to chapter overview

Show/Hide Hidden Text

The Hooked DLLs tab allows you to specify which DLLs should be hooked or not.

The default is simply to hook everything.

interactive Read on, or click on a setting in the picture below to find out more.

Which DLLs to hook - the hooking rule

By default, Thread Validator will try to hook all DLLs and .EXEs used by your application, but you can choose to list only those which should be included or excluded:

·Hook all DLLs instructionStep hook everything - ignoring the settings in the list

·Hook the enabled DLLs in the list instructionStep hook only the ticked modules listed

·Do not hook the enabled DLLs in the list instructionStep ignore all the ticked modules in the list, and hook everything else

Populating the Process Modules list

The Process Modules list should specify the following items to be included or excluded from hooking in the target application

·DLLs

·.EXEs

·folders containing DLLs and .EXEs

Initially the list is empty as the default option is to hook all DLLs and ignore the list. You can add modules to the list by:

·automatically adding modules on which your application is dependent

·manually adding modules or folders

·editing modules or folders already in the list

Automatic module addition

You can automatically populate the list with all the dependent modules for your application:

·Choose Exe... instructionStep navigate to your application and click Open instructionStep all the process modules appear in the list

Manual module addition

You can also manually add one or more modules or a folder to the list.

·Add Module instructionStep navigate to the DLL or EXE and click Open instructionStep all the selected items are added

·Add Folder instructionStep navigate to the folder and click OK instructionStep the folder is added to the list

Manual addition might be useful for example if you use LoadLibrary() to load a DLL rather than linking it, as this would not be picked up automatically by the Choose Exe... method.

By default, all the modules are ticked in the yellow checkboxes.

Any DLLs in the list override the DLL Hook Insertion settings on the Hook Insertion tab.

note Note that ticked modules or folders are either included or excluded depending on the hooking rule above.

Altering existing module names

Although you can't add blank entries to the list and edit them, you can edit existing items in the list by double clicking on an entry:

·enter only the module name, not the path

·you can use wild-cards like MFC*.dll, but only for DLLs, not folders

Managing the process modules list

The usual controls apply for removing or changing the enabled state of items in the list:

·Remove instructionStep removes selected items in the list

·Remove All instructionStep removes all items, clearing the list

·Enable All instructionStep ticks all items in the list for applying to the hooking rule

·Disable All instructionStep unticks all items in the list, meaning they won't apply to the hooking rule

Alternatively, press [image] to delete selected items, and [image] + [image] to select all items in the list first.

Exporting and importing

Since the list of hooked DLLs (and the rule being applied) can be quite complicated to set up and optimise, you can export the settings to a file and import them again later. This is useful when switching between different target applications.

·Export... instructionStep choose or enter a filename instructionStep Save instructionStep outputs the hooking rule and the list of modules to the file

·Import... instructionStep navigate to an existing *.tvx file instructionStep Open instructionStep loads the hooking rule and the list of modules

Optionally hooking delay loaded DLLs

·Don't hook delay loaded DLLs instructionStep prevents hooking of delay loaded DLLs. The default is to hook these.

doc-collapse-icon What is 'delay loading'?

Delay loading a DLL is when it is implicitly linked, but not actually loaded until your code references a symbol contained in the DLL.

Delay loading can speed up startup time, but unhandled exceptions may cause your program to terminate if the DLL can't be found when needed during the run time.

Launching new Applications

When specifying DLLs to hook, and launching different applications, it can be quite easy to forget to change the hooked DLLs for the new program. This might be the case when performing unit tests, for example.

Using the wrong list of hooked DLLs for a program will likely cause incorrect thread data results, so you can opt to be warned about the DLLs being hooked whenever the target application changes between sessions (using the dialog below).

The choices in the drop down list are only applicable when the application changes:

·Ask about DLLs to Hook settings if some DLLs defined

You'll only be asked about the settings if you defined some DLLs in the list and if the hooking rule is not set to Hook all DLLs.

·Always ask about DLLs to Hook settings

You'll always be asked about the settings - whatever the other settings are.

·Never ask about DLLs to Hook settings

The 'Launch Different Application' dialog

When being asked about the hooked DLL settings, you'll see the following dialog:

You can update the settings; ignore them and launch anyway, or just cancel the launch:

·Update Settings and Launch instructionStep edit the settings instructionStep click OK instructionStep the application will be launched

·Ignore Settings and Launch instructionStep the application will be launched without updating the settings

·Cancel instructionStep won't launch the application

To change when you are asked this question, just choose the appropriate option in the dialog.

Reset All - Resets all global settings, not just those on the current page.

Reset - Resets the settings on the current page.


Load Settings Pattern Match

Navigation: The User Interface > Settings > Global Settings > Filters >

Load Settings Pattern Match

 Return to chapter overview

The Load Settings Pattern Match tab allows you to configure loading of different settings depending on the executable being launched (or relaunched).

The grid shows one pattern match per line.

The buttons alongside allow you to Add, Edit and Remove patterns that you have created. You can also enable and disable them all.

·Add... instructionStep display the pattern match dialog to create a pattern to match.

·Edit... instructionStep display the pattern match dialog to edit the selected pattern.

·Remove... instructionStep delete the selected pattern.

·Remove All... instructionStep delete all selected patterns.

·Enable All... instructionStep enable all patterns.

·Disable All... instructionStep disable all patterns.

Pattern Match Dialog

The pattern match dialog allows you to create and edit pattern matches.

·Enable instructionStep enable or disable this pattern.

·Action instructionStep how to evaluate if this pattern is matched.

§Load settings for first executable... instructionStep the first executable that matches a pattern causes the settings to be loaded.

§Load settings for each executable... instructionStep each executable that matches a pattern causes the settings to be loaded provided it is not the same executable that previously loaded the settings.

§Load settings for every executable... instructionStep every executable that matches a pattern causes the settings to be loaded.

When a different pattern matches the first/each status is reset.

·Pattern instructionStep a text pattern, including the * wildcard, to match an executable path.

Examples:

*\examples\nativeExample\*
c:\tests\*
e:\dev\myProject\release\*.exe

·Settings instructionStep the full path to the settings you want to load if the action and pattern match an executable.

How does the pattern matching work?

It is probably easiest to demonstrate how pattern matching works with some examples.

Let's assume we have two patterns:

*\examples\nativeExample\* that will load e:\settingsExamples.tvs

*coverageValidator* that will load e:\settingsCV.tvs.

We'll cover each of the possible action criteria for a sequence of application launches, showing which settings are loaded and why.

·Load settings for first executable... instructionStep the first executable that matches a pattern causes the settings to be loaded.

Launched application | Settings loaded | Reason
e:\examples\nativeExample\release\nativeExample.exe | e:\settingsExamples.tvs | 1st application, new pattern
e:\examples\nativeExample\release\nativeExample.exe |  | repeat application, same pattern
e:\examples\nativeExample\debug\nativeExample.exe |  | 2nd application, same pattern
c:\program files (x86)\software verify\coverage validator x86\coverageValidator.exe | e:\settingsCV.tvs | 1st application, new pattern
e:\examples\nativeExample\release\nativeExample.exe | e:\settingsExamples.tvs | 1st application, new pattern

·Load settings for each executable... instructionStep each executable that matches a pattern causes the settings to be loaded provided it is not the same executable that previously loaded the settings.

Launched application | Settings loaded | Reason
e:\examples\nativeExample\release\nativeExample.exe | e:\settingsExamples.tvs | new application, new pattern
e:\examples\nativeExample\release\nativeExample.exe |  | repeat application, same pattern
e:\examples\nativeExample\debug\nativeExample.exe | e:\settingsExamples.tvs | new application, same pattern
c:\program files (x86)\software verify\coverage validator x86\coverageValidator.exe | e:\settingsCV.tvs | new application, new pattern
e:\examples\nativeExample\release\nativeExample.exe | e:\settingsExamples.tvs | new application, new pattern

·Load settings for every executable... instructionStep every executable that matches a pattern causes the settings to be loaded.

Launched application | Settings loaded | Reason
e:\examples\nativeExample\release\nativeExample.exe | e:\settingsExamples.tvs | Every application
e:\examples\nativeExample\release\nativeExample.exe | e:\settingsExamples.tvs | Every application
e:\examples\nativeExample\debug\nativeExample.exe | e:\settingsExamples.tvs | Every application
c:\program files (x86)\software verify\coverage validator x86\coverageValidator.exe | e:\settingsCV.tvs | Every application
e:\examples\nativeExample\release\nativeExample.exe | e:\settingsExamples.tvs | Every application

Warning

When a pattern is matched and the action criteria are satisfied the specified settings will be loaded.

A warning can be displayed at this point to remind you that the settings are being changed.

·Display warning dialog... instructionStep the warning dialog will be displayed when the pattern match criteria are met.

The warning dialog looks like this:

Reset All - Resets all global settings, not just those on the current page.

Reset - Resets the settings on the current page.


Source Browsing

Navigation: The User Interface > Settings > Global Settings > General >

Source Browsing

 Return to chapter overview

There a few areas in Thread Validator where you can view snippets of source code, such as in the Active Objects tab, Analysis tab or Find Function query results.

The Source Browsing tab allows you control how much source code is displayed and the indentation.

The default options are shown below:

Source browsing

When viewing sections of source code, you can choose to see the whole function or a few lines either side of the line of interest.

·Show entire function instructionStep shows the whole function source as below:

·Show lines instructionStep shows a given number of lines before and after the point of interest:

·Lines before trace instructionStep number of lines before, from 0 to 100

·Lines after trace instructionStep number of lines after, from 0 to 100

The default is to show 5 lines above and below, as in this example:

Source browsing - how much to show?

Showing the entire function is more likely to show the full context of the line of interest, but if you have particularly long functions it may become cumbersome to browse query data!

Because of the unpredictable lengths of showing entire functions, the entire function is not the default setting.

Showing a set number of lines reduces the amount of source displayed to something that is consistent and manageable.

You may see parts of neighbouring functions that are not relevant (as above), or you may not see enough of the preceding lines to determine the full context of the line. If this happens often, try changing the number of lines displayed.

Tab size formatting

When formatting the source code being displayed you can also control the tab size

·Tab width instructionStep set the tab size between 1 and 16 characters

Reset All - Resets all global settings, not just those on the current page.

Reset - Resets the settings on the current page.


Editing

Navigation: The User Interface > Settings > Global Settings > General >

Editing

 Return to chapter overview

The Editing tab allows you to configure which editor Thread Validator will use for editing source code.

The default settings are shown below:

Editing source code

From the Tools menu, or any of the data views in the main tabs, you can right click to edit the source code.

By default, source code is opened in a provided source code editor using syntax colouring, but you can change where you edit code via the drop-down list:

When choosing one of the editors listed, there are options for a currently open instance (e.g. the same one you're using to develop your application), or a new instance.

seeAlso SCiTE externalLink is included in the list of editors, but there are many text editors that can be used for source code on windows. Wikipedia has a comparison externalLink of editors including their programming feature support externalLink

Editing with your preferred editor

We've all got our favourite editors! To use yours:

·Select User defined editor from the list of options instructionStep enables the fields below

·Enter the Editor path and filename or just Browse instructionStep choose the executable for your preferred editor

Now when you want to edit source code, that editor will be opened, but typically you'll need to specify some command line arguments with which to start the editor.

Starting your preferred editor with command line arguments

By default, just the file name is passed as a command line argument to the editor.

Depending on the editor, you may need to tailor the arguments, for example if you want the file scrolled to a particular line.

The arguments can be specified by adding them to the table provided, one at a time and in the order required

·Add instructionStep adds a row to the Editor arguments table instructionStep select an argument Type from the following options:

The possible arguments include:

·(Space) Filename instructionStep appends a space followed by the filename

·Filename instructionStep appends just the filename

·(Space) Line Number instructionStep a space followed by the line number

·Line Number instructionStep just the line number

·Space instructionStep a space

·(Space) Other instructionStep a space followed by the text typed in the Value column of the list

·Other instructionStep just the text typed in the Value column of the list

note Only the Other options need an entry in the Value column.

note You will need to press Return after entering the value otherwise the entry won't get recognized.

The example below configures NotePad++ to edit a file at the required line using the -n switch

As you modify the arguments an example command line is shown below the list.

Managing the command line arguments

Edit a Type or Value by double clicking the entry. The usual controls apply for removing list items:

·Remove instructionStep removes selected arguments in the list

·Remove All instructionStep removes all arguments, clearing the list

Alternatively, press [image] to delete selected items, and [image] + [image] to select all items in the list first.

Reset All - Resets all global settings, not just those on the current page.

Reset - Resets the settings on the current page.


File Locations

Navigation: The User Interface > Settings > Global Settings > General >

File Locations

 Return to chapter overview

The File Locations tab allows you to specify which directories Thread Validator should look in for source code files, whether that's your own or third party code.

The default settings are shown below:

interactive Read on, or click on a setting in the picture below to find out more:

File locations

Sometimes the information Thread Validator has access to consists of the file name, but not the directory.

When this happens Thread Validator scans a set of directories that it knows about in order to find the file.

The options below allow you to specify those directories that should be searched for source files, PDB files and MAP files.

If a file can't be found, you'll get prompted for a location.

Setting directories for a path type

There are five path types, and a separate list of directories to scan for each one.

·Path Type instructionStep select the type of file with which you want to modify the list directory

note You don't have to specify any directories, e.g. if you don't want to, or if you just don't have them. Nor do you have to give directories for all the path types.

Prompting for file locations

Whenever a file still cannot be found, then the default action is for a dialog to ask you where it is.

To avoid frequent user interruption, it is recommended that the directories for source code files (yours and third party) are specified, enabling Bug Validator to automatically load source code for browsing.

If however, you don't want to be prompted for locations, you can disable that too.

·Ask for location of file... instructionStep untick to stop prompting for file locations

Even when prompting is switched on, it can still happen that the line in question is invalid anyway, e.g. line number 0 or -1.

The default is not to prompt for invalid lines, but if you want to know when that happens, just switch that behaviour off.

·Don't ask for location of file if line number is not valid... instructionStep untick to be prompted for invalid lines anyway

PDB (program database) file paths

Normally PDB search paths are automatically generated, based on the same directories that .exe and .dll files are found in:

·Automatically detect PDB paths instructionStep automatically detect PDB locations (the default)

However, it is recommended that you specify paths for PDB (program database) files, especially if your build environment dictates that PDB files are kept in different directories to their binaries.

If you don't automatically generate PDB paths and you don't specify any paths for PDBs, the search path will be defined as the current directory plus any paths found in the following environment variables:

·_NT_SYMBOL_PATH

·_NT_ALTERNATE_SYMBOL_PATH

·SYSTEMROOT

MAP file paths

It's recommended that you specify paths for Map files if your build environment means they are kept in different directories to their binaries.

If you don't specify any paths for Map files, then search paths are automatically generated, based on the same directories that .exe and .dll files are found in.

Manually adding path type directories

Once you have chosen your path type you can modify the list of files for each path type in the following ways:

·Add instructionStep appends a row to the directory list instructionStep enter the directory path

Edit a directory path by double clicking the entry. The usual controls apply for removing list items:

·Remove instructionStep removes selected items from the list

·Remove all instructionStep clears the list

·Remove invalid instructionStep removes all items that are not valid directories from the list

Alternatively, press [image] to delete selected items, and [image] + [image] to select all items in the list first.

Scanning for directories to add

The File Scan... button displays the File Search dialog to provide three ways of specifying the files to scan.

·Visual Studio Search instructionStep choose the version of Visual Studio instructionStep OK instructionStep starts a scan for directories related to that version of Visual Studio

·Directory Search instructionStep Browse... displays a directory browser instructionStep navigate to a location you want to scan within instructionStep OK instructionStep starts a scan for directories

·File System Search instructionStep OK instructionStep starts a scan of all drives for directories containing files

All options will bring up a File Scan dialog indicating number of relevant directories found, and giving you a chance to Stop or Cancel the scan at any time:

Once the scan is complete you'll see the File Paths dialog showing you the scan results:

You can modify the list of resulting directories by adding, removing or editing, exactly as for the path type list above.

Once you're happy with the scan results, either append or replace the path type directories with the scan results.

·Add To List instructionStep adds the scan results list to the path type directories and closes the File Paths dialog

·Replace List instructionStep replaces the path type directories with the scan results

·Cancel instructionStep discard the scan results and close the dialog

Exporting and Importing

Since the list of path types and their file locations can be quite complicated to set up and optimise, you can export the settings to a file and import them again later. This is useful when switching between different target applications.

·Export... instructionStep choose or enter a filename instructionStep Save instructionStep outputs all the path types and their file locations to the file

·Import... instructionStep navigate to an existing *.tvxfl file instructionStep Open instructionStep loads the path types and their file locations

Export file format

The file format is plain text with one folder listed per line. Sections are denoted by a line containing [Files] (for source code files), [Third] (for third party source code files), [PDB] etc.

Example:

[Files]

c:\work\project1\

[Third]

d:\VisualStudio\VC98\Include

[PDB]

c:\work\project3\debug

c:\work\project3\release

[MAP]

c:\work\project3\debug

c:\work\project3\release

Checking directory scanning order

To see the order in which the DbgHelp.dll process checks directories to find symbols, see the diagnostic tab, showing DbgHelp debug in the drop-down.

Reset All - Resets all global settings, not just those on the current page.

Currently, the PDB path detection checkbox at the bottom of this page is not reset as part of the global settings.

Reset - Resets the settings on the current page.

Currently, the PDB path detection checkbox at the bottom of this page is not reset as part of the global settings.


File Cache / Substitutions

Navigation: The User Interface > Settings > Global Settings > General >

File Cache / Substitutions

 Return to chapter overview

The File Cache / Substitutions tab allows you to specify the following:

·set where cached information is stored and when it gets cleared

·file path substitutions to handle copying builds from build machines to development or test machines

The default settings are shown below:

Caching file locations

Thread Validator keeps a cache of known locations for files for which it needed to search, improving the speed at which files can be found.

·Cache Directory instructionStep type directly or Browse to find a directory for Thread Validator to cache its information

By default, the cache is only flushed when the executable changes between sessions.

·Flush cache at each new session instructionStep tick to flush the cache every session

This slightly slows down relaunch of the same executable, as the cache needs rebuilding.

·Flush cache when executable changes instructionStep untick to prevent the cache being flushed at all

When not automatically flushing, you can manually flush the cache if necessary:

·Flush Cache instructionStep flush the cache now

note This is only possible when no sessions are in the session manager. The button will be disabled if any sessions are loaded.

File Path Substitutions

Some software development schemes have multiple rolling builds of their software, often enabled by using substituted disk drive naming schemes.

When you download the build to your development machine for development and testing, debugging information may reference disk drives that don't exist on your machine, for example, drive X: while your machine only has C:, D:, and E: drives.

Or you may just be copying a build from a drive on a development machine to a subdirectory on a drive on your test machine.

These options let you remap the substitution so that the Thread Validator looks in the correct place for the source code.

·Add instructionStep adds a row to the File Paths Substitutions table instructionStep enter the new path that will replace the old path in the New Path column instructionStep click in the Old Path column instructionStep enter the path that is being replaced

For example, you might enter c:\users\stephen\documents for the new path and f:\dev\build for the old path.

You can double click to edit drives and paths in the table, or remove items:

·Remove instructionStep removes selected substitutions from the list

Alternatively, press [image] to delete selected items, and [image] + [image] to select all items in the list first.

Example: Changed disk drive

Project originally located at | m:\dev\build\testApp
Project copied to | e:\dev\build\testApp
New Path | e:\
Old Path | m:\

Example: Project copied to a new location

Project originally located at | f:\dev\build\testApp
Project copied to | C:\Users\Stephen\Documents\testApp
New Path | C:\Users\Stephen\Documents
Old Path | f:\dev\build

Reset All - Resets all global settings, not just those on the current page.

Reset - Resets the settings on the current page.


Instrumentation Logging

Navigation: The User Interface > Settings > Global Settings > General >

Instrumentation Logging

 Return to chapter overview

The Instrumentation Logging tab enables you to understand the reason why part of your code isn't getting the threading information you expect.

Instrumentation logging

The logging of DLLs, source files, classes, methods and functions that are not instrumented can help you understand the reason why part of your code isn't getting the coverage information you expect.

Once enabled, and a session has started, you can view a list of items that have not been instrumented via the Tools menu.

·Enable instrumentation logging instructionStep check to enable logging once the next session starts

Diagnostics

A lot of diagnostic information is collected and displayed on the diagnostic tab when attaching to a target program.

Some of this information is always sent to Thread Validator, but you may not want to see it all.

·Enable diagnostic data collection instructionStep displays all diagnostic information in the diagnostic tab (on by default)

.NET warning

Thread Validator cannot instrument .NET assemblies and cannot monitor locks and thread synchronization primitives called from them (also known as "managed code").

However, locks and thread synchronization primitives can be monitored in any non-.NET DLLs even if part of a .NET application.

You can optionally be warned when trying to launch a .NET application:

·Display a warning dialog box when .NET applications are started instructionStep shows a warning dialog (example below) when using .NET applications (on by default)

·Help... instructionStep will open the manual for User Permissions Warnings

Reset All - Resets all global settings, not just those on the current page.

Reset - Resets the settings on the current page.


Don't Show Me Again

Navigation: The User Interface > Settings > Global Settings > General >

Don't Show Me Again

 Return to chapter overview

The Don't Show Me Again page allows you to control warnings that Performance Validator displays.

Debug Information

Debug Information Failure Warning

When there is a failure collecting debug symbols a warning can be displayed. The options are:

·Always show dialog

·Never show dialog

·Show dialog when symbol fetches throw exceptions

Display Debug Information Warning

When no debug information is available for at least one module a warning can be displayed. The options are:

·Always show dialog

·Never show dialog

·Show dialog when debug information is missing

Services

When trying to monitor a service Performance Validator can detect if the service is not linked to the NT Service API and display a warning.

It is possible to use the service API without linking to it (use GetProcAddress() to lookup the functions and call them) - in this case you would want to turn this warning off.

ISAPI

NT Service API

When trying to monitor ISAPI extensions Performance Validator can detect if the ISAPI is not linked to the NT Service API and display a warning.

It is possible to use the service API without linking to it (use GetProcAddress() to lookup the functions and call them) - in this case you would want to turn this warning off.

Debug Information

Performance Validator can warn if the ISAPI has no debug information. There may be cases where you don't want to see this warning.

Reset All - Resets all global settings, not just those on the current page.

Reset - Resets the settings on the current page.


CoInitializeEx

Navigation: The User Interface > Settings > Global Settings > General >

CoInitializeEx

 Return to chapter overview

The CoInitializeEx tab allows you to set the default behaviour used to initialize COM if Thread Validator needs to initialize COM to acquire symbols for .Net modules.

The default settings are shown below:

CoInitializeEx

In some situations the Validator needs to get .Net symbols and to do that COM needs to be initialized. This normally isn't a problem, but if your program also performs COM initialization and the sequence of events results in your COM initialization coming after the Validator's COM initialisation rather than getting the expected ERROR_SUCCESS return code you'll get either ERROR_INVALID_FUNCTION or RPC_E_CHANGED_MODE.

If you get ERROR_INVALID_FUNCTION this is OK, this just means you've called CoInitialize() or CoInitializeEx() multiple times with the same flags. Your code needs to handle ERROR_INVALID_FUNCTION as not an error.

If you get RPC_E_CHANGED_MODE this means you need to change the Validator's default value to the same value your program is using. That's what this dialog allows you to do.

If you also wish to disable OLE DDE or favour speed rather than memory use we've provided appropriate options for you to select to add those flags to the threading mode.

See the Microsoft documentation for additional information on the behaviour of CoInitialize() and CoInitializeEx().

Runtime detection of CoInitializeEx conflict

When the above scenario happens, that the Validator has initialized COM before your code initializes COM and your call returns RPC_E_CHANGED_MODE, we display a dialog to warn you about this failure and provide you with the option of editing the default value for subsequent runs of your application.

·Edit Settings... instructionStep opens the CoInitializeEx dialog shown above

Reset All - Resets all global settings, not just those on the current page.

Reset - Resets the settings on the current page.


Data Transfer

Navigation: The User Interface > Settings > Global Settings > General >

Data Transfer

 Return to chapter overview

The Data Transfer tab allows you to specify the overall behaviour of data transfer between your application and Thread Validator.

Data Transport

Choose the type of data transport you wish to use.

·Automatic. Applications and services use shared memory to transfer data. IIS uses disk based data transfer.

·Disk. Applications, services and IIS use disk based data transfer.

·High Volume. Data transfer has no data throttling applied to it. This mode is for use with applications that generate very high volumes of data rapidly. They typically exceed the buffering capabilities of Thread Validator when working with shared memory. The High Volume setting uses a data transport that doesn't have a data-throttling requirement allowing the high volume application to continue without waiting.

Automatic

Under most circumstances data transfer between Thread Validator and the target program (desktop, service, etc) is via shared memory. This is handled automatically.

Disk Data

Some applications and services don't allow shared memory access. For these occasions we use a file based data transfer, where the files are stored in a directory of your choice.

We provide two options for this, one for most applications and services, and one for Internet Information Server, as this operates in a very restricted environment.

Both options are configured automatically, but you can override either by typing the path to a suitable directory or using the Microsoft directory browser.

The ISS path you enter will be determined by the settings you have configured for IIS using the Internet Information Services Manager tool. We won't discuss that here because if you're using IIS we assume you already know how to configure IIS correctly.

Advanced

Shared memory data transfer can also be configured but we strongly recommend that you leave these settings alone.

note The Data Transfer Helper is a separate application supplied in the installation directory.

·Advanced... instructionStep opens the data transfer settings dialog.

Here be dragons!

warningnote Caution: Modifying the settings on this page and using the data transfer helper application can prevent Thread Validator from working correctly.

·Set To Defaults instructionStep if you have modified the settings, this resets them

seeAlso See also the Reset to default buttons on the data transfer helper application below

If in doubt, don't modify these settings. If you promise to be careful, read on!

Delayed data transfer

Delayed data transfer is the process of throttling data rates in the stub so that the slower user interface can keep up with processing the data received.

In the stub, as an event occurs, data is queued and then sent to the user interface.

In the user interface, data from the stub is received and queued again for processing.

Any delay is usually in the slower user interface, but still not a problem for most applications.

However, some data intensive applications can generate so much data that the user interface gets swamped and can't process it all before running out of memory.

Temporarily limiting the data rate in the stub allows the user interface to stabilize the data processing.

Managing data rates

We recommend the default settings as shown above:

·disable delay data transfer for most applications

·enable automatic delay data transfer at a threshold of between 100,000 and 1,000,000 data items

If delayed data transfer is enabled all the time, the automatic options don't apply.

If you have more than 1GB RAM, you can raise these thresholds.

Data transfer helper application

A separate data transfer helper application is supplied in the installation directory.

The helper application can be used to modify low level settings that apply when delay data transfer is activated as above.

warningnote The helper should be used with care. We already warned of dragons above, but here we are, warning you again!

An HTML help page for this application is available by clicking the Help button on the helper application.

You can also find the help page directly as dataTransferHelp.html.

Please do take a moment to read the help before use.

Reset All - Resets all global settings, not just those on the current page.

Reset - Resets the settings on the current page.


Inter-Process Communication

Navigation: The User Interface > Settings > Global Settings > General >

Inter-Process Communication

 Return to chapter overview

The Inter-Process Communication tab allows you to configure the size of the buffer used to communicate with the user interface.

Communication buffer size

Thread Validator communicates with the stub using a memory buffer to store data.

The size of the buffer is related to the number of synchronization objects that have been used.

This buffer size is increased as necessary, but this can sometimes cause a slight delay during runtime.

To avoid the buffer being expanded too often, we recommend setting the initial size of the buffer to be larger than the number of synchronization objects required.

·Initial Size instructionStep set the initial size of the buffer

·Increment instructionStep set the amount by which to increase the size of the buffer (if needed)

The size of the buffer can be calculated approximately as follows:

1 + numThreads × ( 1 + numWaitForXXXObjects + ( numCriticalSections × 3 ) )

note Don't set values overly large as this may also adversely affects memory usage. The default is 105

Reset All - Resets all global settings, not just those on the current page.

Reset - Resets the settings on the current page.


Symbol Handling

Navigation: The User Interface > Settings > Global Settings >

Symbol Handling

 Return to chapter overview

Enter topic text here.


Symbol Misc

Navigation: The User Interface > Settings > Global Settings > Symbol Handling >

Symbol Misc

 Return to chapter overview

The Symbols and Warnings tab allows you to set an assortment of symbol and diagnostic warning data.

Symbol loading - immediate or deferred

When converting program addresses to symbol names, you can choose immediate symbol loading, or defer loading until each symbol is needed.

·Use deferred symbol loading instructionStep uses deferred symbol loading rather than 'all at once' (on by default)

Microsoft® recommend deferred symbol loading, claiming it is the fastest option. We give you the choice.

Symbol Reader Logging

Symbols are fetched from symbol servers using a helper process svlDbgHelpSymbolReader.exe. We log the command line and behaviour of this helper tool. This is displayed on the diagnostic tab.

If you wish the log files can be kept for later analysis. By default this option is turned off.

·Keep svlDbgHelpSymbolReader log files instructionStep keep the log files after Bug Validator has finished processing them

The path to the directory containing the log files is shown.

·Clean instructionStep delete all svlDbgHelpSymbolReader log files

Convert Ordinals into symbols

·Convert DLL exported function ordinals to symbols instructionStep enable the ordinal to function name mapping

note You'll need to tick this to enable the use of mapped names defined in the list. If you don't, you won't see the names being used.

·Manage Ordinals... instructionStep shows the Ordinal Handling dialog to manage which .def files are associated with which DLLs

Reset All - Resets all global settings, not just those on the current page.

Reset - Resets the settings on the current page.


Symbol Lookup

Navigation: The User Interface > Settings > Global Settings > Symbol Handling >

Symbol Lookup

 Return to chapter overview

The Symbol Lookup tab allows you to specify how and where symbolic information is retrieved for your application or service.

The default settings are shown below, although the Visual Studio version may vary.

Symbol lookup for Microsoft / Intel compilers

Symbols for your application are read using an appropriate symbol handler for the type of debugging information you have.

A selection of different DbgHelp.dll versions are provided by Thread Validator:

·We can provide a DbgHelp.dll... instructionStep automatically provides the appropriate (most recent) version of Visual Studio (the default)

You can manually override which of the provided handlers is used via the list of Visual Studio versions.

Alternatively, you may wish to specify a DbgHelp.dll from disk, rather than use the provided ones.

·...locate a version of DbgHelp.dll that best matches your build instructionStep enter a path or Browse to a location to specify your own handler

Note that the directory that contains DbgHelp.dll should also contain symsrv.dll if you wish to use symbol servers with Thread Validator.

Visual Studio DbgHelp.dll version compatibility

For Microsoft Visual Studio users, each VS version provides different debugging formats which are readable by the appropriate DbgHelp.dll supplied with Visual Studio.

These handlers are usually backwards compatible, but not forwards compatible. For example Visual Studio 2005 (version 8) can read Visual Studio 6 debug information but cannot read Visual Studio 2008 debug information.

Visual Studio 6.0 doesn't supply a DbgHelp.dll so we have provided one for use with Visual Studio 6.0.

Visual Studio 10 is unusual in that the DbgHelp.dll (6.12) supplied by Visual Studio cannot read the debug information created by Visual Studio! To solve this problem we supply version 6.11 as an alternative.

note To see the order in which the DbgHelp.dll process checks directories to find symbols, see the diagnostic tab with the filter set to DbgHelp debug.

Symbol lookup for other compilers

If you are using the MinGW compiler or the Delphi or C++ Builder, choose the appropriate option.

After selecting the compiler, clicking the links will show the information below

For MinGW:

For Delphi or C++ Builder:

Reset All - Resets all global settings, not just those on the current page.

Reset - Resets the settings on the current page.


Symbol Servers

Navigation: The User Interface > Settings > Global Settings > Symbol Handling >

Symbol Servers

 Return to chapter overview

Show/Hide Hidden Text

The Symbol Servers tab allows you to specify Symbol Servers to retrieve symbols used in your application.

note You do not need to specify symbol servers if you do not wish to, and Thread Validator will work correctly without them.

interactive Read on, or click a setting in the picture below to find out more.

Symbol servers

Symbol servers are entirely optional, but are useful for obtaining symbols from a centralized company resource or for obtaining operating symbols from Microsoft.

The default symbol server is the Microsoft symbol server used for acquiring symbols about Microsoft's operating system DLLs. You may also wish to add some symbol servers for any software builds in your organisation.

A symbol server is defined by at least the following:

·the symbol server dll to be used to handle the symbol server interaction

·a directory location where symbol definitions are saved

·the server location - a url

Each symbol server can be enabled or disabled allowing you to keep multiple symbol server configurations available without constantly editing their definitions.

You can define up to four symbol servers and more than one can be enabled at a time.

Symbol Server Errors

Any symbol server entry shown in red indicates there is a problem with parts of the definition of that symbol server.

In the image shown above the symbol server at http://127.0.0.42:8000 cannot be reached. It is either offline or does not exist.

Managing symbol servers

·Add... instructionStep displays the symbol server dialog described below

·Remove instructionStep remove selected symbol server(s) in the list

·Remove All instructionStep remove all symbol servers

·Enable All instructionStep enables all symbol servers in the list

·Disable All instructionStep disables all symbol servers

You can also enable or disable an item in the list via the yellow check box at the left of each row.

To edit the details for a symbol server, just double click the entry in the list to show the symbol server dialog again.

Symbol server dialog

The dialog initially appears pre-populated with some default values and allows you to set up or edit the definition of a symbol server. Some of the default values can be changed.

·Enable Symbol Server instructionStep enable or disable this server

The following three entries must be set to enable the OK button and define the symbol server.

doc-collapse-icon OK button not enabled? The OK button will only be enabled when the following entries have a valid value:

- Symbol Server DLL names a dll present in the Thread Validator install directory.
- Symbol Store Directory has been specified and exists.
- Symbol Server URL has been specified (this value will not be checked for correctness).

·Symbol Server instructionStep select a predefined public symbol server or enter the URL of the symbol server you wish to use - the Microsoft server is initially set as the default

·Symbol Store Directory instructionStep enter or Browse to set the directory that will contain local copies of the downloaded symbols

·Create Dir instructionStep creates a directory if you entered a directory name that does not exist yet

The Symbol Server DLL is set based on the Symbol Lookup settings you have chosen.

You can optionally associate a directory to scan when you are prefetching symbols (below)

·Prefetch Directory instructionStep specify the directory to scan for symbols

Environment variables related to symbols

If you wish, you can set some environment variables to supply symbol paths.

·Configure Symbol Handling Environment Variables instructionStep opens the dialog below

Check the desired options - if any.

Pre-fetching symbols

To avoid delays when using symbol servers, you can trigger the retrieval of symbols (by running SymChk.exe) to collect symbols for all executable files specified in the exe/dll which you associated with each symbol server.

·Prefetch Symbols... instructionStep open the Prefetch Symbols dialog below to continue

Prerequisites for pre-fetching symbols

The pre-fetching of symbols requires the installation of Microsoft's Debugging Tools externalLink.

note You may already have Debugging Tools if you've previously installed the Windows Driver Kit (DDK or WDK) or the Windows SDK.

·Install Debugging Tools for Windows instructionStep opens a web page (as above) to download and install the x86 or x64 Debugging Tools for Windows

After installing the Debugging Tools, you must specify the location of SymChk.exe from the installed area.

·SymChk.exe instructionStep enter or Browse to SymChk.exe location

A typical path might be C:\WinDDK\7600.16385.1\Debuggers\symchk.exe

Getting the symbols

note Note that prefetching symbols may consume a large amount of disk space and download bandwidth.

You should ensure that you have at least 2 or 3Gb of disk free space, because of the total size of the download packages.

·Prefetch Symbols... instructionStep runs SymChk.exe to get all the symbols

The symbols for each symbol server are stored in the associated symbol store directory.

note If no symbol servers are specified in the symbol server settings above, you'll see a warning dialog and no symbols will be fetched.

Command line pre-fetching of symbols with the SymChk utility

The section on Pre-fetching symbols above is a convenient alternative to manually using the SymChk,exe utility.

To avoid delays when using symbol servers, you can pre-fetch symbols using the SymChk.exe command line tool that is part of Microsoft's Debugging Tools externalLink.

You may want to add the folder of the Debugging Tools for Windows package to the PATH environment variable on your system so that you can access this tool easily from any command prompt.

Example:

To use SymChk.exe to download symbol files for all of the components in the c:\windows\System32 folder, you might use the command:

symchk.exe /r c:\windows\system32 /s SRV*c:\symbols\*http://msdl.microsoft.com/download/symbols

where

/r c:\windows\system32 finds all symbols for files in that folder and any sub-folders

/s SRV*c:\symbols*http://msdl.microsoft.com/download/symbols specifies the symbol path to use for symbol resolution.

In this case, c:\symbols is the local folder where the symbols will be copied from the symbol server.

seeAlso To obtain more information about the command-line options for SymChk.exe, type symchk /? at a command prompt.

Other options include the ability to specify the name or the process ID (PID) of an executable file that is running.

Reset All - Resets all global settings, not just those on the current page.

Reset - Resets the settings on the current page.


Symbol Load Preferences

Navigation: The User Interface > Settings > Global Settings > Symbol Handling >

Symbol Load Preferences

 Return to chapter overview

The Symbol Load Preferences tab allows you to configure which debug information types are looked for and which are ignored.

This can save some time fetching symbols each time a DLL is loaded.

·Select your compiler / IDE... instructionStep choose a preset definition for a compiler / IDE, or edit one of four custom symbol load preferences

The present definitions are:

oI don't know which compilers instructionStep choose this if you don't know which compilers were used to build the software

oAll compilers instructionStep choose this to let Thread Validator fetch the symbols

oVisual Studio instructionStep choose this if you're only using Visual Studio

oDelphi instructionStep choose this if you're only using Delphi

oC++ Builder instructionStep choose this if you're using C++ Builder on 32 bit Windows

oC++ Builder x86 instructionStep choose this if you're using C++ Builder to build 32 bit applications

oC++ Builder x64 instructionStep choose this if you're using C++ Builder to build 64 bit applications

oMingW / gcc / g++ / QtCreator / Dev C++ instructionStep choose this if you're using MingW / gcc / g++/ QtCreator or Dev C++

oCustom 1 instructionStep choose this to edit a definition you can reuse

oCustom 2 instructionStep choose this to edit a definition you can reuse

oCustom 3 instructionStep choose this to edit a definition you can reuse

oCustom 4 instructionStep choose this to edit a definition you can reuse

Editing a definition

Once a definition has been selected the appropriate check boxes next to each debug information type are populated.

You can edit these selections, for example to include or exclude PDB debug information for operating system DLLs, or allow Thread Validator to search for COFF debug information, whatever is optimal for the way you are working.

Custom definitions

Only the custom definitions will be remembered if they are edited.

The four custom definitions will be remembered, so the next time you choose them you'll get the definition you edited. If you choose one of the preset definitions and edit it, you'll use the edited definition, but if you then change to a different preset (or a custom definition) and then back to the original preset you'll get the preset definition, not your edited version of the preset definition.

Reset All - Resets all global settings, not just those on the current page.

Reset - Resets the settings on the current page.


UI Global Hook DLLs

Navigation: The User Interface > Settings > Global Settings > Third Party DLLs >

UI Global Hook DLLs

 Return to chapter overview

The User Interface Global Hook DLLs page allows you to detect and specify global hook DLLs that may not be wanted in the Thread Validator user interface process.

About global hook DLLS

Some third party products such as storage devices and video cards are supplied with software to help integrate the hardware device into the computer desktop environment.

An example is the Iomega® Zip® drive. This uses a global hook externalLink via the IMGHOOK.DLL which allows the browse for files and browse for folders interfaces to correctly display all the storage devices on the computer, including the zip drive and any special options for the drive.

Some global (or system) hook DLLs can interfere with the correct operation of Thread Validator when it inserts hooks into the target program, (although the IMGHOOK.DLL mentioned above doesn't).

The settings below allow you to specify and/or detect DLLs that should be treated as global hook externalLink DLLs.

Any DLL listed will fail to load into the target program when loaded via LoadLibrary() or LoadLibraryEx().

For situations where the hook DLL is already present in the target program, it can optionally be forcibly unloaded. This may happen if it was loaded before Thread Validator attached to the process.

The user interface hook DLL loading rule

The default behaviour is not to allow the global hooks to load, but you can change this if necessary:

·Allow all global hooks to load instructionStep allows all global hook DLLs to load into Thread Validator

·Do not allow any global hooks to load instructionStep prevent any global hook DLLs from loading (the default)

·Use the list of dlls shown instructionStep provide per-DLL control over which DLLs load or don't load via the User Interface Global Hook DLLs list

Any global hook DLLs not listed will result in the user being asked for permission to load a DLL via the Global Hook Warning Dialog below.

Managing user interface global hook DLLs

·Add DLL... instructionStep browse and select one or more DLLs instructionStep Open instructionStep adds the chosen DLLs to the Global Hook DLLs list

Having added a DLL to the list, you can change whether the DLL is allowed to load or not, by double clicking in the second column and changing the value: Load or Don't load.

·Remove instructionStep removes any selected DLL from the list

·Remove All instructionStep removes all DLLs from the list

Auto detecting global hook DLLs

Thread Validator can detect any DLLs in its own process that are not ones it uses itself. Such DLLs are likely to be global hook DLLs:

·Auto Detect instructionStep automatically detect DLLs which may be global hook DLLs, adding them to the Global Hook DLLs list

Global Hook Warning Dialog

When the global hook loading rule above is set to Use the list of dlls shown, the Allow load column controls whether the hook DLL is loaded.

When a global hook is loaded that is not on the list of known global hooks, the user is presented with a warning dialog like that shown below.

The user can then accept or block the global hook from loading. The dialog lists a couple of known problematic DLLs.

·Help instructionStep displays this help page

·Yes instructionStep lets the DLL load

·No instructionStep blocks the DLL

Your response is automatically recorded in the Global Hook DLLs list, so that you won't be asked again.

Reset All - Resets all global settings, not just those on the current page.

Reset - Resets the settings on the current page.


Loading and Saving Settings

Navigation: The User Interface > Settings >

Loading and Saving Settings

 Return to chapter overview

Saving and loading settings files

Thread Validator settings can be saved to a file and restored at any time.

menu Settings menu instructionStep Save Settings... instructionStep save settings to a file

menu Settings menu instructionStep Load Settings... instructionStep load a previously saved settings file


User Permissions Warnings

Navigation: The User Interface > Settings >

User Permissions Warnings

 Return to chapter overview

You may see warning dialogs when Thread Validator receives an error accessing the registry or obtaining debugging privileges.

These warnings are enabled by default, but you can opt not to see them:

menu Settings menu instructionStep User Permissions Warnings... instructionStep shows the User Permissions Warnings dialog below

The Help button displays the User Permissions help topic.

seeAlso See also, the question about creating Power User accounts on Windows XP.


Symbol Path Truncated Warning

Navigation: The User Interface > Settings >

Symbol Path Truncated Warning

 Return to chapter overview

The Symbol Path Truncated warning dialog

The symbol path truncated warning dialog is displayed to warn you when the symbol path is too long.

·Edit Symbol Paths... instructionStep shows the file locations dialog so that you can edit the paths used for subsequent runs of the program.

You can choose when this dialog is displayed.

·Always show instructionStep The dialog is always shown when the symbol path is too long.

·Show when path changes instructionStep The dialog is shown when the symbol path is too long, but only if the symbol path is different than last time this warning was shown.

·Never show instructionStep The dialog is never shown.

Whether this dialog is displayed or not there is always a warning message written to the diagnostic window when the symbol path is truncated.

The display lists each path with it's length (including the unshown ';' path separator) and the total length so far so that you can see which paths exceed the truncation point (length and total displayed in red).

Any paths that don't exist on this computer are displayed in red.

Why is this dialog displayed?

You may see a Symbol Path Truncated warning dialog in some rare circumstances.

This dialog is displayed when the symbol path that has been calculated to pass to DbgHelp.dll to load Microsoft debugging symbols (found in .PDB files) is too long.

If the symbol path has been truncated because it is too long it is possible this may mean that some symbol searches will fail, resulting in failure to load some symbols. We display this dialog so that you are aware that the symbol path is too long and would benefit from editing to make the symbol path shorter.

Passing a symbol path that is too long to DbgHelp.dll will cause the program being tested to end with an EXCEPTION_INVALID_CRUNTIME_PARAMETER C runtime error. This happens because internally DbgHelp.dll is using a fixed length array to format a string. To prevent this fatal termination of the test program we limit the length of the path passed to DbgHelp.dll.

Typically if a path that is long enough to cause this problem is passed to DbgHelp it's because the number of paths in the calculated path contain paths not relevant to finding symbols for the test program. We use the Symbol Path Truncated warning dialog to show you the calculated paths so that you can work out which paths to delete.

The calculated symbol paths come from several places:

· File locations PDB paths

· Symbol server symbol storage directories

·Symbol handling environment variables

Fixing the symbol path

For this example, we are testing the program E:\om\c\3RD_SRC\cdplayer\Release\cdplayer.exe

In the image shown above you can see that seven paths exceed the truncation limit, one of the 7 paths doesn't exist.

To work out what to do we need to do several actions:

1.Looking at the environment variable settings shows that none of the environment variables are being used. We do not need to consider the content of these environment variables.

2.Examining the symbol servers shows that C:\Users\Admin is a local symbol storage location. We should keep this path.

3.We should delete the path that doesn't exist: E:\om\c\testApps\testStdinStdoutRedirectEx\Release. We do this using the file locations dialog by clicking Edit Symbol Paths... then click Delete invalid.

4.Examining the paths in the file locations dialog we can identify any paths not relevant to the program we are testing. In this case the following paths are not relevant and can be deleted.

E:\om\c\testApps\testStdinStdoutRedirect\Release

E:\om\c\testApps\testAppTheReadsFromStdinAndWritesToStdout\Release

E:\om\c\testApps\testSimpleMemoryLeak\Release

e:\om\c\3rd_src\cppunit-1.12.1\examples\cppunittest\release

e:\om\c\3rd_src\cppunit-1.12.1\examples\cppunittest\releasedll


Ordinal Handling

Navigation: The User Interface >

Ordinal Handling

 Return to chapter overview

Ordinal values and .def files

Some DLLs, including some from Microsoft, may export their functions by ordinal value, instead of by the usual readable name.

However, having access to the module's original .def externalLink file means those ordinal values can be used to look up the symbol names to display in Thread Validator.

The .def file will contain the function names and ordinal values, allowing a DLL's exported ordinal value to be mapped to the symbol name.

For example, here's a small section of mfc90.def showing the ordinal values 332 to 335 and a selection of decorated names externalLink:

??0CBrush@@QEAA@K@Z @ 332 NONAME

??0CBrush@@QEAA@PEAVCBitmap@@@Z @ 333 NONAME

??0CByteArray@@QEAA@XZ @ 334 NONAME

??0CChevronOwnerDrawMenu@@QEAA@XZ @ 335 NONAME

You can use the ordinal handler dialog (below) to associate a def file with a DLL. These associations will persist between sessions.

If you need different ordinal configurations for different DLL usage, you can export this mapping between DLL and .def to a file, to be used at a later date.

Switching usage of mapped names on and off

The option to switch the ordinal mapping on or off is in the global settings dialog:

menu Settings menu instructionStep Edit Settings... instructionStep General instructionStep Symbols and Warnings page instructionStep Convert DLL exported function ordinals to symbols instructionStep enable the ordinal to function name mapping

note You'll need to tick this to enable the use of mapped names defined in the dialog below. If you don't, you won't see the names being used.

The ordinal handler dialog

The ordinal handler dialog lets you manage which .def files are associated with which DLLs.

menu Settings menu instructionStep Edit Settings... instructionStep General instructionStep Symbols and Warnings page instructionStep Manage Ordinals... instructionStep shows the ordinal handler dialog below

·Add... instructionStep shows the ordinal-to-function converter dialog, described below, so you can add a new mapping

·Edit... instructionStep opens a selected mapping in the ordinal-to-function converter dialog

Double clicking an item in the list also does this.

·Remove instructionStep removes the selected associations from the list

·Remove All instructionStep clears all the associations in the list

·Import... instructionStep choose a previously saved set of associations to add to the list

·Load... instructionStep as for Import, but replaces the contents of the list

·Save... instructionStep saves the associations in the list to a .ord file of your choice

The ordinal-to-function converter dialog

After clicking Add... on the Ordinal Handler Dialog (above) you'll see the Ordinal to function converter dialog below.

The basic process for adding a new mapping is to:

·choose a DLL

·find its matching .def file

·convert the ordinal values to symbol names

·add the file association to the Ordinal Handler dialog

This example shows the Microsoft MFC90.dll associated with its .def file:

Associating the DLL and .def files

In the Ordinal to function converter dialog:

·DLL to examine... instructionStep type or Browse to enter the DLL you want to map

·Definition file to examine... instructionStep type or Browse to enter the .def file you want to associate with the DLL, or choose one from the drop-down list (see scanning for files below)

If a .def file matching the name of the .dll exists in the same directory as the DLL, this will be set automatically.

·Convert Ordinals into Symbol Names instructionStep convert the exported ordinals from the chosen DLL into symbol names using the specified .def file

All the ordinals and symbol names found will be displayed in the list at the bottom.

·OK instructionStep closes the dialog and adds the association between the DLL and the .def to the ordinal handler dialog

note Don't forget to select the Convert DLL exported function ordinals to symbols check box.

Scanning for .def files

The .def files aren't always in the same directory as the DLLs and may be hard to find, so a search option is available.

note Any .def files found during a scan can be used to extend or replace the choices in the drop-down list of the Definition file to examine... option above.

·Partial Scan... instructionStep choose a folder and scan it for .def files

·Full Scan... instructionStep scan all drives for .def files

While scanning, a progress dialog shows the search location and the number of .def files found:

·Stop instructionStep stop the scan and show results found so far

·Cancel instructionStep stop the scan and discard any results

When the scan is complete a dialog shows any .def files found:

·Add To List instructionStep extend the drop-down list of the Definition file to examine... option by adding all the search results in the list

·Replace List instructionStep as above but replaces the list rather than extending it

·Add instructionStep adds an entry to the list so you can manually enter a file path

·Remove instructionStep remove any selected items from the list

·Remove All instructionStep clears the list

·Cancel instructionStep closes the dialog, discarding the list of results


Managers

Navigation: The User Interface >

Managers

 Return to chapter overview

The Managers menu provides a handful of powerful tools to manage or inspect data collected by Thread Validator.

The tools include:

· session management

· thread filters

· watermarks and bookmarks


Session Manager

Navigation: The User Interface > Managers >

Session Manager

 Return to chapter overview

Managing multiple sessions

Thread Validator can manage multiple sessions at once.

As well as the actively running session, open sessions may include those run since Thread Validator started, or reloaded sessions that had been saved earlier.

menu Managers menu instructionStep Session Manager... instructionStep shows the Session Chooser dialog below, highlighting the current session

Each time a session is started or loaded it is added to this list, using the name of the executable program and the date and time the session started.

Managing the sessions

·Select instructionStep makes the selected entry the current session, i.e. the one for which data will be displayed

note Some tab views may update immediately, others may need a manual refresh.

·Set Alias... instructionStep opens the Edit Session Alias dialog so you can give the session a more useful name

The alias is added before the session details:

·Delete instructionStep removes the selected session

You can't delete a session that is actively collecting data.

·Delete All instructionStep removes all the loaded sessions

If one of the session is actively collecting data, this will be disabled.

·Close instructionStep closes the dialog (as opposed to closing any selected sessions!)

Limiting the number of sessions

You can choose to limit the maximum number of sessions open at once.

Once this limit is reached, then each time a new session is added, the oldest session may automatically be removed:

·Auto purge sessions instructionStep ensures that the number of loaded sessions is limited to the maximum (below)

·Maximum number of sessions instructionStep sets the maximum number of sessions allowed if auto-purge is on


Thread Filter

Navigation: The User Interface > Managers >

Thread Filter

 Return to chapter overview

Thread filtering affects data displayed on All Locks, Locks Per Thread, Active Locks, Thread Locks, Active Objects and Analysis tabs

Thread filters

Thread filtering simply allows you to exclude data according to the thread id.

Filtering by thread id is only going to be useful for multi-threaded applications.

Many applications have threads that you may want to exclude from your data as being beyond your control.

note The thread filter dialog below also serves the dual purpose of manually naming threads. The names are used elsewhere in the display of data and selection of threads.

The thread filter dialog

menu Managers menu instructionStep Thread Filter... instructionStep shows the Filter Objects by Thread Id dialog

The dialog has a list of all the threads in the target program, with check boxes to enable and disable the display of data from each thread id.

·Enable All instructionStep checks all threads, meaning that no thread filtering will occur

·Disable All instructionStep unchecks all threads, making it easier to enable just one or two of many threads

To sort the list on id or name, click one of the headers.

To edit a thread name, double click on the name.

Thread names

If a thread has been named using the Win32 RaiseException method, the Win32 SetThreadDescription(), or using tvSetThreadName() its name is shown in the list above. See the link below for more details.

For unnamed threads, you can give it a name here by double clicking on the name column and entering a name for the thread. Click outside the box or press return to complete the entry.

Names of threads will be used where relevant in other parts of the application such as the Thread or Owning Module columns in tabular data or in callstack information.

seeAlso How can I give a name to a thread from my code?


Watermarks

Navigation: The User Interface > Managers >

Watermarks

 Return to chapter overview

Watermarks

In Thread Validator, Watermarks are event markers in the allocation history at which you can say other events occurred either before or after the watermark.

Watermarks are used in the Active Objects and Analysis tabs as a kind of filter to constrain displayed data to that which happened between two watermarks.

Adding watermarks

You can add new watermarks directly from allocation items displayed in the Active Objects and Analysis tabs, using the popup menu options.

Watermarks added this way are initially named using the .exe or DLL and the function name as in the picture below, but you can change this if you want.

Alternatively, you can add a watermark at the most recent recorded allocation event:

menu Managers menu instructionStep choose Add watermark at most recent trace instructionStep enter a name instructionStep click OK

Or use the option on the Watermarks Toolbar:

note The most recent trace event may not actually be visible in any of the displays as it could be filtered or hidden for other reasons.

First and last watermarks

There are two permanent special watermarks, not directly associated with particular events:

·The first watermark is the point before every other event

·The last watermark is the point after every other event

These two watermarks are the default settings, meaning that no data is filtered due to watermarks.

You cannot remove or rename the first and last watermarks.

The watermarks dialog

When a session is active, you can show the watermark manager to see a list of watermarks, change their names, or apply selected watermarks to the data views:

menu Managers menu instructionStep Watermark Manager... instructionStep shows the Watermarks dialog

Or use the Watermarks Toolbar option:

Watermarks are shown in order of their associated event allocation history.

If you haven't added any watermarks yet, this will just be the special first and last watermarks.

note The watermarks dialog can only be shown when the Active Objects or Analysis tab is open.

Managing the watermarks

There's a few options for renaming and removing watermarks:

·Edit... instructionStep rename the selected watermark

Double clicking on the watermark also works.

You can't edit the first and last watermarks.

·Delete instructionStep delete the selected watermark

You can't remove the first and last watermarks.

·Delete All instructionStep delete all the watermarks except the first and last

You can't change watermark locations. If you want to do that, delete the watermarks you don't want and add new ones.

Applying watermarks to the data displays

You can override the local watermark settings in the Active Objects and Analysis tabs.

At the bottom of the watermarks dialog choose the watermarks:

·First instructionStep set the earlier of the watermark range

·Second instructionStep set the later of the watermark range

You can't choose a second watermark which is earlier than (or the same as) the first one.


Bookmarks

Navigation: The User Interface > Managers >

Bookmarks

 Return to chapter overview

Bookmarks

Bookmarks are event markers in the allocation history. You can use the Bookmarks dialog to jump back to a bookmarked location any time.

Bookmarks are only used in the Active Objects and Analysis tabs.

Adding bookmarks

Adding bookmarks is very similar to adding watermarks.

You can add new bookmarks directly from allocation items displayed in the Active Objects and Analysis tabs, using the popup menu options.

Bookmarks added this way are initially named using the .exe or DLL and the function name as in the picture below, but you can change this if you want.

Alternatively, you can add a bookmark at the most recent recorded allocation event:

menu Managers menu instructionStep choose Add bookmark at most recent trace instructionStep enter a name instructionStep click OK

Or use the option on the Watermarks Toolbar:

note The most recent trace event may not actually be visible in any of the displays as it could be filtered or hidden for other reasons.

The bookmarks dialog

When a session is active, you can show the bookmark manager to see a list of bookmarks, change their names, or jump to a bookmark location:

menu Managers menu instructionStep Bookmark Manager... instructionStep shows the Bookmarks dialog

Or use the Watermarks Toolbar option:

Unlike watermarks, bookmarks are shown in the order you add them.

note The bookmarks dialog can only be shown when the Active Objects or Analysis tab is open.

Jumping to bookmark locations

The most useful option in this dialog is the Goto:

·Goto instructionStep scrolls the open tab to the selected bookmark and selects it (if it exists in the current tab)

Double clicking on the bookmark also jumps to its location.

Managing bookmarks

There's also a few options for renaming and removing bookmarks:

·Edit... instructionStep rename the selected bookmark

·Delete instructionStep delete the selected bookmark

·Delete All instructionStep delete all the bookmarks in the list

You can't change bookmark locations. If you want to do that, delete the bookmarks you don't want and add new ones.


Query and Search

Navigation: The User Interface >

Query and Search

 Return to chapter overview

Tools to search for allocations

The following tools help you find memory and handle allocations using different criteria and are all found on the Query Menu.

interactive Click on an item in the picture or in the list below to find out more in the following topics.

·Search instructionStep use the Find Sychronization Object dialog to search the data in some of the tab views for synchronization events

·Find Function instructionStep use the Find Functions dialog to search for synchronization enter/exits and synchronization object allocations/deallocation occurring in certain functions

·Single Thread Critical Section Detector instructionStep use the Single Thread Critical Section Detector dialog detect potentially unnecessary synchronization objects that have only been used in one thread

·Display stack traces for all threads instructionStep use the Deadlocked Thread PostMortem dialog to analyse your application that has already deadlocked

·Deadlock detection instructionStep Perform deadlock detection in your application

·Potential deadlock detection instructionStep Perform potential deadlock detection in your application

·Display lock order instructionStep use the Locks and Waits in Sequence Order dialog to display the order in which locks and waits were entered


Finding synchronization objects

Navigation: The User Interface > Query and Search >

Finding synchronization objects

 Return to chapter overview

Searching for synchronization objects

Using the Find Synchronization Object dialog below, you can search for objects in the Active Objects Tab.

Searches can be:

·based on allocation location such as in a function, file or module

·based on the allocated object such as type or address

The Analysis Tab has its own Find function which does the same search within data collected in its own view.

The Find Synchronization Object dialog

To show the Find Synchronization Object dialog, choose the menu option below:

menu Query menu instructionStep choose Search... instructionStep displays the dialog below

Or use the following icon on the Query Toolbar.

Note that this dialog can remain open while you inspect the results.

Search Criteria

Each of the desired search options needs to be enabled and criteria specified:

To find objects... | enable the option and choose...
·of type | a data type from the drop down list
·in function | a function from the list
·allocated in file | a file from the list
·in module | an .exe, DLL or other module
·in thread | a thread or "Any" to accept any thread
Objects between... |
·addresses | type in the values or choose the current minimum or maximum from the drop down list

For options where there is a set choice of values, the lists show all the options that Thread Validator knows about at the time the dialog is shown.

Where a range is specified, you can enter the same value for the beginning and end of the range.

Exclusive or inclusive searches

There are two ways of searching:

·Exclusive instructionStep search results satisfy all the enabled search criteria

·Inclusive instructionStep search results satisfy at least one of the enabled search criteria

As a general rule, exclusive searches return a tightly focused set of results, while inclusive searches return a broader set of results.

For those who prefer logic notation, exclusive searches use AND logic, while inclusive use OR logic.

Performing the search

Once search criteria are enabled, and search mode selected, results can be found:

·Find... instructionStep matching results in the corresponding tab are highlighted

The colour of selected objects is set on the colours tab of the Global Settings dialog.

Example search

Here are two example searches performed on the Example Application, one inclusive, one exclusive.

Inclusive

Search for type CriticalSection, in the range 0x67c20000 to 0x67c22000, inclusively. All other search criteria are disabled.

The results are shown below - all CriticalSection objects are selected.

Exclusive

The search is repeated using same search criteria as above, but with the exclusive option selected.

The results are shown below and only CriticalSection objects in the specified address range are now selected.


Finding functions

Navigation: The User Interface > Query and Search >

Finding functions

 Return to chapter overview

Searching for object allocations in functions

Using the Find Function dialog below, you can search for objects occurring in certain functions.

The functions can be the allocation/creation function or anywhere in the callstack

The find function dialog

To show the Find Function dialog, choose the menu option below:

menu Query menu instructionStep choose Find Function... instructionStep displays the Find Function dialog

Or use the following icon on the Query Toolbar.

Search criteria

Enter a function name, and optionally any other search characteristics to find objects allocated in matching functions

·Function instructionStep enter full or partial function name

·Match case instructionStep tick to do a case-sensitive match

·Complete function name instructionStep tick to only match the whole name

note For C++ methods, complete names must be of the form classname::methodname.

·Trace locations instructionStep matches only the function containing the object allocation

·Callstacks instructionStep matches any function in the allocation callstack

Finding results

·Find instructionStep performs the search displaying results in the list

note Results replace any previous search.

You can expand the search results, and double click the data items to edit source code in your preferred editor.

Examples of finding allocations in functions

Thread Validator has an example program you can use to safely explore features.

In the example program, the Test menu has options for a Bad and Good lock strategy example.

After doing both of these, the example searches can be made below.

Searching only within matching functions

Searching for critical section usage only in functions that have ontestbad as part of their name finds these results in CTeststakView::OnTestBadlockstrategyexample

Searching anywhere in the callstack

Changing the function name to oncmd and now searching in any part of the callstack finds both the 'Good' and 'Bad' lock strategy functions called from CCmdTarget::OnCmdMsg


Finding critical sections only used in one thread

Navigation: The User Interface > Query and Search >

Finding critical sections only used in one thread

 Return to chapter overview

Searching for critical sections only used in one thread

Using the Single Thread Critical Section Detector dialog below, you can search for potentially unnecessary synchronization objects that have only been used in one thread.

If further examination within your program confirms the critical sections are not needed, you may be able to improve performance in your program by removing them.

The Single Thread Critical Section Detector dialog

To show this dialog, choose the menu option below:

menu Query menu instructionStep choose Single Thread Critical Section Detector... instructionStep displays the dialog below

Or use the following icon on the Query Toolbar.

Display options

·Display one/all entry per critical section instructionStep show just one use of a given critical section by one thread, or show all uses

·Clear instructionStep remove any existing results from the display

Finding results

·Find instructionStep performs the search, displaying results in the list

note Results are appended to any previous search results.

You can expand the search results, and double click the data items to edit source code in your preferred editor.

Examples of finding objects used in one thread

Thread Validator has an example program you can use to safely explore features.

In the example program, the Test menu has options for starting deadlock threads:

After starting deadlock Thread 1, that menu option is disabled and clicking Find on the Single Thread dialog shows two results:


Fetching callstacks for all threads

Navigation: The User Interface > Query and Search >

Fetching callstacks for all threads

 Return to chapter overview

Fetching callstacks for all threads

Using the Deadlocked Thread PostMortem dialog below, you can retrieve all thread callstacks in your application.

This may be useful in many ways, but in particular, if you know a deadlock has occurred in your program, then examining the callstacks of each thread will help determine where the deadlock occurred.

The Deadlocked Thread PostMortem dialog

To show this dialog, choose the menu option below:

menu Query menu instructionStep choose Display stack traces for all threads... instructionStep displays the dialog below

Or use the following icon on the Query Toolbar.

The dialog appears already populated with the callstack information

·Clear instructionStep remove any existing results

·Refresh instructionStep update the list of callstacks shown in the display

Viewing the callstacks

The image below shows the results of a search that has been expanded to show a callstack.

Note that above each callstack, the thread id (and name if the thread is named) is displayed followed by a list of critical sections which this thread has locked or is waiting upon.

For example:

If the thread is not waiting upon any critical sections and is not involved in a wait, a message No critical sections or waits for this thread is displayed.

'Unable to get locks list' warning

If Thread Validator fails to find the process locks list it will provide a warning and information for what to do to enable the list to be found.

In this example, the suggestion is to enable a Microsoft Symbol Server.


Deadlock detection

Navigation: The User Interface > Query and Search >

Deadlock detection

 Return to chapter overview

The deadlock and potential deadlock settings allow Thread Validator to regularly scan for various error conditions using the same data collected by the options on the Collect settings tab.

If your application has many threads, you may prefer to disable these options to prevent Thread Validator from using too much processor time.

However, at run time you can force Thread Validator to check for deadlocks or potential deadlocks in the application under test.

Forcing a deadlock check

If deadlock detection is off by default, you can manually trigger a deadlock check:

menu Query menu instructionStep choose Deadlock detection instructionStep runs a deadlock check updating displays accordingly

This menu option will be disabled if the Deadlocks option on the Detect settings tab is enabled.

Example

The example application can be used to demonstrate the deadlock checking:

1. Turn off the Deadlocks option on the Detect settings tab and

2. Launch the example application.

3. Use some of the built in tests to create a deadlock, for example the 3 thread deadlock.

4. Notice that Thread Validator does not register the deadlocks including for example, in the following three displays.

In the Errors panel of the Summary tab:

In the snapshots view of the Threads tab

Or in the All Locks tab:

5. Force a deadlock check as described above, and each of these displays will update to show the deadlocks found

In the Errors panel of the Summary tab, where the red bar indicates 3 deadlocked locks:

note Note these options are disabled, reflecting the disabled general deadlock detection setting which prevents interactive exploration of the deadlock data. Enable the setting to explore further.

In the snapshots view of the Threads tab, where the thread snapshots now starts to register the threads as locked (red)

Or in the All Locks tab, where the locked threads are also now highlighted in red:


Potential deadlock detection

Navigation: The User Interface > Query and Search >

Potential deadlock detection

 Return to chapter overview

The deadlock and potential deadlock settings allow Thread Validator to regularly scan for various error conditions using the same data collected by the options on the Collect tab.

If your application has many threads, you may prefer to disable these options to prevent Thread Validator from using too much processor time.

However, at run time you can force Thread Validator to check for deadlocks or potential deadlocks in the application under test.

Forcing a potential deadlock check

If potential deadlock detection is on but the detection interval is set to a long time or to Never, you may wish to manually trigger a potential deadlock check:

menu Query menu instructionStep choose Potential deadlock detection instructionStep runs a potential deadlock check, updating displays accordingly

This menu option will only be enabled if the Potential Deadlocks option on the Detect settings tab is enabled.

Example

The example application can be used to demonstrate the deadlock checking:

1. Turn on the Potential Deadlocks option on the Detect settings tab

2. Set the Deadlock detect interval to Never (on the same setting page)

3. Launch the example application.

4. Use some of the built in tests to create a potential deadlock, for example the Potential deadlocks 2 thread.

5. Notice that Thread Validator does not register the potential deadlocks including for example, in the following three displays.

In the Errors panel of the Summary tab:

In the snapshots view of the Threads tab

Or in the All Locks tab:

6. Force a potential deadlock check as described above, and each of these displays will update to show the potential deadlocks found

In the Errors panel of the Summary tab, where the pink col-potdead bar indicates 2 potential deadlocks:

In the snapshots view of the Threads tab, where the thread snapshots now starts to register the threads as having potential deadlocks (pink col-potdead)

Or in the All Locks tab, where the locked threads are also now highlighted in pink:


Display lock order

Navigation: The User Interface > Query and Search >

Display lock order

 Return to chapter overview

Lock order dialog

Thread Validator can display the order in which locks and waits were entered.

The lock order dialog (i.e. Locks and Waits in Sequence Order dialog) can be started in two different ways:

·All Locks tab instructionStep [image] popup menu instructionStep Lock Acquisition Order...

· menu Query menu instructionStep Display lock order

The dialog displays the order...

·in which critical sections are locked and waited upon

·that waits are entered into

·in which threads sleep and are suspended

For this, you need to enable the Functions working with waitable handles option on the Hook Insertion settings page.

note You don't need to enable the individual Sleep option.

Data displayed in the table

·Thread Id instructionStep displays the thread id and a thread name if one is available

·Address instructionStep the critical section address that is locked or being waited upon

For WaitForSingleObject calls, this is the handle that is being waited upon.

For WaitForMultipleObjects calls, the number of handles being waited upon is shown.

·Sequence instructionStep displays the sequence id of the lock or wait

Green bars in this column indicate the sequence id relative to the known range of all ids.

·Status instructionStep displays the word Locked or Waiting for critical sections

For WaitForSingleObject or WaitForMultipleObjects calls the appropriate function is displayed instead.

·Member variable instructionStep shows information about the storage variable used when entering the critical section

·Filename instructionStep displays the filename of the function where the critical section was entered

Understanding the data

The image below shows that three threads have deadlocked.

Each thread has acquired one lock and is waiting upon another, so there's two entries in this view for each thread.

The order the threads acquired and is waiting upon locks is the same as the order of the data in the list, which is in turn the same as the sequence ids in the Sequence column.

This situation was caused by the bad lock strategy used in the example program.

In this example three threads are created - lets call them A, B and C - and each repeatedly attempts to lock two of the critical sections a,b and c as follows:

·Thread A locks sections a and b and then unlocks b and a

·Thread B locks sections b and c and then unlocks c and b

·Thread C locks sections c and a and then unlocks a and c

It should be easy to see that a three lock circular deadlock will occur quickly occur as each thread waits for a lock that another thread has, and indeed this is what the image above shows us has happened.

Sleeping threads

When a sleeping thread is listed:

·the Address column displays Thread

If the Hook Insertion settings has Functions working with waitable handles enabled:

·the Sequence column indicates the sequence id for the start of the thread sleeping

The horizontal position of the green bar in this column changes to show relative size of the sequence id compared to the most recently allocated id.

·the Status column displays Sleeping.

Suspended threads

When a suspended thread is listed:

·the Address column displays Thread

If the Hook Insertion settings has Functions working with waitable handles enabled:

·the Sequence column indicates the sequence id for the start of the thread suspension

·the Status column displays Suspended

Related threads

Selecting a critical section or wait handle in the list highlights (in grey) any other threads using the same critical section or handle (same address).

Any other occurrences of the same thread waiting on a lock or holding a lock will also be highlighted with the thread information colour (orange col-threadinfo by default).

Updating the display

·Auto Update instructionStep refresh the contents of the list once per second

·Refresh instructionStep refresh the list manually when you need to

The green bars in the Sequence column are automatically updated periodically.

Menu Options

A popup menu is available by right clicking on any item in the list:

Menu option: Information about lock or wait

·Information about lock/wait... instructionStep shows the relevant information dialog from those below, depending on the type of item selected

These information dialogs do not block the application so you can show as many as you need, either from this tab or others, and leave them open to compare or investigate later.

Menu option: editing source code

·Edit Source Code... instructionStep opens the default or preferred editor to edit the source code

Menu options: show ... callstacks

·Show Creation Callstack... instructionStep shows the callstack for the creation of this item, i.e. the locked or waiting critical section and thread

·Show Lock Callstack... instructionStep shows the callstack for the locked or waiting critical section and thread

·Show All Lock Callstacks (this thread)... instructionStep shows all callstacks for this critical section and only this thread

·Show All Lock Callstacks (all threads)... instructionStep as above but for any thread


Tools

Navigation: The User Interface >

Tools

 Return to chapter overview

interactive Click on an item in the picture of the Tools Menu below to jump to the relevant topic:


Colour coded source code editor

Navigation: The User Interface > Tools >

Colour coded source code editor

 Return to chapter overview

Source code editing

The editing settings let you set an editor of your choice to view or edit source code. Thread Validator's built-in editor is one of those options.

The built-in editor can be started in several ways:

·double click on a source code fragment in one of the views

· [image] popup menu instructionStep Edit Source Code...

· menu Tools menu instructionStep Edit Source Code...

Using the built-in editor

The built-in editor supports the basic operations expected for editing source code:

File menu

The file options need no explanation:

Edit menu

All the following edit options should also be familiar:

Undo/Redo is unlimited by default, but this can be changed in the options below.

note Editing bookmarks has nothing to do with Thread Validator's own bookmarks.

Formatting menu

The formatting menu has general display and editing options

·Convert instructionStep Tabs to spaces instructionStep turns all tabs into spaces

·Convert instructionStep Spaces to tabs instructionStep turns all spaces into tabs

·Use Colour instructionStep toggles the colour coded display

·Fonts and Line Numbers... instructionStep change text colours, fonts and line numbers

·Options... instructionStep set tab length and other options

·Wrap Width... instructionStep changes the column width at which lines will wrap in the display

Status bar

The status bar shows help text at the bottom as you hover over menu and toolbar options.

To the right of the status bar are insert mode, column number and line number.

Line collapsing

You can temporarily collapse sections of code as follows:

·Left click in the margin to start the section instructionStep Drag to define the length instructionStep Release to set the end of the section

Click anywhere on the resulting indicator to collapse, and on the + to expand a section.

You'll need to drag near the middle of the empty grey area, as not all of the margin is active.

Expanded:

Collapsed:

note Line collapsing is temporary and not remembered between edit sessions.


Refresh and Refresh All

Navigation: The User Interface > Tools >

Refresh and Refresh All

 Return to chapter overview

Refreshing data

You have the option in some views to automatically update in the view at an interval of your choice.

Sometimes you need to refresh the data when you want to, especially while inspecting the data.

Most views have a local Refresh button, which updates the data.

The same function is found in the Tools menu, as well as an option to update all views at once.

menu Tools menu instructionStep Refresh instructionStep refresh the data displayed only on the current tabbed view

menu Tools menu instructionStep Refresh All instructionStep refresh the data on all the tabbed views

or use the Refresh and Refresh All icons on the Tools toolbar.


Loaded Modules

Navigation: The User Interface > Tools >

Loaded Modules

 Return to chapter overview

Viewing the loaded modules

You can view a list of the modules which are loaded by your target application.

menu Tools menu instructionStep Loaded Modules... instructionStep shows the Loaded Modules dialog below

The dialog shows:

·the Address space occupied by the module (DLL or EXE)

·the type of Code in the module (native, managed, mixed mode or resources only

·the type of Build - is the code debug or release?

·the Path the module was loaded from


DLL Debug Information

Navigation: The User Interface > Tools >

DLL Debug Information

 Return to chapter overview

Viewing the DLL debug information

If you are having problems collecting thread data for a particular EXE/DLL the problem may be that the debug information that is required to perform the instrumentation of the software cannot be found.

You can view a list of the debug information status of modules loaded by your target application.

menu Tools menu instructionStep DLL Debug Information... instructionStep shows the DLL Debug Information dialog below

The dialog shows:

·the path from which Modules (DLL or EXE) were loaded

·the debug Status (below)

·if any symbol server is not reachable (offline or doesn't exist) a message will be shown in red at the bottom of the dialog. You can edit the symbol server definitions here.

Debug status

There are various reasons why a module may not have its debug information read.

The dialog shows a comment or reason in the status column. Examples might be:

·PDB or MAP if the debug information was found and used

·Debug information not present

·A reason for being ignored

·Module is a part of the C Run-time Library (CRT) or Standard Template Library (STL)

·Location is a system directory

·Ignored due to Hooked DLLs advanced settings

·File is a Software Verify own module

·Module has been specified as a 3rd party

·No executable code is contained

·The module only has GUI resources

More information about PDB and MAP files

Clicking on the Learn more... link at the top right of the dialog shows some more details with additional links to topics in this help.

interactive Click the links below to read more in our frequently asked questions.

Finding out more using the Debugging Information Diagnosis Dialog

When debug information is not present for a given module the DLL Debug Information dialog (above) may display a button in the Status column to show the Debugging Information Diagnosis dialog.

The dialog shows:

·Information, advice, and diagnostic help

·Quick links to change settings

The information options include:

·Debugging information advice... instructionStep shows the Symbols and Debugging Information dialog above.

·Help me choose what flags... instructionStep shows the Debugging Flags wizard

Use the wizard to first select the compiler or linker you're using

Next >> instructionStep Provides the relevant debug compiler and linker flags. An example for Visual Studio 2017 to 2015 is below:

·Show me how debug information was searched for... instructionStep shows the Debug Information Search Path dialog

This information is extracted from the Diagnostic tab and shows only the relevant information for the module selected in the DLL Debug Information dialog.

The options for changing settings include quick links to the following pages from the Global Settings Dialog

·Edit PDB search paths... instructionStep shows the File Location settings page for PDB files.

·Edit symbol lookup options... instructionStep shows the Symbol Lookup settings page

·Edit symbol server options... instructionStep shows the Symbol Servers settings page

·Edit symbol load preferences... instructionStep shows the Symbol Load Preferences settings page

·Edit symbol debug options... instructionStep shows the Symbol Misc settings page


Symbol Path Truncation

Navigation: The User Interface > Tools >

Symbol Path Truncation

 Return to chapter overview

menu Tools menu instructionStep Symbol Path Truncation... instructionStep shows the Symbol Path Truncation dialog

The Symbol Path Truncated warning dialog

The symbol path truncated warning dialog is displayed to warn you when the symbol path is too long.

·Edit Symbol Paths... instructionStep shows the file locations dialog so that you can edit the paths used for subsequent runs of the program.

You can choose when this dialog is displayed.

·Always show instructionStep The dialog is always shown when the symbol path is too long.

·Show when path changes instructionStep The dialog is shown when the symbol path is too long, but only if the symbol path is different than last time this warning was shown.

·Never show instructionStep The dialog is never shown.

Whether this dialog is displayed or not there is always a warning message written to the diagnostic window when the symbol path is truncated.

The display lists each path with it's length (including the unshown ';' path separator) and the total length so far so that you can see which paths exceed the truncation point (length and total displayed in red).

Any paths that don't exist on this computer are displayed in red.

Why is this dialog displayed?

You may see a Symbol Path Truncated warning dialog in some rare circumstances.

This dialog is displayed when the symbol path that has been calculated to pass to DbgHelp.dll to load Microsoft debugging symbols (found in .PDB files) is too long.

If the symbol path has been truncated because it is too long it is possible this may mean that some symbol searches will fail, resulting in failure to load some symbols. We display this dialog so that you are aware that the symbol path is too long and would benefit from editing to make the symbol path shorter.

Passing a symbol path that is too long to DbgHelp.dll will cause the program being tested to end with an EXCEPTION_INVALID_CRUNTIME_PARAMETER C runtime error. This happens because internally DbgHelp.dll is using a fixed length array to format a string. To prevent this fatal termination of the test program we limit the length of the path passed to DbgHelp.dll.

Typically if a path that is long enough to cause this problem is passed to DbgHelp it's because the number of paths in the calculated path contain paths not relevant to finding symbols for the test program. We use the Symbol Path Truncated warning dialog to show you the calculated paths so that you can work out which paths to delete.

The calculated symbol paths come from several places:

· File locations PDB paths

· Symbol server symbol storage directories

·Symbol handling environment variables

Fixing the symbol path

For this example, we are testing the program E:\om\c\3RD_SRC\cdplayer\Release\cdplayer.exe

In the image shown above you can see that seven paths exceed the truncation limit, one of the 7 paths doesn't exist.

To work out what to do we need to do several actions:

1.Looking at the environment variable settings shows that none of the environment variables are being used. We do not need to consider the content of these environment variables.

2.Examining the symbol servers shows that C:\Users\Admin is a local symbol storage location. We should keep this path.

3.We should delete the path that doesn't exist: E:\om\c\testApps\testStdinStdoutRedirectEx\Release. We do this using the file locations dialog by clicking Edit Symbol Paths... then click Delete invalid.

4.Examining the paths in the file locations dialog we can identify any paths not relevant to the program we are testing. In this case the following paths are not relevant and can be deleted.

E:\om\c\testApps\testStdinStdoutRedirect\Release

E:\om\c\testApps\testAppTheReadsFromStdinAndWritesToStdout\Release

E:\om\c\testApps\testSimpleMemoryLeak\Release

e:\om\c\3rd_src\cppunit-1.12.1\examples\cppunittest\release

e:\om\c\3rd_src\cppunit-1.12.1\examples\cppunittest\releasedll


Instrumentation Log Data

Navigation: The User Interface > Tools >

Instrumentation Log Data

 Return to chapter overview

Instrumentation Log Data

It can be very useful to know why your code hasn't been instrumented. For example, a file or part of a file you were expecting to receive coverage information may have been excluded by one or more of the DLL filters in the Global Settings dialog.

To log details of why dlls are not instrumented, first switch on the instrumentation logging settings.

Once enabled, and a session has started, you can view a list of the files that have not been instrumented via the Tools menu.

menu Tools menu instructionStep Instrumentation Logging Data... instructionStep shows the Instrumentation Log Data dialog

The dialog shows:

·log order

·the name of the item that hasn't been instrumented

·the reason why each item wasn't instrumented

Example reasons why an item might not be instrumented include the following:

·MFC file ignored

·Microsoft C Runtime file ignored

·Microsoft DLL ignored

·CRT DLL ignored

·Software Verify's own DLL ignored


Software Updates

Navigation: The User Interface >

Software Updates

 Return to chapter overview

This topic covers the items on the Software Updates menu:

· checking for software updates

· configuring your update schedule

· renewing your software maintenance

· setting your software update credentials

· setting the software update directory

Software updates

If you've been notified of a new software release to Thread Validator or just want to see if there's a new version, this feature makes it easy to update.

menu Software Updates menu instructionStep Check for software updates instructionStep checks for updates and shows the software update dialog if any updates exist

An internet connection is needed to be able to make contact with our servers.

note Before updating the software, close the help manual, and end any active session by closing target programs.

If no updates are available, you'll just see this message:

note Note that evaluation versions cannot be updated.

Software Update dialog

If a software update is available for Thread Validator you'll see the software update dialog, unless your maintenance has expired.

·Download and install instructionStep prompts you for login details if not known, and then downloads the update, showing progress

note If you haven't set login credentials, you may be asked for your user email and password, which you'll have received when you purchased Thread Validator or subsequent update email.

Once the update has downloaded, Thread Validator will close, run the installer, and restart.

You can stop the download at any time, if necessary.

·Don't download instructionStep Doesn't download, but you'll be prompted for it again next time you start Thread Validator

·Skip this version instructionStep Doesn't download the update and doesn't bother you again until there's an even newer update

·Software update options... instructionStep edit the software update schedule

·Manage software maintenance... instructionStep opens your browser ready for maintenance renewal

Problems downloading or installing?

If for whatever reason, automatic download and installation fails to complete:

·Log in to https://www.softwareverify.com/authdownload.php externalLink with the details provided when you purchased Thread Validator

·Download the latest installer manually, via one of the .exe, .xyz or .zip files that are available

Make some checks for possible scenarios where files may be locked by Thread Validator as follows:

·Ensure any open sessions are completed

·Ensure any target programs started by Thread Validator are closed

·Ensure Thread Validator and its help manual is also closed

·Ensure any error dialogs from the previous installation are closed

Have your license details handy as you may need to copy information into the license dialog

You should now be ready to run the new version.

Software maintenance expiry

If the software maintenance period has expired you won't be able to automatically update Thread Validator as above.

Instead, you'll see the software update maintenance expiry dialog:

You can manage your software maintenance or choose to stop receiving any more software updates.

Software update schedule

Thread Validator can automatically check to see if a new version of Thread Validator is available for downloading.

menu Software Updates menu instructionStep Configure software updates instructionStep shows the software update schedule dialog

The update options are:

·never check for updates

·check daily (the default)

·check weekly

·check monthly

The most recent check for updates is shown at the bottom.

Managing software maintenance

menu Software Updates menu instructionStep Renew software updates instructionStep shows the Software update maintenance renewal dialog

·Renew software maintenance instructionStep Opens your browser, logging you in to our website externalLink from which you can purchase maintenance

Your maintenance expiry date is shown. If you don't need to do anything just Close the dialog.

Managing software update credentials

You can configure your software update credentials within the application.

menu Software Updates menu instructionStep Set software update credentials instructionStep shows the Software update login details dialog

The text will be shown in red if the email address looks incorrectly formatted.

Testing the login details checks they're valid:

·Test login details instructionStep check your entered details are valid (requires an internet connection)

Valid details will be confirmed:

Invalid details may mean you entered credentials for another application in the Validator suite, or they could have been entered incorrectly.

You should have received the correct credentials when you purchased Thread Validator, or with any software update emails.

If you experience problems, check with your system administrator or contact Software Verify.

If you need to clear the update credentials, you can do this directly from the menu.

menu Software Updates menu instructionStep Reset software update credentials instructionStep clears the email and password details stored in the application

You will be asked to confirm the reset. After resetting the credentials, no software updates will occur.

If you later need to restore your credentials, you should have received that information when you purchased Thread Validator, or with any software update emails.

Software update directory

It’s important to be able to specify where software updates are downloaded to because of potential security risks that may arise from allowing the TMP directory to be executable. For example, to counteract security threats it's possible that account ownership permissions or antivirus software blocks program execution directly from the TMP directory.

The TMP directory is the default location but if for whatever reason you're not comfortable with that, you can specify your preferred download directory. This allows you to set permissions for TMP to deny execute privileges if you wish.

menu Software Updates menu instructionStep Set software update directory instructionStep shows the Software update download directory dialog

An invalid directory will show the path in red and will not be accepted until a valid folder is entered.

Example reasons for invalid directories include:

·the directory doesn't exist

·the directory doesn't have write privilege (update can't be downloaded)

·the directory doesn't have execute privilege (downloaded update can't be run)

note When modifying the download directory, you should ensure the directory will continue to be valid. Updates may no longer occur if the download location is later invalidated.

·Reset instructionStep reverts the download location to the user's TMP directory

The default location is c:\users\[username]\AppData\Local\Temp


Sessions: Load, Save, Export, Close

Loading, Saving, Exporting, Closing

Navigation: The User Interface >

Loading, Saving, Exporting, Closing

 Return to chapter overview

Thread Validator allows sessions to be saved so that you can send the session to a colleague or examine the session at a later date. To complement the save capability sessions can be loaded.

Sessions can be exported in HTML and XML formats.

When you have finished working with a session, a session can be closed. The session can be reopened later if so desired.

Working with sessions

Sessions with Thread Validator can be saved to and loaded from a file so that you can:

·share the session with a colleague

·examine the session at a later date

Sessions can be even exported in HTML and XML formats.

You can have multiple sessions open at once.

Closing a session

When you've finished working with a session, it can be closed.

menu File menu instructionStep Close Session... instructionStep closes the session, clearing the displays

Closing a session may happen automatically if you start a new session and the session count limit is 1.

If the maximum session count allows, closed sessions still appear in the Session Manager, where they can be reopened or deleted.


Loading & Saving Sessions

Navigation: The User Interface > Loading, Saving, Exporting, Closing >

Loading & Saving Sessions

 Return to chapter overview

Loading sessions

Load a session using any of the following options.

menu File menu instructionStep Open Session... instructionStep open a previously saved session from file ( *.tvm )

Or click on the Open Session icon on the standard toolbar.

Or use the shortcut:

+ [image] Open session

If you have a limit of one session to be open at a time, any open session will be closed first, otherwise you can open multiple sessions at a time.

Saving sessions

Save a session using any of the following options.

menu File menu instructionStep Save Session... instructionStep saves all the session data to a file ( *.tvm ), prompting for a file name if necessary

menu File menu instructionStep Save As... instructionStep saves the session to a new file

Or click on the Save Session icon on the standard toolbar.

Or use the shortcut:

+ [image] Save session

Unlike exports, there are no options here, as all the session data is saved.


Exporting Sessions

Navigation: The User Interface > Loading, Saving, Exporting, Closing >

Exporting Sessions

 Return to chapter overview

Exporting to HTML or XML

Exporting sessions allows you to use external tools to analyse or view session data for whatever reasons you might need.

You can export to HTML or XML format:

menu File menu instructionStep Export Session... instructionStep Choose HTML Report or XML Report instructionStep shows the Export Session dialog below

Exporting is not saving

You can't import session data.

Use save and load if you want to save session data for loading back into Thread Validator at a later date.

The Export Session dialog

The Export Session dialog looks very similar to the Save Session dialog, except there are more options enabled.

Scope section

Critical sections and waits will be exported automatically. The following additional information is optional

·Allocated/Entered instructionStep object types specified below that have been allocated or entered

·Deallocated/Exited instructionStep object types specified below that have been deallocated or exited from

Type section

Choose what type of data you want to include

·Synchronization instructionStep export synchronization objects

·Handle instructionStep export handles (e.g. notifications)

·Trace instructionStep TRACE() and OutputDebugString() messages

For each type of data

·Include Stack Trace instructionStep includes the relevant stack trace information in the export

Extra Information section

·Detailed Report instructionStep adds Thread ID and timestamp information to the report

·Colour Coded Report instructionStep for HTML reports, exports a coloured HTML table layout

The colour scheme is not configurable.

If you want a custom style, export a detailed XML report and process that to generate the HTML report.

File section

Specify the output destination and format:

·File instructionStep type the filename or Browse to a location

·Format instructionStep set whether exporting HTML or XML

Defaults to the menu option selected, but included here to more easily export one format and then the other.

·Encoding instructionStep set whether UTF-16 LE, UTF-8 or ASCII encoding. By default the exported file is saved in the Windows Unicode format UTF-16 little endian. You can also save in UTF-8 and ASCII. ASCII has no byte order mark at the start of the file.

·OK instructionStep exports the session data

Check the overwrite existing file option if you want to be warned about overwrites.


XML Export Tags

Navigation: The User Interface > Loading, Saving, Exporting, Closing > Exporting Sessions >

XML Export Tags

 Return to chapter overview

This section describes the XML tags used to export session data from Thread Validator.

Application and program details

An exported XML file starts with a few details about Thread Validator and the target program:

<XML>

<VALIDATORINFO>Thread Validator information online</VALIDATORINFO>
<VALIDATOR>Thread Validator name</VALIDATOR>
<VALIDATORVERSION>Version</VALIDATORVERSION>
<VALIDATORDATE>Build date</VALIDATORDATE>
<VALIDATORTIME>Build time</VALIDATORTIME>
<TITLE>Target program name</TITLE>
<EXITCODE>Program exit status code and description - if collected</EXITCODE>

Thread and Lock information

Thread and lock information is listing the following tag pairs:

<LOCK_DATA>...</LOCK_DATA>

Example lock data might be as follows:

<LOCK>
<CRITICAL_SECTION>0x0b22194c</CRITICAL_SECTION>
<ENTERED>388</ENTERED>
<RECURSE>0</RECURSE>
<CONTENDED>0</CONTENDED>
<CONTENDRATIO>0.00%</CONTENDRATIO>

<SEQUENCE>7,746,320</SEQUENCE>
<THREAD>9632</THREAD>
<STATUS>StateWait(DelayExecution)</STATUS>
<CALLSTACK>
<ENTRY>0x620c4667 mfc90ud.dll CCriticalSection::Lock : [f:\dd\vctools\vc7libs\ship\atlmfc\include\afxmt.inl Line 80]</ENTRY>
<ENTRY>0x00405551 nativeExample.exe CTeststakView::threadProc1 : [c:\program files (x86)\software verification\c++ thread validator\examples\nativeExample\testsvw.cpp Line 688]</ENTRY>
<ENTRY>0x1004bb09 svlthreadvalidatorstub.dll svl_setIgnoreGetProcAddress</ENTRY>
<ENTRY>0x757c38ef KERNEL32.DLL BaseThreadInitThunk</ENTRY>
<ENTRY>0x77275dde ntdll.dll RtlUnicodeStringToInteger</ENTRY>
<ENTRY>0x77275dde ntdll.dll RtlUnicodeStringToInteger</ENTRY>
</CALLSTACK>
<LOCATION>0x620c466c : f:\dd\vctools\vc7libs\ship\atlmfc\include\afxmt.inl Line 81</LOCATION>

</LOCK>

Lock data may contain the following:

·<OBJECT>Handle of waited object</OBJECT>

·<TIMEOUT>Infinite</TIMEOUT>

·<TIMEOUT>Timeout in milliseconds</TIMEOUT>

·<WAITING>Number of waiting processor cycles</WAITING>

·<THREAD>Thread id</THREAD>

·<STATUS>Thread status</STATUS>

·<LOCATION>Source code line where object was allocated, locked or waiting</LOCATION>

·<CALLSTACK>List of <ENTRY></ENTRY> tag pairs</CALLSTACK>

·<ENTRY>Callstack entry</ENTRY>

·<NUM_HANDLES>Number of handles waited for a multiple wait</NUM_HANDLES>

·<OBJECTS>List of <OBJ></OBJ> tag pairs</OBJECTS>

·<OBJ>Object handle</OBJ>

·<CRITICAL_SECTION>Critical section address</CRITICAL_SECTION>

·<ENTERED>Entered count</ENTERED>

·<RECURSE>Recursion count</RECURSE>

·<CONTENDED>Contended count</CONTENDED>

·<CONTENDRATIO>Contention ratio (contention vs entered)</CONTENDRATIO>

·<THREAD_WAITING>Number of waiting threads</THREAD_WAITING>

Not all of these tags will appear for a given data item in a session. Some of them only appear when certain data items are monitored using Thread Validator.

Depending on how you use Thread Validator you may in fact never see some of these tags.

All hexadecimal numbers will have leading zeros, e.g. 0x620c4667.

Allocation types

Allocated/entered, deallocated/exited objects are listed in one of two containers

<ALLOCATED>...</ALLOCATED>
<FREE>...</FREE>

Allocation events

The next level of tags are shown in optional <EVENT> tags.

<EVENT>...</EVENT>

Here's an example for a detailed report. The non-detailed report excludes thread and timestamp entries:

<EVENT>
<ID>82</ID>
<THREAD>7068</THREAD>
<TIME>18508531</TIME>
<File>c:\program files (x86)\software verification\c++ thread validator\examples\nativeexample\examples\testsvw.cpp</File>
<Line>226</Line>
<Synchronization>CriticalSection</Synchronization>
<STACKTRACE>
<SYMBOL>0x00402d1d nativeExample.exe CTeststakView::CTeststakView : [c:\program files (x86)\software verification\c++ thread validator\examples\nativeExample\testsvw.cpp Line 226]</SYMBOL>
<SYMBOL>0x004025a7 nativeExample.exe CTeststakView::CreateObject : [c:\program files (x86)\software verification\c++ thread validator\examples\nativeExample\testsvw.cpp Line 53]</SYMBOL>
<SYMBOL>0x6242b6a7 mfc90ud.dll CRuntimeClass::CreateObject : [f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\objcore.cpp Line 142]</SYMBOL>
<SYMBOL>0x620d3ece mfc90ud.dll CFrameWnd::CreateView : [f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\winfrm.cpp Line 627]</SYMBOL>
<SYMBOL>0x620d4003 mfc90ud.dll CFrameWnd::OnCreateClient : [f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\winfrm.cpp Line 659]</SYMBOL>
<SYMBOL>0x620d40c4 mfc90ud.dll CFrameWnd::OnCreateHelper : [f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\winfrm.cpp Line 678]</SYMBOL>
<SYMBOL>0x620d4073 mfc90ud.dll CFrameWnd::OnCreate : [f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\winfrm.cpp Line 669]</SYMBOL>
<SYMBOL>0x620c9337 mfc90ud.dll CWnd::OnWndMsg : [f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\wincore.cpp Line 2014]</SYMBOL>
</STACKTRACE>
</EVENT>

For allocated handles rather than synchronization objects you may see handle information instead

<Handle>0x6FCB0000</Handle>
<HandleType>Notification</HandleType>

Event data may have the following, in addition to the <STACKTRACE> tags in the next section:

·<ID>the sequence number of the event in the recorded history of all events <ID>

·<File>the source file location of the allocation event <File>

·<Line>the source line number in the file <Line>

·<Type>a string indicating the datatype of the allocated object, if known <Type>

·<Handle>the value of the allocated handle <Handle>

·<HandleType>the type of handle allocated, if known <HandleType>

·<Synchronization>the type of synchronization object <Synchronization>

·<THREAD>the id of the thread in which the allocation was made (shown as a decimal value) <THREAD>

·<TIME>the timestamp of the allocation <TIME>

This is a relative 'ticker' time rather than an absolute time, and is not measured in hours/mins/secs.

·<ReportType>type of trace message <ReportType>

·<Message>a message from a TRACE() macro or OutputDebugString() <Message>

Not all of these event tags will appear for a given allocation in a session. Some of them only appear when certain data items are monitored using Thread Validator.

As with the lock data you may never see some of these tags, depending on how you use Thread Validator .

Any hexadecimal numbers will have a leading 0x....

Stacktrace tags

The stacktrace for the event is defined in the tags

<STACKTRACE>...</STACKTRACE>

In the stacktrace are a number of symbols

<SYMBOL>symbol data</SYMBOL>

The symbol data includes:

·hexadecimal address

·dll/exe name terminated by a semi-colon

·function name

·filename and line number in square brackets, if known

Example (from the XML fragment above):

<SYMBOL>0x00402d1d nativeExample.exe CTeststakView::CTeststakView : [c:\program files (x86)\software verification\c++ thread validator\examples\nativeExample\testsvw.cpp Line 226]</SYMBOL>

Error conditions

The presence of any of the following tags indicate an error condition:

·<DEADLOCKED/>

·<POTENTIAL_DEADLOCK/>

·<EXIT_OUT_OF_ORDER/>

·<NOT_ENTERED/>

·<MISC_ERROR/>


Starting your target program

Navigation: The User Interface >

Starting your target program

 Return to chapter overview

Starting options

There are seven ways to start a target program and have Thread Validator collect data from it.

· Launch your program in a specified directory, with as many command line arguments as you want

· Inject Thread Validator into an already running program

· Wait until a specific program starts to run before attaching to it - e.g. for programs started as an OLE server

· Monitor a service

· Monitor IIS and ISAPI

·Use the Native API to start Thread Validator from code that you control

·Start Thread Validator from the command line, allowing you to automate your use of Thread Validator

Modules without PDB files and without MAP files

For your application to be processed for thread data, each module to be monitored must have a PDB file with debug data, or a MAP file with line number data.

Use the Debug DLLs dialog to see whether debug information was not found for any modules, and check the Diagnostics tab for failure messages.


Launching the program

Navigation: The User Interface > Starting your target program >

Launching the program

 Return to chapter overview

Launching the application

Having Thread Validator launch your program is the most common way to start up

When you're ready to start running a target program:

menu File menu instructionStep Start Application... instructionStep Shows the launch program wizard or dialog below

Or click on the launch icon on the session toolbar.

Or use the shortcut:

Start application

seeAlso You can easily re-launch the most recently run program.

User interface mode

There are two interface modes used while starting a program

·Wizard mode guides you through the tasks in a linear fashion

·Dialog mode has all options contained in a single dialog

All the options are the same - just in different places.

In this section we'll cover the Wizard mode first and the Dialog mode later.

The start application wizard

On first use, the wizard appears with fields cleared, but here's an example with a few fields set:

Enter the details for your program, or if you want to run a previous program select it from the application list to repopulate the details.

After entering the details click Next >> for the next page of the wizard.

Administrator privileges when launching your program

The following applies only if you did not start Thread Validator in administrator mode.

Anywhere you see the admin-priv-icon icon indicates that administrator privileges will be required to proceed.

If you started Thread Validator in administrator mode, you won't see any of these warnings, and everything will behave as normal.

Page 1: Entering details

·Application to start instructionStep type or Browse to set the program name to launch

You can also choose a batch file and the first executable started in the batch file will be launched.

You can also choose a powershell script and the first executable started in the powershell script will be launched.

Manually typing a path will show red text until a valid path is entered, after which the text becomes black.

·Application to monitor instructionStep choose the application that actually gets monitored

This will typically just be the program that you set to start - unless otherwise specified.

Alternatively you can monitor another application which will get launched by the start program.

If the start application has already been added to the Applications to Monitor settings with a default application then that default will be entered here automatically.

Otherwise, if nothing has been set up yet, you can do it from here:

·Edit... instructionStep set the child applications that can be monitored for the start program

This uses the Applications to Monitor dialog - which is exactly equivalent to using the Applications to Monitor settings page.

A fallback option is to start monitoring <<Any application that is launched>>.

note If in doubt, just use the same as the start application.

seeAlso See also: Application to Monitor settings

·Launch Count instructionStep when monitoring a child application, set its nth invocation as the one to monitor

If the application to start is the same as the application to monitor then this is set to 1 and cannot be changed.

This will be reset to 1 every time the Application to Monitor field selection changes.

note If in doubt, leave it set to 1.

seeAlso See also: Launch Count.

·Command Line Arguments instructionStep enter program arguments exactly as passed to the target program

·Startup Directory instructionStep enter or click Dir... to set the directory for the program to start in

When setting your target program, this will default to the location of the executable

Manually typing a directory path will show red text until a valid path is entered, after which the text becomes black.

·Environment Variables instructionStep click Edit... to set any additional environment variables before your program starts

These are managed in the Environment Variables Dialog.

·File to supply to stdin instructionStep optionally enter or Browse to set a file to be read and piped to the standard input of the application

·File to supply to stdout instructionStep optionally enter or Browse to set a file to be written with data piped from the standard output of the application

Page 1: Using details from a previous run

The list at the bottom of the wizard shows previously run programs.

Selecting an item in the list populates all the details above as used on the last run for that program.

You can still edit those details before starting.

·Full path instructionStep shows the full path to the executable in the list

·Image Name instructionStep shows the short program name without path

·Delete instructionStep removes a selected program from the list

·Reset instructionStep clears all details in the wizard - including the list of previously run applications below

The Admin column in the list of previous runs may show a admin-priv-icon symbol to indicate a requirement for administrator privileges in order to run the program. This is automatically detected from the program's manifest externalLink.

Page 2: Data collection

·Collect data from application instructionStep if it's the startup threads you want to monitor, then obviously start collecting data from launch

seeAlso See the section on controlling data collection for how to turn collection on and off after launch.

·Redirect standard output instructionStep Controls redirection of stdout and stderr

Use this option if you want to collect the output of stdout and stderr for later analysis.

Be aware that if the output of the program under test generates a lot of data via stdout or stderr that this data will need to be stored in memory and could exhaust Coverage Validator's memory.

·Display command prompt instructionStep Shows or hides the launched application.

If you are collecting stdout and stderr you may not be interested in viewing the application (or the command prompt if it is a console application). This provides you the option to hide the application when it is running.

Be aware that if you hide a command prompt you will not be able to type anything into the application.

Page 3: Summary and starting your program

The last page is just a summary of the options you have chosen.

note Something missing? The choice of launch method is no longer necessary and has been removed.

If you're happy with the settings, go ahead:

·Start Application... instructionStep start your program and attach Thread Validator to it

·Cmd Line... instructionStep display the command line builder

Administrator privileges in wizard mode

If administrator privileges are required you'll be reminded of the need to restart here:

·Start Application... instructionStep shows the Administrator Privileges Required confirmation dialog before restarting

Dialog mode

In Dialog mode, all the settings are in one dialog which looks very much like the first page of the launch wizard above.

At the top are the options to collect line times and to start collecting data immediately.

·Launch instructionStep start your program and attach Thread Validator to it

·Cmd Line... instructionStep display the command line builder

Double clicking a program in the list will also start it immediately.

Administrator privileges in dialog mode

If administrator privileges are required, the Launch button will show the privileges icon reminding you of the need to restart.

·Launch instructionStep shows the Administrator Privileges Required confirmation dialog before restarting.

If you started Thread Validator in administrator mode, you won't see any of these warnings, and everything will behave as normal.

How do I use Application to Monitor and Launch Count?

The three fields Application to Start, Application to Monitor and Launch Count work together to control which application actually gets monitored by Thread Validator.

By example, let's say we have a program P.

In the simplest case, set options as follows:

·start P

·monitor P

·the Launch Count defaults to 1 and cannot be changed.

If P launches an application and you just want to monitor whatever that is:

·start P

·monitor <<Any application that is launched>>

·leave the Launch Count at 1

If P launches an application A and maybe others as well, and you specifically want to monitor only A as it's launched:

·use the Application to Monitor settings to add a definition for P and child applications A

·start P

·monitor A

·leave the Launch Count at 1

If P launches an application A many times and you specifically want to monitor the third invocation:

·use the Application to Monitor settings to add a definition for P and child applications A

·start P

·monitor A

·set the Launch Count to 3


Re-Launching the program

Navigation: The User Interface > Starting your target program >

Re-Launching the program

 Return to chapter overview

Re-launching the application

It's very easy to start another session using the most recently run program and settings:

menu File menu instructionStep Re-Start Application... instructionStep starts the most recently launched program

Or click on the re-launch icon on the session toolbar.

Or use the shortcut:

Re-start application

No wizards or dialogs appear, so be ready for the application to start right away.

seeAlso For troubleshooting launch problems, see Why might Inject or Launch fail? in the general questions .

There is no difference between wizard and dialog interface mode when re-launching.


Injecting into a running program

Navigation: The User Interface > Starting your target program >

Injecting into a running program

 Return to chapter overview

Injecting into a running program

Thread Validator attaches to a running process by injecting the stub into the process so it can start collecting data.

Choose one of these methods of starting the injection:

menu File menu instructionStep Inject... instructionStep shows the Attach to Running Process wizard or dialog below

Or click on the Inject icon on the session toolbar.

Or use the shortcut

Inject into running application

Administrator privileges

The following applies only if you did not start Thread Validator in administrator mode.

When choosing the inject method described in this topic, a restart of Thread Validator with administrator privileges will be required to proceed.

Injecting into a service?

If your process is a service, Thread Validator won't be able to attach to it.

Services can't have process handles opened by third party applications, even with Administrator privileges.

In order to work with services, you can use the NT service API and monitor the service

You may see this warning dialog when trying to inject into a service:

User interface mode

There are two interface modes used while starting a program

·Wizard mode guides you through the tasks in a linear fashion

·Dialog mode has all options contained in a single dialog

All the options are the same - just in slightly different places

In this section we'll cover the Wizard mode first and the Dialog mode later.

The attach to running process wizard

The first page of the wizard shows a list of running system and user processes.

The list shows the following information:

·ID instructionStep The process ID

·Admin instructionStep may show a admin-priv-icon symbol to indicate a requirement for administrator privileges in order to run the program.

This requirement is automatically detected from the manifest externalLink for the process.

·Process instructionStep The process executable name

Choose a process before continuing:

·Next >> instructionStep move to the next page of the wizard

The button will show the admin-priv-icon symbol if you have selected a process which requires elevated privileges to run.

Page 1: Choosing the process

·System processes / Services / User processes instructionStep show any or all of services and system or user processes in the list

·Full path instructionStep shows the full path to the process executable in the list

·Image Name instructionStep shows the short program name without path

·Refresh instructionStep update the list with currently running processes

Clicking on the headers of the list will sort them by ID or by name using the full name or short name, depending on what's displayed.

Page 2: Data collection

The second page controls when to start collecting information.

Depending on your application, and what you want to test, you may want to start collecting data as soon as injection happens, or do it later.

If your program has a complex start-up procedure, initialising lots of data, it may be much faster not to collect data until the program has launched.

·Collect data from application instructionStep if it's the startup Thread you want to monitor, then obviously start collecting data from launch

seeAlso See the section on controlling data collection for how to turn collection on and off after launch.

Summary and starting your program

The second page also confirms at the top which process you have selected to inject into, and prompts you to attach:

·Attach... instructionStep injects Thread Validator into the specified process, showing progress status

The button will show the admin-priv-icon symbol if you have selected a process which requires elevated privileges to run.

seeAlso In the general questions see Why might Inject or Launch fail? for troubleshooting launch problems.

Dialog mode

In Dialog mode, all the settings are in one dialog but which still looks similar to the first page of the wizard above.

The option of when to start collecting data, and whether to collect function and line times is at the top, as is the Attach... button itself.


Waiting for a program

Navigation: The User Interface > Starting your target program >

Waiting for a program

 Return to chapter overview

Waiting for a program

Waiting for a program is essentially the same as injection except that instead of injecting into a running program, Thread Validator watches for the process starting up and then injects.

note If the process is a service, Thread Validator won't be able to attach to it as services can't have process handles opened by third party applications, even with Administrator privileges.

Wait for Application can be accessed by one of these methods:

menu File menu instructionStep Wait for Application... instructionStep shows the Wait for application wizard or dialog below

Or click on the Wait (timer) icon on the session toolbar.

Or use the shortcut:

Wait for application

Administrator privileges

The following applies only if you did not start Thread Validator in administrator mode.

When choosing the 'wait for program' method described in this topic, a restart of Thread Validator with administrator privileges will be required to proceed.

This is the case whether you are in Wizard or Dialog user interface mode.

Waiting for a service?

If your process is a service, Thread Validator won't be able to attach to it.

Services can't have process handles opened by third party applications, even with Administrator privileges.

In order to work with services, you can use the NT service API and monitor the service

User interface mode

There are two interface modes used while starting a program:

·Wizard mode guides you through the tasks in a linear fashion

·Dialog mode has all options contained in a single dialog

All the options are the same - just located in slightly different places.

In this section we'll cover the Wizard mode first and the Dialog mode later.

The wait for application wizard

The first page of the wizard lets you specify the application or choose one that you've waited for previously.

Choose the process and click Next >> for the next page of the wizard.

Page 1: Choosing the process

·Application to wait for instructionStep type or Browse to set the application name to launch

·Full path instructionStep shows the full path to the process executable in the list

·Image Name instructionStep shows the short program name without path

·Reset instructionStep clears the list

Page 2: Data collection

The second page controls when to start collecting information.

Depending on your application, and what you want to test, you may want to start collecting data as soon as injection has happened, or do it later.

If your program has a complex start-up procedure, initialising lots of data, it may be much faster not to collect data until the program has launched.

·Collect data from application instructionStep if it's the startup Thread you want to monitor, then obviously start collecting data from launch

seeAlso See the section on controlling data collection for how to turn collection on and off after launch.

Summary and starting your program

The second page confirms the application and prompts you to start waiting:

·Wait for Process... instructionStep starts waiting and then injects Thread Validator into the specified process, showing progress status

The button changes to show Stop Waiting. Click this to abandon the wait.

What could go wrong?

The program you're waiting for might already be running, in which case you'll be given the option to cancel or attach to the existing process:

Timing issues are inherit with injecting into a program as it starts up.

This could cause the injection to fail in unpredictable ways and you may see dialogs like that below:

One case when this dialog can occur is if the program needs to run at an elevated privilege and is waiting for the user to give permission via the UAC dialog.

Injection may fail for different reasons and you might see the following information dialog showing:

·messages relating to the specific failure

·a selection of reasons why failure might be occurring

·some possible solutions to the problem

Sometimes retrying a few times might catch a better moment for attaching to the process.

seeAlso In the general questions see Why might Inject or Launch fail? for troubleshooting launch problems.

Dialog mode

In Dialog mode, all the settings are in one dialog which looks similar to the first page of the wizard above.

The option of when to start collecting data, and whether to collect function and line times is at the top, as is the Wait For Process button


Monitor a service

Navigation: The User Interface > Starting your target program >

Monitor a service

 Return to chapter overview

Monitoring a service

Monitoring a service works for:

·Native services

·.Net services

·Mixed mode services.

Native Services

If you're working with native services you must use the NT Service API in your service as well as using the Monitor a service method below.

.Net Services

Thread Validator won't attach until some .Net code is executed.

If there is native code being called prior to the .Net code, Thread Validator won't monitor that code, only the native code called after the first .Net code that is called.

To monitor any native code called prior to your .Net code, use the NT Service API.

Mixed Mode .Net Services

You don't need to use the NT Services API.

If you are working with a .Net service that loads native DLLs, or a mixed mode service, Thread Validator will recognize the service when the .Net runtime starts executing the .Net service main.

note When working with Thread Validator and services, you still start the service the way you normally do - e.g. with the service control manager.

The code that you have embedded into your service then contacts Thread Validator, which you should have running before starting the service.

To start monitoring a service:

menu File menu instructionStep Monitor a service... instructionStep shows the Monitor a service dialog below

or use the shortcut

Monitor a service

The monitor a service dialog

First ensure the service is installed, but not running.

Set the service to monitor, choose whether to start collecting data right away, and click OK.

·Service to monitor instructionStep type or Browse to set the service name to monitor

·OK instructionStep performs some brief setup work and then prompts you to start the service

Click OK to close the dialog and then start your native service or .Net service.

Start the service in the normal manner, e.g. from the control panel, the command line or programmatically.

Data collection

Depending on your application, and what you want to validate, you may want to start collecting data as soon as injection has happened, or do it later.

If your program has a complex start-up procedure, initialising lots of data, it may be much faster not to collect data until the program has launched.

If it's the startup procedure you want to validate, obviously start collecting data immediately.

seeAlso See the section on controlling data collection for how to turn collection on and off after launch.

Examples

Example demonstrating how to monitor a service.

Example demonstrating how to monitor an application launched from a service (how to monitor any application running on a service account).


IIS

Navigation: The User Interface > Starting your target program >

IIS

 Return to chapter overview

Enter topic text here.


Monitor IIS and ISAPI

Navigation: The User Interface > Starting your target program > IIS >

Monitor IIS and ISAPI

 Return to chapter overview

Monitoring ISAPI

Monitoring ISAPI works for:

·Native ISAPI extensions.

Native ISAPI

If you are working with native ISAPI you must use the NT Service API in your service as well as using the Monitor ISAPI method below.

To start monitoring ISAPI:

menu Launch menu instructionStep IIS menu instructionStep Monitor IIS and ISAPI... instructionStep shows the Monitor ISAPI dialog below

or use the shortcut

Monitor IIS and ISAPI

The monitor ISAPI dialog

Set the dll to monitor, the web root, the IIS process, an optional web browser to use and an optional url to launch, and click OK.

·ISAPI DLL instructionStep type or Browse to set the ISAPI DLL that we're monitoring

·IIS web instructionStep type or Browse to set the web root for the IIS website we're working with

·IIS process to monitor instructionStep select the IIS process we're working with

·Web Browser instructionStep select the web browser that you're going to use to load the web page

·URL to open in browser instructionStep type the web page and arguments you want to load to cause the ISAPI to be loaded in IIS

·OK instructionStep resets IIS, setups all the variables, copies DLLs and settings into the web root and starts the web browser to load the specified web page

menu IIS is a protected process and can only execute, read and write files in specific directories. That's why Thread Validator copies data to the web root so that it can be read, written or executed.

Data collection

Depending on your application, and what you want to validate, you may want to start collecting data as soon as injection has happened, or do it later.

If your program has a complex start-up procedure, initialising lots of data, it may be much faster not to collect data until the program has launched.

If it's the startup procedure you want to validate, obviously start collecting data immediately.

seeAlso See the section on controlling data collection for how to turn collection on and off after launch.


Reset & Stop IIS

Navigation: The User Interface > Starting your target program > IIS >

Reset & Stop IIS

 Return to chapter overview

Reseting IIS

menu Launch menu instructionStep IIS menu instructionStep Reset IIS instructionStep resets Internet Information Server (stops it and starts it again).

The session is not discarded when IIS is reset.

Stopping IIS

menu Launch menu instructionStep IIS menu instructionStep Stop IIS instructionStep stops Internet Information Server.

The session is not discarded when IIS is stopped.


Linking to a program

Navigation: The User Interface > Starting your target program >

Linking to a program

 Return to chapter overview

Why link Thread Validator into your program?

There are cases when you might need to link Thread Validator directly into your program.

Sometimes the normal methods of launching and injecting aren't enough to get the data needed for a particular debugging task.

For example:

·maybe the data to be monitored has already been allocated before the stub was successfully injected

·maybe there is conflict with DLLs or a timing problem stopping the injection process from working as well as normal

These situations are rare, but given the variety of different applications, can happen.

Linking to your program

The library that you need to link to is:

·svlThreadValidatorStubLib.lib for 32 bit

·svlThreadValidatorStubLib_x64.lib for 64 bit

When linked and started, your program will automatically start Thread Validator.

note The libraries should be linked to your program's .exe, not to a DLL that is loaded into your program.


Environment Variables

Navigation: The User Interface > Starting your target program >

Environment Variables

 Return to chapter overview

When launching an application, you might want to pass in some environment variables to your program.

The Environment Variables dialog lets you manage name/value pairs, including importing and exporting for use between programs or sessions.

The Environment Variables dialog

The dialog initially has no entries.

The example below shows the equivalent of set QT_PLUGIN_PATH=%QTDIR%\plugins

·Add... instructionStep adds a new item to the list instructionStep enter name in the first column, value in the second

·Delete instructionStep deletes a selected item in the list

·Delete All instructionStep clears the list

·Acquire instructionStep fetches all system environment variables, adding them to the list

·Import... instructionStep loads variables from a previously exported file, adding them to the list

·Export... instructionStep saves all entries in the list to a file of your choice

The exported file is a simple ascii file with one entry per line of the form name=value

·OK instructionStep accepts all changes

·Cancel instructionStep ignores changes


Stopping your target program

Navigation: The User Interface >

Stopping your target program

 Return to chapter overview

Stopping the application

You can stop or kill your program at any time using the task manager, or debugger.

You can also stop your program from within Thread Validator.

menu File menu instructionStep Abandon Application... instructionStep stop the target program

or click on the red cross icon on the session toolbar.

The target program is ended using ExitProcess() from inside the stub.

Since the session is discarded, using Thread Validator to stop the target program is usually quicker and more convenient than external stop methods.

seeAlso You can easily re-launch the program again using the same settings as before.


Command Line Builder

Navigation: The User Interface >

Command Line Builder

 Return to chapter overview

The command line builder helps you create command lines with valid options.

The command line builder is a two stage process, the first stage helping your choose how you want to build the command line, and the second stage actually building the command line based on the choices in the first stage.

There are five options for building your command line:

·I'll build my own instructionStep you'll build your command line from scratch, with no predefined options

·Use a predefined template instructionStep choose from a list of predefined command lines that you can customize

The predefined templates cover a range of tasks you may want to perform from the command line. These include running sessions, saving sessions, exporting to HTML and XML.

Examples are provided for both Native and .Net applications, and .Net Core applications.

·Use an existing command line instructionStep use the command line you use to start the tool you want to collect profiling data for

Example: e:\dev\paintpot\release\paintpot.exe e:\testimages\venn.png -invert -mirror -phaseChange

·Use an existing Thread Validator command line instructionStep use an existing Thread Validator command line and customize that

Example: -program e:\dev\paintpot\release\paintpot.exe -hideUI -exportAsHTML e:\testResults\gannt.html -allArgs e:\testimages\gantt.png -inflate:3

·Use an existing Thread Validator command file instructionStep use an existing Thread Validator command file and customize that

Example: -commandFile e:\commandFiles\paintpot_gantt.cf

When you have made your choice the Next button moves you to the customization part of the command line builder.

The image above shows the command line builder populated with one of the predefined template choices. You can see a few entries refer to directories and files that do not exist on disk (they are red).

These are items you will need to customize to match the program you are testing.

Any entries that will only exist after they have been created by the test will also be shown in red.

Editing

To edit an argument, double click the argument. A combo box will display a list of valid arguments you can choose.

To edit a value, double the value. If the argument type has a list of known values a combo box will be provided, directories will display a directory chooser, files will display a file chooser, numbers will only allow numeric editing. All other values will be edited as text.

·Add instructionStep add a new argument to the grid

·Remove instructionStep remove the selected item

·Remove All instructionStep removes all items in the grid

·Add Hide instructionStep adds a -hideUI argument which will cause Thread Validator to hidden when running. Thread Validator will close after the target program finishes running

·Add Debug instructionStep adds various arguments which will cause Thread Validator to display error messages if there are problems with the command line.

·Add Export instructionStep adds export options that will cause Thread Validator to export html and/or xml reports after the target program finishes running

·Import... instructionStep you can import a command file, the contents of which will replace all the items in the grid

Command Line Output

There are two command line output styles.

·Command line with arguments instructionStep generates a command line containing all arguments and values shown in the grid

·Command line with command file instructionStep generates a command file containing all arguments and values shown in the grid, and a command line that references the command file

When this option is chosen the command file edit field and the Browse... and View... buttons are enabled, allowing you to specify a command file name, and to view it's contents.

If a command file has not been specified when this option is selected you will be prompted to select a name for the command file.

When the command file name is selected the command file will be created with the arguments and values shown in the grid.

·Copy instructionStep copies the command line to the clipboard so that you can paste the command line in cmd prompts, batch files and automated scripts (Jenkins etc)

·Browse... instructionStep opens a Windows file dialog to allow you to specify the command file location

·View... instructionStep opens the command file using the Windows shell, this allows you to view the command file in your favourite editor

Testing

If you wish to test the command line, you have two options:

·Manual test instructionStep use the Copy button to copy the command line, then paste it into a cmd prompt and press return.

·Test Command Line instructionStep a new instance Thread Validator is started with the specified command line.


Data Collection

Navigation: The User Interface >

Data Collection

 Return to chapter overview

Collecting data

Once you've launched or injected into a program, you can stop and start data collection whilst the program is running.

This is a high level switch that controls all data collection, regardless of any other settings.

With data collection off, the target program runs at close to normal speed.

Temporarily turning off collection can be a good idea if you need to take actions to get the program into the right state for validation.

You can also turn data off from the start and only turn it on when you need it.

Starting and stopping data collection

menu File menu instructionStep Start collecting data... instructionStep starts collecting data immediately

or click on the green icon on the session toolbar to start collecting.

menu File menu instructionStep Stop collecting data... instructionStep stops collecting

or click on the red icon on the session toolbar to stop.


Help

Navigation: The User Interface >

Help

 Return to chapter overview

The help menu

The help menu provides access to useful help, tips and tutorials.

Each item is covered briefly below, in menu order.

interactive

help-menu

Tips

menu Help menu instructionStep Tips... instructionStep shows the tip dialog where you can browse tips in random order

Here you can also choose whether to display the tips dialog while launching programs.

About box

menu Help menu instructionStep About Thread Validator... instructionStep shows contact and copyright information, as well as details of your license

Overview Video

menu Help menu instructionStep Overview Video... instructionStep opens a new dialog showing a short video

The video has sound and does not play automatically.

The video is also available on the product website. Visit https://www.softwareverify.com/products.php and find the product link for Thread Validator.

Read-me and version history

menu Help menu instructionStep Readme... instructionStep opens the readme.html (from your installation) in your browser.

The readme file contains all the latest information about Thread Validator including:

·basic information about getting started and where to go for support

·known issues

·version history

To see what's changed since the version you have installed see the latest version history externalLink.

Help HTML

menu Help menu instructionStep Help topics... instructionStep shows the HTML help dialog

You might be reading this right now!.

Or click on the question mark icon on the standard toolbar:

note The [image] key also shows the help, but has the added bonus of jumping directly to the page relevant for the current view or dialog.

note We occasionally get reports of customers seeing exception errors while viewing the HTML help. Unfortunately, we don't have a solution for this yet, but we'd appreciate knowing which pages are affecting you!

Help PDF

menu Help menu instructionStep Help PDF instructionStep shows the PDF version of this help

You will need a suitable PDF reader such as Adobe Acrobat Reader externalLink, but do beware of unwanted add-on installs.

PDF help for all our products are online externalLink.

Help on softwareverify.com

menu Help menu instructionStep Help on softwareverify.com instructionStep shows the online version of this help externalLink

Blog

menu Help menu instructionStep Blog instructionStep shows the Software Verify Blog externalLink.

Library

menu Help menu instructionStep Library instructionStep shows the Software Verify Library - all our best articles organised into related topics externalLink for easy access.

Tutorials

The tutorials are intended to guide you through learning how to use aspects of Thread Validator.

Latest tutorials are available online externalLink in the form of short videos and examples covering popular topics.

menu Help menu instructionStep Tutorial... instructionStep simply selects the Tutorial tab to show a list of the tutorials

Double click on the row of a tutorial in the list to open it in a browser.

menu Help menu instructionStep Tutorials on softwareverify.com... instructionStep opens the online tutorials externalLink in a browser

Contact customer support

menu Help menu instructionStep Contact customer support instructionStep shows the Contact customer support externalLink dialog.

How do I?

menu Help menu instructionStep How do I? instructionStep shows the How do I? dialog.

Report a crash

menu Help menu instructionStep Report a crash instructionStep displays the options for reporting a crash.

If an exception report for the Thread Validator user interface, or an exception report for an application that Thread Validator was monitoring is available it will be displayed with options to copy it to the clipboard and contact customer support at Software Verify.


Command Line Interface

Navigation: »No topics above this level«

Command Line Interface

 Return to chapter overview

Thread Validator provides a command line interface to allow you to perform automated critical section data collection.

To run 32 bit thread validator run C:\Program Files (x86)\Software Verify\Thread Validator x86\threadValidator.exe

To run 64 bit thread validator run C:\Program Files (x86)\Software Verify\Thread Validator x64\threadValidator_x64.exe

Automated critical section data collection

Potential uses for automated critical section analysis are:

·In the regression test suite to ensure critical section behaviour

·In unit testing to ensure critical section performance of a certain level

·Quality assurance

Results from thread data collection sessions can be merged to form an aggregate result.

Typically, command line options allow Thread Validator to run by specifying:

·the target program to run

·arguments to pass to the target program

·the working directory to run in

·whether to run with or without the user interface

·a baseline session to compare with

·where and how to save results

·what to include or exclude from hooking

·how to merge results

Usually Thread Validator would exit between automated tests, but it can be made to stay running if necessary.

seeAlso See the command line reference for an alphabetical listing all the available commands.

Command line argument usage

There are a few basic rules to remember when using the command line arguments:

·separate arguments by spaces

·quote arguments if they contain spaces

·some arguments are only useful in conjunction with others

·some arguments are incompatible with others

If your command line is very long, consider using -commandFile to specify a command file for your arguments.

Unrecognised arguments

Any unrecognised arguments found on the command line are simply ignored, whether or not they are prefixed with a hyphen.

Arguments intended for your program will not conflict with the Thread Validator arguments in this manual as you should use -arg (or -allArgs) to redirect them to your program.

Need some help building the command line?

If you find creating command lines from nothing to be a bit daunting we've created a Command Line Builder tool to help you build command lines.

You'll still need to complete some details, but the builder will help prevent you making some mistakes.

Command Lines and Floating Licences

Thread Validator works from the GUI and from the command line with all types of software licence (floating licences and non-floating licences).

When floating licences are being used Thread Validator will wait to acquire a floating licence before proceeding to process the command line options.

There are no options to:

·Checkout a floating licence

·Release a floating licence

·Query for available licences

These options are managed automatically by Thread Validator, there is no need for such options to be manually controlled from the command line.


Example Command Lines

Navigation: Command Line Interface >

Example Command Lines

 Return to chapter overview

Typical command line examples

The following examples demonstrate a few different scenarios in which you might want to use Thread Validator via the command line.

To run 32 bit thread validator run C:\Program Files (x86)\Software Verify\Thread Validator x86\threadValidator.exe

To run 64 bit thread validator run C:\Program Files (x86)\Software Verify\Thread Validator x64\threadValidator_x64.exe

Example 1 - running a session and saving the results

This example starts the application, showing no progress dialog whilst attaching to the process.

On completion, the resulting session is saved, and some tabs are refreshed.

The last tab refreshed is displayed, resulting in the ActiveObjects tab being the current tab.

threadValidator_x64.exe -program "c:\myProgram.exe" -saveSession "c:\myResults\session1.tvm_x64" -displayUI -refreshSummary -refreshLocks -refreshActiveObjects

A brief explanation of each argument:

Option | Argument | Description
-program | "c:\myProgram.exe" | The target program to launch
-saveSession | "c:\myResults\session1.tvm_x64" | After the application finishes, the session should be saved in this file
-displayUI |  | Show the user interface during the thread test
-refreshSummary |  | These tabs should be refreshed when the test completes
-refreshLocks |  |
-refreshActiveObjects |  |

Example 2 - running a session and saving the results and exiting

This example starts the application, showing no progress dialog whilst attaching to the process.

On completion, the resulting session is saved, and Thread Validator exits.

threadValidator_x64.exe -program "c:\myProgram.exe" -saveSession "c:\myResults\session2.tvm_x64" -hideUI

A brief explanation of each argument:

Option | Argument | Description
-program | "c:\myProgram.exe" | The target program to launch
-saveSession | "c:\myResults\session2.tvm_x64" | After the application finishes, the session should be saved in this file
-hideUI |  | Hide the user interface during the thread test and close the user interface after the test application finishes.

Example 3 - running a session and saving and exporting the results

This example starts the application, showing no progress dialog whilst attaching to the process.

On completion, the resulting session is saved, and some tabs are refreshed.

The last tab refreshed is displayed, resulting in the ActiveObjects tab being the current tab.

threadValidator_x64.exe -program "c:\myProgram.exe" -saveSession "c:\myResults\session3.tvm_x64" -exportAsHTML "c:\myResults\session3.html" -displayUI -refreshSummary -refreshLocks -refreshActiveObjects

A brief explanation of each argument:

Option | Argument | Description
-program | "c:\myProgram.exe" | The target program to launch
-saveSession | "c:\myResults\session3.tvm_x64" | After the application finishes, the session should be saved in this file
-exportAsHTML | "c:\myResults\session3.html" | After the application finishes, the exported data should be saved in this file
-displayUI |  | Show the user interface during the thread test
-refreshSummary |  | These tabs should be refreshed when the test completes
-refreshLocks |  |
-refreshActiveObjects |  |


Environment variables

Navigation: Command Line Interface >

Environment variables

 Return to chapter overview

Environment variables can be referenced on the command line.

This allows you to set an environment variable outside of Thread Validator (cmd prompt, batch file, etc) and then reference it on the command line.

For example:

-program %BUILD_DIR%\testProgram.exe

If the BUILD_DIR environment variable is set to e:\dev\debug the above would evaluate to -program e:\dev\debug\testProgram.exe

What if I can't set an environment variable?

There are situations where it isn't desirable, or possible to set the environment variable value prior to starting Thread Validator.

In those situations you can set the environment variable on the command line using -setenvironment.

-setenvironment BUILD_DIR=e:\dev\debug -program %BUILD_DIR%\testProgram.exe

Problems with environment variable substitution

If you are running from a command prompt, or batch file, or any process that will handle environment variable substitution using %ENV_VAR% you will find that referencing the environment variable on the command line won't work when using -setenvironment, because by the time Thread Validator sees the command line the %ENV_VAR% values have already been substituted.

To get around this, using $ENV_VAR$ instead of %ENV_VAR%.

-setenvironment BUILD_DIR=e:\dev\debug -program $BUILD_DIR$\testProgram.exe

-setenvironment

Set environment variables for Thread Validator, as a series of name/value pairs.

Use this option once for each environment variable you wish to set.

Usage of -setenvironment for any environment variable must appear on the command line prior to any reference to that environment variable on the command line.

note To pass quotes along with the string, escape a pair of inner quotes like the example below

Examples:

-setenvironment APP_FLAG=ON;

-setenvironment "APP_FAG=ON;"

-setenvironment "APP_COMMS=ON; APP_DEBUG=OFF;"
-setenvironment "APP_MSG=\"A quoted string with spaces\";"

-setenvironment BUILD_DIR=e:\dev\debug

Note that this is not the same as -environment, which allows you to specify environment values that you can pass to the program being launched.


Target Program & Start Modes

Navigation: Command Line Interface >

Target Program & Start Modes

 Return to chapter overview

Resetting global settings

-resetSettings

Forces Thread Validator to reset all settings to the default state, except for any configured colours and the UI Global Hook settings which must be reset manually.

note If using this option, it's recommended that you list this first on your command line or in your command file.

Specifying the target application

The following options let you launch a program (with various start-up modes), inject into a running program or wait for a program to start before attaching.

Launching a program

-program

Specifies the full file system path of the executable target program to be started by Thread Validator, including any extension.

Not compatible with -injectName, -injectID, -waitName or -monitorAService.

See - arg below to pass arguments to your program, and -directory to set where it runs.

Examples:

-program c:\testbed.exe

-program "c:\new compiler\version2\testbed.exe"

If you specify the file without a path then:

·If you used -directory to set a startup directory then the filename in that directory is used if it exists

·Otherwise, the directories in the PATH environment variable are used to look for the filename

-programToMonitorEXE

-programToMonitor

-programToMonitor has been replaced by -programToMonitorEXE. -programToMonitor will be honoured to provided backward compatibility.

Specifies the full path of the program from which the data is collected, but does not change which process is initially launched. Include the extension.

This program will be monitored by Thread Validator only when the program specified using -program starts it.

If no path is specified, the first child process that has the same name will be monitored.

To monitor any program that is launched specify <<Any>> as the program argument. In batch files and powershell scripts you will need to quote this to get it accepted by the file parser.

See -programToMonitorLaunchCount to change which instance of the program is monitored.

Only valid in conjunction with -program.

Examples:

-programToMonitorEXE c:\testbed-child-process.exe

-programToMonitorEXE "c:\new compiler\version2\testbedChildProcess.exe"

-programToMonitorEXE testbed-child-process.exe

-programToMonitorEXE "<<Any>>"

-program c:\testbed.exe -programToMonitorEXE c:\testbed-child-process.exe

In this last example c:\testbed.exe is launched but not monitored. Only when testbed.exe launches a child process c:\testbed-child-process.exe is that child process monitored.

-programToMonitorDLL

This option provides a qualifying DLL to identify different .Net Core processes, which are typically launched using the same .Net Core runtime. Include the dll extension.

Only valid in conjunction with -program and -programToMonitorEXE.

Examples:

-programToMonitorDLL c:\test\dotNetCoreApp.dll

-program c:\testbed.exe -programToMonitorEXE "c:\program files\dotnet\dotnet.exe" -programToMonitorDLL c:\test\dotNetCoreApp.dll

In this last example c:\testbed.exe is launched but not monitored. Only when testbed.exe launches a child process c:\program files\dotnet\dotnet.exe to run the application c:\test\dotNetCoreApp.dll is that child process monitored.

-programToMonitorLaunchCount

Specify the nth invocation of the child program specified by -programToMonitor which is to have its data collected.

Any value which is invalid (including anything less than 1) will default to 1.

Only valid in conjunction with -programToMonitor and consequently also -program.

Examples:

-programToMonitorLaunchCount 1

-programToMonitorLaunchCount 34

-program c:\testbed.exe -programToMonitor c:\testbed-child-process.exe -programToMonitorLaunchCount 1

In the above example c:\testbed.exe is launched but not monitored. As soon as testbed.exe launches a child process c:\testbed-child-process.exe then that child process is monitored.

If the value 1 was changed to a 2, then only the second invocation of c:\testbed-child-process.exe would get monitored, with the first invocation being ignored.

-environment

Environment variables for program, as a series of name/value pairs. Not to be confused with -setenvironment.

Use this option once for each environment variable you wish to set.

note To pass quotes along with the string, escape a pair of inner quotes like the example below

Only valid with: -program

Examples:

-environment APP_FLAG=ON;

-environment "APP_FAG=ON;"

-environment "APP_COMMS=ON; APP_DEBUG=OFF;"
-environment "APP_MSG=\"A quoted string with spaces\";"

-arg

Passes the following element on the command line to the target program.

-arg can be used multiple times, or you can use -allArgs

note To pass quotes along with the string, escape a pair of inner quotes like the example below

Only valid with: -program

Examples:

-arg myProgram.exe

-arg "c:\Program Files\myApp\myProgram.exe"

-arg "-in infile -out outfile"
-arg "\"a quoted string\""

-allArgs

Passes the remainder of the command line (after -allArgs) to the program being launched.

Unlike -arg above, there is no need to escape the quotes as the content is passed verbatim.

Only valid with: -program

Example:

-allArgs anything put here is passed to the target program "even stuff in quotes" is passed

-directory

Sets the working directory in which the program is executed. If -directory is not specified the program is run in its current directory.

Only valid with: -program

Examples:

-directory c:\development\

-directory "c:\research and development\"

-stdin

Specifies a file to be read and piped to the standard input of the application being tested.

If the filename contains spaces, the filename should be quoted.

An error occurs if the file does not exist. See -ignoreMissingStdin to avoid this error.

Examples:

-stdin c:\settings\input.txt

-stdin "c:\reg tests settings\input.txt"

-stdout

Specifies a file to be written with data piped from the standard output of the application being tested.

If the filename contains spaces, the filename should be quoted.

An error occurs if the file does not exist. See -ignoreMissingStdout to avoid this error.

Examples:

-stdout c:\settings\output.txt

-stdout "c:\reg tests results\output.txt"

-ignoreMissingStdin

If this flag is specified and the file specified by -stdin does not exist, no error is reported.

-ignoreMissingStdout

If this flag is specified and the file specified by -stdout does not exist, no error is reported.

Injecting into a program

-injectName

Sets the name of the process for Thread Validator to attach to.

Not compatible with -program, -injectID, -waitName or -monitorAService.

Examples:

-injectName c:\testbed.exe

-injectName "c:\new compiler\version2\testbed.exe"

-injectID

Sets the numeric id of a process for Thread Validator to attach to.

Not compatible with -program, -injectName, -waitName or -monitorAService.

Example:

-injectID 1032

Waiting for a program

-waitNameEXE

-waitName

-waitName has been replaced by -waitNameEXE. -waitName will be honoured to provided backwards compatibility.

Sets the name of a process that Thread Validator will wait for.

When the named process starts Thread Validator will attach to the process.

Not compatible with -program, -injectName, -injectID or -monitorAService.

Examples:

-waitNameEXE c:\testbed.exe

-waitNameEXE "c:\new compiler\version2\testbed.exe"

-waitNameDLL

Sets the name of a process DLL that Thread Validator will wait for.

When the named process starts Thread Validator will attach to the process.

Examples:

-waitNameDLL c:\dotNetApp.dll

-waitNameDLL "c:\new compiler\version2\dotNetApp.dll"

For use with -waitNameEXE when you want to wait for .Net Core applications.

-waitNameEXE "c:\program files\dotnet\dotnet.exe" -waitNameDLL "c:\testApps\dotNetCoreApp\release\dotNetCoreApp.dll"

Monitoring a service

-monitorAService

Sets the full file system path of a service including any extension.

Thread Validator will wait for the service to start and attach to it.

Not compatible with -program, -injectName, -injectID or -waitName.

Examples:

-monitorAService c:\service.exe

-monitorAService "c:\new compiler\version2\service.exe"

Data Collection

-collectData

Enables or disables the collection of flow tracing data

Examples:

-collectData:On

-collectData:Off

-collectStdout

Enables or disables the collection of standard output (stdout)

Examples:

-collectStdout:On

-collectStdout:Off


User interface visibility

Navigation: Command Line Interface >

User interface visibility

 Return to chapter overview

User interface visibility

You can choose to hide or show Thread Validator during the test, as well as the window of the target application.

-displayUI

Forces the Thread Validator user interface to be displayed during the test.

This is useful for debugging a command line session that is not working, for example inspecting the Diagnostic tab for messages related to the test.

You wouldn't normally use this option when running unattended thread tests.

-doNotInteractWithUser

Never display dialog boxes in the target application that is being profiled.

note This applies even for warning and error dialog boxes.

The intended use for this option is for when you are running command line sessions on unattended computers and you have automated processes that may kill the Thread Validator user interface if something goes wrong. Actions such as this then cause the stub to recognise the user interface has gone away and display an error warning.

-hideUI

Hides the Thread Validator user interface during the test.

-launchAppHide

-launchAppHidden (for backwards compatibility only)

Hides the target application during the test.

note Depending on your application, this may not work and may not even be suitable.

This is equivalent to setting the wShowWindow member of the STARTUPINFO struct to SW_HIDE when using the Win32 CreateProcess() function.

It's useful if you're testing console applications that have no user interaction, as it prevents the console/command prompt from being displayed.

For GUI applications this option very much depends on how your application works.

For interactive applications, it clearly has no use, but for some, hiding the GUI may help prevent various windows messages from being processed.

Typically, for complex applications, it's better to design this capability into your application and control it via a command line, which can be passed in from Thread Validator via the -arg option.

-launchAppShow

Shows the target application during the test.

This is equivalent to setting the wShowWindow member of the STARTUPINFO struct to SW_SHOW when using the Win32 CreateProcess() function.

-launchAppShowMaximized

-launchAppShowMinimized

-launchAppShowMinNoActive

-launchAppShowNA

-launchAppShowNoActivate

-launchAppShowNormal

As well as the previous two options to show or hide the target application during the test there are other options equivalent to values that can be used in the STARTUPINFO struct.

The options are equivalent to the setting the wShowWindow member to the following values

Option | wShowWindow member | Launched application is shown...
-launchAppShowMaximized | SW_SHOWMAXIMIZED | Maximized and activated
-launchAppShowMinimized | SW_SHOWMINIMIZED | Minimized and activated
-launchAppShowMinNoActive | SW_SHOWMINNOACTIVE | Minimized and not active
-launchAppShowNA | SW_SHOWNA | Shown at current size and position but not activated
-launchAppShowNoActivate | SW_SHOWNOACTIVATE | Show at most recent size and position but not activated
-launchAppShowNormal | SW_SHOWNORMAL | Show at original size and position and activated

-showCommandPrompt

-hideCommandPrompt

Causes any launched console window to be shown or hidden during the test.

-showErrorsOnCommandPrompt

If an error occurs when launching the application, the error will be reported on the command line.

Refreshing the interface after test completion

You can run automated tests that leave the user interface open after completion,

The following options are used to automatically refresh the main data tabs in Thread Validator once a test is complete.

-refreshSummary

-refreshLocks

-refreshPerThreadLocks

-refreshCurrentLocks

-refreshThreads

-refreshCoverage

-refreshActiveObjects

-refreshAnalysis

-refreshObjects

-refreshWaitChain


Session Management

Navigation: Command Line Interface >

Session Management

 Return to chapter overview

Session management

The following options let you control the sessions during testing

-baseline

Loads a previous session as the baseline session against which the recorded session is compared for regressions or improvements.

Examples:

-baseline c:\baseline\testMacro1.mvm

-baseline "c:\base line\testMacro1.mvm"

note Ensure your session manager is configured to hold at least 2 sessions or use -numSessions to specify how many sessions to use.

-numSessions

Sets the number of sessions that can be loaded at once.

This is equivalent to the same setting in the session manage and can't be less than 1.

Example:

-numSessions 2

-saveSession

Saves the session data when all data has finished being collecting from the target program.

Thread Validator 32 and 64 bit use the file extension .tvm and .tvm_64 respectively.

A missing or incorrect filename extension will be corrected automatically

Examples:

-saveSession c:\results\testMacro1.tvm

-saveSession "c:\test results\testMacro1.tvm_x64"

-saveSession c:\results\testMacro1

-sessionLoad

-sessionLoad loads a previously created session to be merged with the data from the session being recorded.

These options might be used when a series of tests have already been performed and their sessions saved.

Thread Validator 32 and 64 bit use the file extension .tvm and .tvm_64 respectively.

A missing or incorrect filename extension will be corrected automatically

Examples:

-sessionLoad c:\results\testMacro1.tvm

-sessionLoad "c:\test results\testMacro1.tvm"

-sessionLoad c:\results\testMacro1

note Ensure your session manager is configured to hold at least 2 or 3 sessions or use -numSessions to specify how many sessions to use.

-sessionCompareHTML
-sessionCompareXML

Compare two sessions, producing an HTML or XML report detailing any regression and improvements.

The report is produced using the XML Export tags described in the Exporting Sessions section..

The two sessions can be loaded using one of these options:

-baseline and -sessionLoad

-baseline and running a program using one of -program, -injectName, -injectID, or -waitName

Examples:

-sessionCompareXML c:\regtests\testMacro1.xml

-sessionCompareHTML "c:\reg tests\testMacro1.html"

note Ensure your session manager is configured to hold at least 2 sessions or use -numSessions to specify how many sessions to use.


Session Export Options

Navigation: Command Line Interface >

Session Export Options

 Return to chapter overview

Session export format - HTML or XML

-exportAsHTML

-exportAsXML

Export the session data as an HTML or XML file when Thread Validator has finished collecting data from the target program.

If you merge the current session with another session, the exported HTML will be for the merged session.

If you disable merging with the current session the export will be for the unmerged session.

Example:

-exportAsHTML c:\results\html\testMacro1.html

-exportAsXML "c:\test results\xml\testMacro1.html"

Session export encoding - HTML or XML

These options allow you to export the session data as UTF-16, UTF8 or ASCII. UTF-16 and UTF-8 will add a byte order mark (BOM) to the start of the exported file.

-exportAsHTML_BOM

The exported HTML will be exported with the appropriate format.

-exportAsHTML_BOM ASCII

-exportAsHTML_BOM UTF8

-exportAsHTML_BOM UTF16

-exportAsXML_BOM

The exported XML will be exported with the appropriate format.

-exportAsXML_BOM ASCII

-exportAsXML_BOM UTF8

-exportAsXML_BOM UTF16


File Locations

Navigation: Command Line Interface >

File Locations

 Return to chapter overview

File Locations

When using the command line it's convenient to store settings and options in files that can be easily referenced.

Those files include:

·Global settings files

·File locations for source, PDB or MAP files

·DLL hook files

Each of these file types can be saved or exported from Thread Validator.

The -settings option is used to specify the settings to be used for the test. If the filename contains spaces, the filename should be quoted. This option is the same as -loadSettings and is provided for backwards compatibility.

Loading global settings from a file

Global settings are usually stored in the registry, but you can save a specific set of settings for use in thread tests:

·Settings menu instructionStep Save settings...

-loadSettings
-settings

Points to a previously saved settings file to be used for the test.

Examples:

-loadSettings c:\settings\testMacro1.tvs

-loadSettings "c:\thread test settings\testMacro1.tvs"

note The -settings option is identical to -loadSettings and is provided for backwards compatibility

File locations for source, PDB or MAP files

File location files can be easily generated by exporting file locations from the File Locations page of the settings dialog.

-fileLocations

Specify a plain text file listing file locations to be used during testing. See the format of the file below.

Each set of file types (one per line) is preceded by a header line in the file.

·[Files] instructionStep Source files

·[Third] instructionStep Third party source files

·[PDB] instructionStep PDB files

·[MAP] instructionStep MAP files

Example:

-fileLocations c:\threadTests\testFileLocations1.tvxfl

Example file:

[Files]

c:\work\project1\

[Third]

d:\VisualStudio\VC98\Include

[PDB]

c:\work\project3\debug

c:\work\project3\release

[MAP]

c:\work\project3\debug

c:\work\project3\release

Files listing DLLs to hook

DLL hook files can be easily generated by exporting DLL hooks from the Hooked DLLs page in the Filters section of the settings dialog.

-dllHookFile

Points to a file listing the DLLs to be hooked for the test.

Examples:

-dllHookFile c:\settings\testMacroDLLs.tvx

-dllHookFile "c:\thread tests settings\testMacroDLLs.tvx"

The first line of text in the DLL hooks file is one of the following:

·Rule:DoNotHook instructionStep DLLs marked as enabled will not be hooked. All other DLLs will be hooked

·Rule:DoHook instructionStep DLLs marked as enabled will be hooked. All other DLLs will not be hooked

·Rule:HookAll instructionStep All DLLs will be hooked regardless of the settings in the list

note Capitalization is important.

The remaining lines list one DLL filename or folder path and an enabled state on each line.

Example:

Rule:DoNotHook

nativeExample.exe enable=FALSE

MFC42D.DLL enable=TRUE

MSVCRTD.dll enable=TRUE

KERNEL32.dll enable=TRUE

ole32.dll enable=TRUE

Example:

Rule:DoHook

E:\OM\C\threadValidator\examples\nativeExample\DebugNonLink enable=TRUE

Example:

Rule:DoHook

"E:\OM\C\threadValidator\examples\nativeExample with spaces\DebugNonLink" enable=TRUE

Example:

Rule:DoHook
%ENV_VAR%\DebugNonLink enable=TRUE

Here, the environment variable ENV_VAR is used to replace the text %ENV_VAR% in the path definition.

The file can be ANSI or UNICODE text and paths with spaces do not need quotes.


Command Files

Navigation: Command Line Interface >

Command Files

 Return to chapter overview

Show/Hide Hidden Text

Using a command file

If your command line is very long, consider using -commandFile to specify a command file for your arguments.

-commandFile

Specify a file from which to read the command line arguments.

Useful when command lines become unwieldy or longer than the windows command size limits.

Use -- to insert comments into the file, including when commenting out option.

Examples:

-commandFile c:\threadtests\testMacro1.cf

-commandFile "c:\thread tests\testMacro1.cf"

doc-collapse-icon Example command file

-hideUI

-program c:\testbed\testApp.exe

-- arguments for application

-arg argumentOne

-arg argumentTwo

-arg "-s wobble"

-directory c:\testbed\test1

-settings c:\testbed\settings_test1.tvs

-- do export and save of the results

-exportAsHTML c:\testbed\results\test1.html

-saveSession c:\testbed\results\test1.tvm

For any argument that can be supplied to a command in a command file, you can also specify an environment variable substitution.

-directory %DIR%
-program %DIR%\testProgram.exe

The environment variables must have been set prior to starting Thread Validator.

You cannot specify a command with an environment variable substitution.


Help, Errors & Return Codes

Navigation: Command Line Interface >

Help, Errors & Return Codes

 Return to chapter overview

The following options may help with using and debugging the command line driven automated regression testing.

Command line help

-help

-?

Command line help is printed on the standard output.

-echoArgsToUser

Show the arguments that were supplied to the program.

Debugging command driven testing

If you're having problems with using the command line, check the following, try displaying error messages using the option below, and look at the exit return codes.

.

·separate command line arguments with spaces

·all command line options that include spaces need to have quotes around them

·some arguments are only useful in conjunction with others - check notes against each option

·some arguments are incompatible with others - check notes against each option

-showErrorsWithMessageBox

Forces errors to be displayed using a message box when running from the command line.

This can be very useful when debugging a command line that does not appear to work correctly.

Exit return codes

Thread Validator returns the following status codes when running from the command line. Some of these status codes are for internal use, or are obsolete (retired products).

·0 instructionStep All ok

·-1 instructionStep Unknown error. An unexpected error occurred starting the runtime

·-2 instructionStep Application started ok. You should not see this code returned

·-3 instructionStep Application failed to start. E.g. runtime not present, not an executable or injection dll not present,

·-4 instructionStep Target application is not an application

·-5 instructionStep Don't know what format the executable is, cannot process it

·-6 instructionStep Not a 32 bit application

·-7 instructionStep Not a 64 bit application

·-8 instructionStep Using incorrect MSVCR(8|9).DLL that links to CoreDLL.dll (incorrect DLL is from WinCE)

·-9 instructionStep Win16 app cannot start these because we can't inject into them

·-10 instructionStep Win32 app - not used

·-11 instructionStep Win64 app - not used

·-12 instructionStep .Net application

·-13 instructionStep User bailed out because app not linked to MSVCRT dynamically

·-14 instructionStep Not found in launch history

·-15 instructionStep DLL to inject was not found

·-16 instructionStep Startup directory does not exist

·-17 instructionStep Symbol server directory does not exist

·-18 instructionStep Could not build a command line

·-19 instructionStep No runtime specified, cannot execute script (or Java) (obsolete)

·-20 instructionStep Java arguments are OK - not an error (obsolete)

·-21 instructionStep Java agentlib supplied that is not allowed because Java Thread Validator uses it (obsolete)

·-22 instructionStep Java xrun supplied that is not allowed because Java Thread Validator uses it (obsolete)

·-23 instructionStep Java cp supplied that is not allowed because Java Thread Validator uses it (obsolete)

·-24 instructionStep Java classpath supplied that is not allowed because Java Thread Validator uses it (obsolete)

·-25 instructionStep Firefox is already running, please close it (obsolete)

·-26 instructionStep Lua runtime DLL version is not known (obsolete)

·-27 instructionStep Not compatible software

·-28 instructionStep InjectUsingCreateProcess, no DLL name supplied

·-29 instructionStep InjectUsingCreateProcess, Unable to open PE File when inspecting DLL

·-30 instructionStep InjectUsingCreateProcess, Invalid PE File when inspecting DLL

·-31 instructionStep InjectUsingCreateProcess, No Kernel32 DLL

·-32 instructionStep InjectUsingCreateProcess, NULL VirtualFree() from GetProcAddress

·-33 instructionStep InjectUsingCreateProcess, NULL GetModuleHandleW() from GetModuleHandleW

·-34 instructionStep InjectUsingCreateProcess, NULL LoadLibraryW() from LoadLibraryW

·-35 instructionStep InjectUsingCreateProcess, NULL FreeLibrary() from FreeLibrary

·-36 instructionStep InjectUsingCreateProcess, NULL VirtualProtect() from GetProcAddress

·-37 instructionStep InjectUsingCreateProcess, NULL VirtualFree() from GetProcAddress

·-38 instructionStep InjectUsingCreateProcess, unable to find DLL load address

·-39 instructionStep InjectUsingCreateProcess, unable to write to remote process's memory

·-40 instructionStep InjectUsingCreateProcess, unable to read remote process's memory

·-41 instructionStep InjectUsingCreateProcess, unable to resume a thread

·-42 instructionStep UPX compressed - cannot process such executables

·-43 instructionStep Java class not found in CLASSPATH

·-44 instructionStep Failed to launch the 32 bit svlGetProcAddressHelperUtil.exe

·-45 instructionStep Uknown error with svlGetProcAddressHelperUtil.exe

·-46 instructionStep Couldn't load specified DLL into svlGetProcAddressHelperUtil.exe

·-47 instructionStep Couldn't find function in the DLL svlGetProcAddressHelperUtil.exe

·-48 instructionStep Missing DLL argument svlGetProcAddressHelperUtil.exe

·-49 instructionStep Missing function argument svlGetProcAddressHelperUtil.exe

·-50 instructionStep Missing svlGetProcAddressHelperUtil.exe

·-51 instructionStep Target process has a manifest that requires elevation

·-52 instructionStep svlInjectIntoProcessHelper_x64.exe not found

·-53 instructionStep svlInjectIntoProcessHelper_x64.exe failed to start

·-54 instructionStep svlInjectIntoProcessHelper_x64.exe failed to return error code

·-55 instructionStep getImageBase() worked ok

·-56 instructionStep ReadFile() failed in getImageBase()

·-57 instructionStep NULL pointer when trying to allocate memory

·-58 instructionStep CreateFile() failed in getImageBase()

·-59 instructionStep ReadProcessMemory() failed in getImageBase()

·-60 instructionStep VirtualQueryEx() failed in getImageBase()

·-61 instructionStep Bad /appName argument in svlInjectIntoProcessHelper_x64.exe

·-62 instructionStep Bad /dllName argument in svlInjectIntoProcessHelper_x64.exe

·-63 instructionStep Bad /procId argument in svlInjectIntoProcessHelper_x64.exe

·-64 instructionStep Failed to OpenProcess in svlInjectIntoProcessHelper_x64.exe

·-65 instructionStep A DLL that the .exe depends upon cannot be found

·-66 instructionStep A stdin file was specified, but Validator could not open it

·-67 instructionStep A stdout file was specified, but Validator could not open it

·-68 instructionStep Failed to create the child output pipe

·-69 instructionStep Failed to create a duplicate of the output write handle for the std error write handle. This is necessary in case the child application closes one of its std output handles

·-70 instructionStep Failed to create the child input pipe

·-71 instructionStep Failed to create a duplicate output read temporary file

·-72 instructionStep Failed to create a duplicate input write temporary file

·-73 instructionStep User was trying to launch a service as an application that was linked to TV APIs. User cancelled when informed of this fact

·-74 instructionStep Returned by Thread Validator if user performs a baseline comparison and memory leaks are detected

·-75 instructionStep Shutdown and restart as 32 bit Thread Validator

·-76 instructionStep Shutdown and restart as 64 bit Thread Validator

·-77 instructionStep Entry point in executable is NULL.

·-78 instructionStep Application is .Net Core.

·-79 instructionStep Entry point is for a .Net application.

·-80 instructionStep VirtualAllocEx() returned NULL

·-81 instructionStep InjectUsingCreateProcess, NULL GetLastError() from GetProcAddress


Command Line Reference

Navigation: Command Line Interface >

Command Line Reference

 Return to chapter overview

Command line reference

The following alphabetical list provides a convenient look-up for all the command line arguments used in automated regression testing.

Option | Description
-? | Print command line help on the standard output.
-allArgs | Pass the remainder of the command line to the program being launched.
-arg | Pass command line arguments to the target program. Can be used multiple times.
-baseline | Loads a previous session as the baseline session against which the recorded session is compared for regressions or improvements.
-collectData | Turn data collection on or off
-collectStdout | Turn collection of stdout on or off
-commandFile | Specify a file from which to read the command line arguments.
-directory | Set the working directory in which the program is executed.
-displayUI | Force the Thread Validator user interface to be displayed during the test.
-dllHookFile | Points to a file listing the DLLs to be hooked for the test.
-doNotInteractWithUser | Never display dialog boxes in the target application that is being profiled.
-echoArgsToUser |
-environment | Environment variables for program, as a series of name/value pairs
-exportAsHTML -exportAsXML | Export the session data as an HTML or XML file when Thread Validator has finished collecting data from the target program.
-exportAsHTML_BOM -exportAsXML_BOM | Specify the file encoding for the exported file
-fileLocations | Specify a plain text file listing file locations to be used during testing. See the format of the file below.
-help | Print command line help on the standard output.
-hideCommandPrompt | Any launched console window will be hidden during the test.
-hideUI | Hide the Thread Validator user interface during the test.
-injectID | Set the numeric (decimal) id of a process for Thread Validator to attach to.
-injectName | Set the name of the process for Thread Validator to attach to.
-launchAppHide | Hide the target application during the test.
-launchAppShow | Show the target application during the test.
-launchAppShowMaximized | Show the target application maximized and activated.
-launchAppShowMinNoActive | Show the target application minimized and activated.
-launchAppShowMinimized | Show the target application minimized and not active.
-launchAppShowNA | Show the target application at current size and position but not activated.
-launchAppShowNoActivate | Show the target application at most recent size and position but not activated.
-launchAppShowNormal | Show the target application at original size and position and activated.
-loadSession | Load a previously created session to be merged with the data from the session being recorded.
-loadSettings | Points to a previously saved settings file to be used for the test.
-monitorAService | Specify the full file system path to the service to monitor, including any extension. The service is not started by Thread Validator but by an external means.
-numSessions | Set the number of sessions that can be loaded at once.
-program | Specify the full file system path of the executable target program to be started by Thread Validator, including any extension.
-programToMonitor | Changes which program the data is collected from but does not change which process Thread Validator initially launches.
-programToMonitorLaunchCount | Specify the nth invocation of the programToMonitor which is to have its data collected.
-refreshActiveObjects | Automatically refresh the Active Objects tab once a test is complete.
-refreshQuery | Automatically refresh the Query tab once a test is complete.
-refreshCoverage | Automatically refresh the Coverage tab once a test is complete.
-refreshActiveLocks | Automatically refresh the Active Locks tab once a test is complete.
-refreshAllLocks | Automatically refresh the All Locks tab once a test is complete.
-refreshObjectHandles | Automatically refresh the Object Handles tab once a test is complete.
-refreshLocksPerThread | Automatically refresh the Locks Per Thread tab once a test is complete.
-refreshSummary | Automatically refresh the Summary tab once a test is complete.
-refreshThreads | Automatically refresh the Threads tab once a test is complete.
-refreshWaitChain | Automatically refresh the Wait Chain tab once a test is complete.
-resetSettings | Forces Thread Validator to reset (nearly) all settings to the default state.
-saveSession | Save the session data when all data has finished being collecting from the target program.
-sessionCompareHTML -sessionCompareXML | Compare two sessions, producing an HTML or XML report detailing any regression and improvements.
-sessionLoad | Loads a previously created session to be merged with the data from the session being recorded
-setenvironment | Environment variables for Thread Validator, as a series of name/value pairs
-settings | Points to a previously saved settings file to be used for the test.
-showCommandPrompt | Any launched console window will be shown during the test.
-showErrorsOnCommandPrompt | If an error occurs when launching the application, the error will be reported on the command line.
-showErrorsWithMessageBox | Force errors to be displayed using a message box when running from the command line.
-waitName | Name a process that Thread Validator will wait for.

To run 32 bit thread validator run C:\Program Files (x86)\Software Verify\Thread Validator x86\threadValidator.exe

To run 64 bit thread validator run C:\Program Files (x86)\Software Verify\Thread Validator x64\threadValidator_x64.exe


Troubleshooting

Navigation: Command Line Interface >

Troubleshooting

 Return to chapter overview

Running from the command line can cause some problems, often because you can't be sure that what you put on the command line did what you thought would do.

Ensure the arguments supplied are what you expected.

-echoArgsToUser

If you are testing a console application, make sure you can see it.

-showCommandPrompt

If an errors occur when processing the command line, make sure you can see those.

-showErrorsOnCommandPrompt

-showErrorsWithMessageBox

Look on the diagnostic tab to ensure the diagnostic data collected makes sense.

If you've got -hideUI in your command line, comment it out temporarily (make it -xhideUI so that it's not recognised).

What if the tool hangs?

If you're running from the command line, most likely you'll be running from a cmd prompt, or possibly powershell.

We've only ever had one customer report a hang with any of our tools when running from the command line.

We eventually found the problem, and it wasn't with the software tool.

The problem was that they were running the tool in hidden mode (-hideUI) from a command prompt and for unknown reasons the tool would never exit.

When they added a simple change to their command the problem went away.

They added cmd /c to the start of their command line. This opens a new command prompt and instructs it to launch the command line and wait for it to exit.

Problem command line:

"c:\program files (x86)\Software Verify\Thread Validator x64\threadValidator_x64.exe" -program c:\testProgram.exe -hideUI

Working command line:

cmd /c "c:\program files (x86)\Software Verify\Thread Validator x64\threadValidator_x64.exe" -program c:\testProgram.exe -hideUI


Native API

Navigation: »No topics above this level«

Native API

 Return to chapter overview

The Thread Validator API

There are some features of Thread Validator that are useful to call directly from your program, including tracking of memory in custom heap managers.

Thread Validator has an API that makes this possible; just include svlTVAPI.c and svlTVAPI.h to your codebase. There is no library to link to, dlls to copy.

Source files

The source files can be found in the API directory in the Thread Validator install directory.

svlTVAPI.h

svlTVAPI.c

Just add these files to your project and build.

If you are using precompiled headers you will need to disable them for svlTVAPI.c.

Working with services?

If you are working with services you to attach Thread Validator to a service and to start Thread Validator, you should use the NT Service API, not the functions in this API.

All the other functions in this API can be used with applications and with services.

Unicode or ANSI?

All the API functions are provided in Unicode and ANSI variants where strings are used. We've also provided a character width neutral #define in the same fashion that the Windows.h header files do.

For example the function for naming a heap is provided as tvSetThreadNameA(), tvSetThreadNameW() with the character width neutral tvSetThreadName() mapping to tvSetThreadNameW() for unicode and tvSetThreadNameA() for ANSI.

In this document we're going to use TCHAR like the Window.h header files do.

Deploying on a customer machine

You can use the API without incurring any dependency on Thread Validator.

If Thread Validator is not installed on the machine the software runs on, nothing will happen.

This allows you to add the Thread Validator API to your software without need to have a separate build for use with Thread Validator.

Loading the Profiler

For most use cases won't need to load the profiler, as the profiler will have been loaded when your launched your program from Thread Validator, or when you injected into your program using Inject or Wait For Application.

However if you're running your program from outside of Thread Validator and want to load the profiler from inside your program you can use tvLoadProfiler() to do that. You'll then need to call tvStartProfiler() to start it.

Starting the Profiler

To start the profiler from your API code you need to call the function tvStartProfiler() from your code before you call any API functions. Ideally you should call this function as early in your program as possible.

If you prefer to start the profiler from the user interface or command line you can omit the startProfiler() call. You can leave it present if you wish to start Thread Validator from your program.

Naming threads

You can name threads using the tvSetThreadNameA() and tvSetThreadNameW() functions.

Turning data collection on and off

You can turn data collection on and off using the tvSetCollect() function.

You can use tvGetCollect() to inspect the data collection status.


Native API Reference

Navigation: Native API >

Native API Reference

 Return to chapter overview

Unicode or ANSI?

All the API functions are provided in Unicode and ANSI variants where strings are used. We've also provided a character width neutral #define in the same fashion that the Windows.h header files do.

For example the function for naming a heap is provided as tvSetThreadNameA(), tvSetThreadNameW() with the character width neutral tvSetThreadName() mapping to tvSetThreadNameW() for unicode and tvSetThreadNameA() for ANSI.

In this document we're going to use TCHAR like the Window.h header files do.

All the API functions are declared as extern "C", so they can be used by C users and C++ users.

To use these functions #include svlTVAPI.h into your code.

tvLoadProfiler

Loads the profiler DLL into memory, but does not start the profiler.

For most use cases won't need to load the profiler, as the profiler will have been loaded when your launched your program from Thread Validator, or when you injected into your program using Inject or Wait For Application.

However if you're running your program from outside of Thread Validator and want to load the profiler from inside your program you can use tvLoadProfiler() to do that. You'll then need to call tvStartProfiler() to start it.

extern "C"

void tvLoadProfiler();

Do not use this function if you are working with services, use the NT Service API.

tvStartProfiler

To start the profiler from your API code you need to call the function tvStartProfiler() from your code before you call any API functions. Ideally you should call this function as early in your program as possible.

extern "C"

void tvStartProfiler();

If you prefer to start the profiler from the user interface or command line you can omit the tvStartProfiler() call. You can leave it present if you wish to start Thread Validator from your program.

Do not use this function if you are working with services, use the NT Service API.

tvSetThreadName()

Sets the name of a thread.

extern "C"
void tvSetThreadName(DWORD threadID

const TCHAR *name);

tvSetThreadNameA()

Sets the name of a thread.

extern "C"
void tvSetThreadNameA(DWORD threadID

const char *name);

tvSetThreadNameW()

Sets the name of a thread.

extern "C"
void tvSetThreadNameW(DWORD threadID

const wchar_t *name);

tvSetCollect()

Enables or disables data collection - i.e. whether data is sent to Thread Validator from your target application.

extern "C"
void tvSetCollect(int enable); // TRUE to enable, FALSE to disable

tvGetCollect()

Returns whether data collection is on.

extern "C"
int tvGetCollect(); // Returns TRUE or FALSE


C# API

Navigation: Native API >

C# API

 Return to chapter overview

The C# API is a wrapper around the native API.

For all of these APIs see the native API for more details.

Adding the API to your application

The C# API is provided as a source code svlTVAPI.cs file that you add to your application. The source file is in the API directory in the Thread Validator install directory.

The C# API does not add any dependencies to your application - if Thread Validator is present the API functions work, if Thread Validator is not present the API functions do nothing.

The C# API

The C# API is implemented by the ThreadValidator class in the SoftwareVerify namespace.

collectOn()

Turn data collection on.

public static void collectOn();

collectOff()

Turn data collection off.

public static void collectOff();

setCollect()

Turn data collection on or off.

public static void setCollect(bool enable);

getCollect()

Determine if data collection is turned on or off.

public static bool getCollect();


Calling the API via GetProcAddress

Navigation: Native API >

Calling the API via GetProcAddress

 Return to chapter overview

Show/Hide Hidden Text

Calling API functions using GetProcAddress

If you don't want to use the svlTVAPI.c/h files you can use GetProcAddress to find the interface functions in the Thread Validator DLL.

The interface functions have different names and do not use C++ name mangling, but have identical parameters to the API functions.

To determine the function name take any native API name, replace the leading tv with api. For example tvSetThreadNameW() becomes apiSetThreadNameW();

Example usage

typedef void (*tvSetThreadNameW_FUNC)(const TCHAR *name);

HMODULE getValidatorModule()
{
HMODULE hModule;

hModule = GetModuleHandle(_T("svlThreadValidatorStub6432.dll")); // 32 bit DLL with 64 bit Thread Validator GUI
if (hModule == NULL)
hModule = GetModuleHandle(_T("svlThreadValidatorStub_x64.dll")); // 64 bit DLL with 64 bit Thread Validator GUI
if (hModule == NULL)
hModule = GetModuleHandle(_T("svlThreadValidatorStub.dll")); // 32 bit DLL with 32 bit Thread Validator GUI

return hModule;
}

HMODULE hMod;

// get module, will only succeed if Thread Validator launched this app or is injected into this app

hMod = getValidatorModule();
if (hMod != NULL)
{
// MV is present, lookup the function and call it to set a watermark for this location in the code

tvSetThreadNameW_FUNC pFunc;

// "apiSetThreadNameW" is equivalent to linking against "tvSetThreadNameW"

pFunc = (tvSetThreadNameW_FUNC)GetProcAddress(hMod, "apiSetThreadNameW");
if (pFunc != NULL)
{
(*pFunc)(threadName);
}
}

API functions and their GetProcAddress names

For any API functions not listed, try looking up the name in svlMemoryValidatorStub.dll using depends.exe or PE File Browser.

doc-collapse-icon Show API functions and GetProcAddress names

API Name

GetProcAddress() Name

tvLoadProfiler

tvIsValidatorPresent

tvStartProfiler

tvSetThreadNameA

tvSetThreadNameW

tvSetCollect

tvGetCollect

tvShutdownThreadValidator

apiSetThreadNameA

apiSetThreadNameW

apiSetCollect

apiGetCollect

apiShutdownThreadValidator

Other exported functions

You may see some other functions exported from svlThreadValidatorStub.dll(_x64).dll.

warningnote These other functions are for Thread Validator's use. Using them may damage memory locations and/or crash your code. Best not to use them!


Convenience functions

Navigation: Native API >

Convenience functions

 Return to chapter overview

Convenience functions

One convenience function is provided that will start the Thread Validator GUI (if it is not already running), then load the Thread Validator execution tracer into your process and start tracing it.

extern "C"

void loadValidatorIntoApplication();

To use this function #include loadValidatorIntoApplication.h into your code.

The source files can be found in the API directory in the Thread Validator install directory.

loadValidatorIntoApplication.h

loadValidatorIntoApplication.c

Just add these files to your project and build.


Working with IIS and Services

Navigation: »No topics above this level«

Working with IIS and Services

 Return to chapter overview

note When working with NT services your account must have the appropriate privileges described in the User Permissions topic.

Attaching to your service

To use Thread Validator with NT Services you need to link a small library to your application and call two functions in the library.

The NT Service API

The NT Service API is provided to enable Thread Validator to work with services.

The API works just as well with normal applications, and the same considerations outlined here also apply generally.

When the NT Service API is used, source code symbols are acquired in the stub and sent to the Thread Validator user interface.

Monitoring the service

When working with Thread Validator and services using the NT Service API you don't start the service using Thread Validator.

Instead, you start the service the way you normally start the service - e.g. with the service control manager.

The code that you have embedded into your service then contacts Thread Validator, which you should have running before starting the service.

Once you've exercised your service and stopped it, Thread Validator will show the usual thread data.

Examples and help

We provide some Example Service Source Code to demonstrate how to embed the service code into your service.

If you have problems using Thread Validator with services, please contact us at support@softwareverify.com.


NT Service API

Navigation: Working with IIS and Services >

NT Service API

 Return to chapter overview

The Thread Validator stub service libraries

The NT Service API is very simple, consisting of functions to load, start and unload the Thread Validator DLL.

We have also provided some debugging functions to help you debug the implementation of the NT Service API because getting data into and out of services is not always straightforward.

The stub service libraries used for this are shown in the following table:

 | 32 bit Thread Validator | 64 bit Thread Validator
32 bit service | svlTVStubService.lib svlTVStubServiceMD.lib svlTVStubServiceMT.lib | svlTVStubService6432.lib
64 bit service | N/A | svlTVStubService_x64.lib svlTVStubServiceMD_x64.lib svlTVStubServiceMT_x64.lib

All the functions exported from these libraries are exported as extern "C" so that C and C++ users can use them.

Library name suffixes

The MD suffix indicates the library was built with the /MD compiler switch.

The MT suffix indicates the library was built with the /MT compiler switch.

Directory Name: 2010 or 2012?

Visual Studio 6 to Visual Studio 2010

If you are using Visual Studio 2010 or earlier, use libraries from a directory with 2010 in the directory name.

Visual Studio 2010 to Visual Studio 2022

If you are using Visual Studio 2012 or later, use libraries from a directory with 2012 in the directory name.

Header files

The header files can be found in the svlTVStubService directory in the Thread Validator install directory.

The headers file provide an error enumeration and the NT Service API functions.

svlTVStubService.h

svlServiceError.h

Linker Problems

Some linkers cannot link the stub service library file. If you have this problem see What do I do if I cannot use svlTVStubService.lib?

Loading the Thread Validator DLL into your service

To load the Thread Validator stub dll svlThreadValidatorStub(_x64).dll into your service, call svlTVStub_LoadThreadValidator(), not LoadLibrary().

If you are monitoring a 32 bit service with the 64 bit Thread Validator user interface you should use svlTVStub_LoadThreadValidator6432().

Shutting down the Thread Validator DLL from your service.

To shutdown Thread Validator's monitoring of the service , call svlTVStub_ShutdownThreadValidator().

This sends the shutting down notification and removes any hooks for your process.

Calling this function is optional. You can stop your service without calling this function.

Unloading the Thread Validator DLL from your service.

To unload the Thread Validator stub dll, call svlTVStub_UnloadThreadValidator(), not FreeLibrary().

Calling this function is optional. You can stop your service without calling this function.

Setting a service notification callback

Once you have successfully loaded the Thread Validator DLL you can setup a service callback so that the service control manager can be kept updated during the process of starting the validator.

When a service is starting, Windows requires the service to inform the Service Control Manager (SCM) that is starting at least every ten seconds.

Failure to do so results in Windows concluding that the service has failed to start, and the service is terminated.

Instrumenting your service may well take more than 10 seconds, depending on the complexity and size of your service.

The solution is for Thread Validator to periodically call a user supplied callback from which you can regularly inform the SCM of the appropriate status.

You can set the service callback with svlTVStub_SetServiceCallback(callback, userParam).

Usage

Here is an example callback which ignores the userParam.

void serviceCallback(void *userParam)
{
static DWORD dwCheckPoint = 1;

ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
ssStatus.dwServiceSpecificExitCode = 0;

ssStatus.dwControlsAccepted = 0;

ssStatus.dwCurrentState = dwCurrentState;
ssStatus.dwWin32ExitCode = dwWin32ExitCode;
ssStatus.dwWaitHint = dwWaitHint;

ssStatus.dwCheckPoint = dwCheckPoint++;

// Report the status of the service to the service control manager.

return SetServiceStatus(sshStatusHandle, &ssStatus);
}

Starting Thread Validator DLL in your service

To start Thread Validator detecting deadlocks in your service call svlTVStub_StartThreadValidator.

Starting Thread Validator DLL in IIS

To start Thread Validator detecting deadlocks in IIS call svlTVStub_StartThreadValidatorForIIS().

Setting a filename for all logging data to be written to

To set the filename for all debugging/logging information to be written to call svlTVStub_setLogFileName().

Deleting the logfile

To delete the log file call svlTVStub_deleteLogFile().

Writing text to the logfile

To write a standard ANSI character string to the log file call svlTVStub_writeToLogFileA(text). The ANSI string will be converted to Unicode prior to writing to the log file.

To write a Unicode character string to the log file call svlTVStub_writeToLogFileW(text).

Writing error code descriptions to the logfile

To write a human readable description of the SVL_SERVICE_ERROR error code to the log file call svlTVStub_writeToLogFile(errCode).

Writing LastError code descriptions to the logfile

To write a human readable description of the Windows error code to the log file call svlTVStub_writeToLogFileLastError(errCode).

Dumping the PATH environment to the logfile

To write the contents of the PATH environment variable to the log file call svlTVStub_dumpPathToLogFile().

This can be useful if you want to know what the search path is when trying to debug why a DLL wasn't found during an attempt to load the Validator DLL.


Changes to the NT Service API

Navigation: Working with IIS and Services > NT Service API >

Changes to the NT Service API

 Return to chapter overview

API changes - February 2018

To make the API easier to use with services we made the following changes:

·Changed the API by adding many debugging functions to allow you to easily log information.

·We also extended the error enumeration to provide additional error status values.

·We also split the function of loading and starting Thread Validator into two functions - a load function and a start function.

·We split the functionality so that you could setup a service callback prior to calling the start function.

The service callback allows the service control manager to be informed that the service is still active during time consuming operations, such as starting the Thread Validator when the service is non-trivial in scope.

Failure to inform the service control manager results in the service being killed by the service control manager because it thinks the service has hung.

This change in the API is to ensure you get better results from using our software.

What do you need to do to move from the old API to the new API?

Change all SVL_ERROR declarations to SVL_SERVICE_ERROR.

Your previous startup code probably looked like this:

SVL_ERROR errCode;

errCode = svlTVStub_LoadThreadValidator();

Change it to this:

SVL_SERVICE_ERROR errCode;

errCode = svlTVStub_LoadThreadValidator();

errCode = svlTVStub_SetServiceCallback(serviceCallback, NULL);

errCode = svlTVStub_StartThreadValidator();

The serviceCallback would look something like this:

void serviceCallback(void *userParam)
{
static DWORD dwCheckPoint = 1;

ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
ssStatus.dwServiceSpecificExitCode = 0;

ssStatus.dwControlsAccepted = 0;

ssStatus.dwCurrentState = dwCurrentState;
ssStatus.dwWin32ExitCode = dwWin32ExitCode;
ssStatus.dwWaitHint = dwWaitHint;
ssStatus.dwCheckPoint = dwCheckPoint++;

// Report the status of the service to the service control manager.

return SetServiceStatus(sshStatusHandle, &ssStatus);
}

In the code above we have omitted error handling. To see how to use the new logging function with error handling please examine the source code service.cpp in the example service project.

Important.

Once your service is running (rather than starting) your service callback should set the appropriate running status SERVICE_RUNNING rather than SERVICE_START_PENDING.

if (!ReportStatusToSCMgr(SERVICE_RUNNING, // service state
NO_ERROR, // exit code
0)) // wait hint
{
dwErr = GetLastError();
if (bLogging)
svlTVStub_writeToLogFileW(L"ReportStatusToSCMgr:5\r\n");
goto cleanup;
}

An alternative solution is to prevent the service callback from being called once the service status has been set to running.

svlTVStub_SetServiceCallback(NULL, NULL);.


NT Service API Reference

Navigation: Working with IIS and Services > NT Service API >

NT Service API Reference

 Return to chapter overview

The API consists of the following functions.

SVL_SERVICE_ERROR Enumeration

typedef enum _svlServiceError
{
SVL_OK, // Normal behaviour
SVL_ALREADY_LOADED, // Stub DLL already loaded into service
SVL_LOAD_FAILED, // Failed to load stub DLL into service
SVL_FAILED_TO_ENABLE_STUB_SYMBOLS, // Loaded DLL, but failed to enable stub symbols because couldn't find function
SVL_NOT_LOADED, // Couldn't unload DLL because DLL not loaded
SVL_FAIL_UNLOAD, // Couldn't unload DLL because couldn't find function
SVL_FAIL_TO_CLEANUP_INTERNAL_HEAP, // Couldn't get the internal stub heap and thus couldn't clean it up
SVL_FAIL_MODULE_HANDLE // Couldn't get the stub DLL handle so couldn't continue
SVL_FAIL_SETSERVICECALLBACK, // Couldn't call the set service callback

SVL_FAIL_COULD_NOT_FIND_ENTRY_POINT, // Couldn't find the DLL entry point to start the validator

SVL_FAIL_TO_START, // Failed to start the Validator

SVL_FAIL_SETSERVICECALLBACKTHRESHOLD, // Couldn't call the set service callback threshold

SVL_FAIL_PATHS_DO_NOT_MATCH, // Path to service in env vars doesn't match the service being run

SVL_FAIL_INCORRECT_PRODUCT_PREFIX, // Wrong validator

SVL_FAIL_X86_VALIDATOR_FOUND_EXPECTED_X64_VALIDATOR, // Found wrong bit depth validator

SVL_FAIL_X64_VALIDATOR_FOUND_EXPECTED_X86_VALIDATOR, // Found wrong bit depth validator

SVL_FAIL_DID_YOU_MONITOR_A_SERVICE_FROM_VALIDATOR, // Looks like Monitor A Service wasn't used

SVL_FAIL_ENV_VAR_NOT_FOUND, // Env Var not found

SVL_FAIL_VALIDATOR_ENV_VAR_NOT_FOUND, // Env Var identifying validator not found

SVL_FAIL_VALIDATOR_ID_NOT_SPECIFIED, // Validator process not specified

SVL_FAIL_VALIDATOR_ID_NOT_A_PROCESS, // Validator process identified doesn't exist

SVL_FAIL_VALIDATOR_NOT_FOUND, // Validator process identified doesn't exist

} SVL_SERVICE_ERROR;

svlTVStub_LoadThreadValidator

extern "C"

SVL_SERVICE_ERROR svlTVStub_LoadThreadValidator();

To load the Thread Validator stub svlThreadValidatorStub.dll into your service, use svlTVStub_LoadThreadValidator(), not LoadLibrary().

This loads the DLL and sets up a few internal variables in the DLL to ensure that symbols are sent from the stub to the Thread Validator user interface.

This is necessary because the Thread Validator user interface can't open a process handle to a service and so is unable to get symbols from the process.

To solve this, symbols are sent from the stub to the user interface as needed.

If you just call LoadLibrary() on the DLL, symbols will not be sent to the Thread Validator user interface and you won't get meaningful function names in your stack traces.

This function can be used when monitoring:

·32 bit services or applications with Thread Validator

·64 bit services or applications with Thread Validator x64

If you are monitoring 32 bit applications with Thread Validator x64 you should use svlTVStub_LoadThreadValidator6432().

Which function you should call is shown in the table below.

 | 32 bit Thread Validator | 64 bit Thread Validator
32 bit service | svlTVStub_LoadThreadValidator() | svlTVStub_LoadThreadValidator6432()
64 bit service | N/A | svlTVStub_LoadThreadValidator()

svlTVStub_LoadThreadValidator6432

extern "C"

SVL_SERVICE_ERROR svlTVStub_LoadThreadValidator6432();

To load the Thread Validator stub svlThreadValidatorStub6432.dll into your service, use svlTVStub_LoadThreadValidator6432(), not LoadLibrary().

This loads the DLL and sets up a few internal variables in the DLL to ensure that symbols are sent from the stub to the Thread Validator user interface.

This is necessary because the Thread Validator user interface can't open a process handle to a service and so is unable to get symbols from the process.

To solve this, symbols are sent from the stub to the user interface as needed.

If you just call LoadLibrary() on the DLL, symbols will not be sent to the Thread Validator user interface and you won't get meaningful function names in your stack traces.

This function should only be used when monitoring 32 bit services or applications with Thread Validator x64.

svlTVStub_StartThreadValidator

extern "C"

SVL_SERVICE_ERROR svlTVStub_StartThreadValidator();

To start Thread Validator inspecting the service call svlTVStub_StartThreadValidator().

svlTVStub_StartThreadValidatorForIIS

extern "C"

SVL_SERVICE_ERROR svlTVStub_StartThreadValidatorForIIS();

To start Thread Validator inspecting IIS call svlTVStub_StartThreadValidatorForIIS().

Example usage.

svlTVStub_ShutdownThreadValidator

extern "C"

SVL_SERVICE_ERROR svlTVStub_ShutdownThreadValidator();

To stop Thread Validator inspecing the service call svlTVStub_ShutdownThreadValidator().

This sends the shutting down notification and removes any hooks for your process.

Calling this function is optional. You can stop your service without calling this function.

svlTVStub_UnloadThreadValidator

extern "C"

SVL_SERVICE_ERROR svlTVStub_UnloadThreadValidator();

To unload Thread Validator call svlTVStub_UnloadThreadValidator(), do not call FreeLibrary().

Calling this function is optional. You can stop your service without calling this function.

svlTVStub_SetServiceCallback

extern "C"

SVL_SERVICE_ERROR svlTVStub_SetServiceCallback(serviceCallback_FUNC callback,
void* userParam);

svlTVStub_SetServiceCallback is used to setup a service callback that is used to inform the Windows service control manager that the service is alive.

userParam is a value you can supply which will then be passed to the callback every time the callback is called during instrumentation.

Why is a service callback needed?

When a service is starting, Windows requires the service to inform the Service Control Manager (SCM) that is starting at least every ten seconds.

Failure to do so results in Windows concluding that the service has failed to start, and the service is terminated.

Instrumenting your service may well take more than 10 seconds, depending on the complexity and size of your service.

The solution is for Coverage Validator to periodically call a user supplied callback from which you can regularly inform the SCM of the appropriate status.

We strongly recommend that you setup a service callback. Not setting a service callback can result in failure of your service to run because Windows kills it during startup and Thread Validator's instrumentation phase.

Debugging functions

The following functions are provided to help you log information about the progress, success or failure of the NT Service API attaching Thread Validator to your service.

We strongly recommend that you use these logging functions so that you can understand why Thread Validator might fail to connect to a service.

To see example usage of these debugging functions please look in service.cpp in the examples\service directory in the Thread Validator install directory.

svlTVStub_setLogFileName

extern "C"

void svlTVStub_setLogFileName(const wchar_t* fileName);

Call svlTVStub_setLogFileName to set the name of the filename used for logging.

This function must be called before you can use any of the other debugging functions.

Setting this filename also sets the filename used by some of these API functions - you will find additional logging data from those functions that will help debug any issues with the service.

svlTVStub_deleteLogFile

extern "C"

void svlTVStub_deleteLogFile();

This function deletes the log file.

svlTVStub_writeToLogFileA

extern "C"

void svlTVStub_writeToLogFileA(const char* text);

This function writes a standard ANSI character string to the log file.

The ANSI string will be converted to Unicode prior to writing to the log file.

svlTVStub_writeToLogFileW

extern "C"

void svlTVStub_writeToLogFileW(const wchar_t* text);

This function writes a Unicode character string to the log file.

svlTVStub_writeToLogFile

extern "C"

void svlTVStub_writeToLogFile(SVL_SERVICE_ERROR errCode);

This function writes a human readable description of the SVL_SERVICE_ERROR error code to the log file.

svlTVStub_writeToLogFileLastError

extern "C"

void svlTVStub_writeToLogFileLastError(DWORD errCode);

This function writes a human readable description of the Windows error code to the log file.

The errCode parameter is the error code returned from GetLastError().

svlTVStub_dumpPathToLogFile

extern "C"

void svlTVStub_dumpPathToLogFile();

This function writes the contents of the PATH environment variable to the log file.

This can be useful if you want to know what the search path is when trying to debug why a DLL wasn't found during an attempt to load the Validator DLL.


Troubleshooting

Navigation: Working with IIS and Services > NT Service API >

Troubleshooting

 Return to chapter overview

Troubleshooting - Service fails to start

If a service takes too long to start the service control manager kills the service.

The way to stop this is for a service to call ReportStatusToSCMgr() to tell the service control manager that the service is still OK.

Thread Validator can't do this for you as the call requires some data from any earlier call you have made.

The solution is that you provide a callback using svlTVStub_SetServiceCallback() that Thread Validator can call during the process of attaching to the service, and you can call the appropriate function.

Example code to set the callback:

errCode = svlTVStub_SetServiceCallback(serviceCallback,                // the callback

    NULL);                                // some user data (we don't have any, so set NULL)

if (bLogging)

{

if (errCode != SVL_OK)

{

svlTVStub_writeToLogFileW(L"Setting service callback failed. \r\n");

svlTVStub_writeToLogFile(errCode);

}

svlTVStub_writeToLogFileW(L"Starting Thread Validator\r\n");

}

Example callback:

static void serviceCallback(void        *userParam)

{

// just tell the Service Control Manager that we are still busy

// in this example userParam is not used

//

// note that prior to the Validator loading it's DLL ssStatus.dwCurrentState must have been initialised, most likely to SERVICE_START_PENDING

// you could pass a fixed value here, but it would need to change once the service has finished starting up so that you don't unintentionally change the service state

// when this callback is called. This callback is called whenever instrumentation happens (when a DLL is loaded). Thus you can't assume this is only called during service startup,

// it may also get called later in the service lifetime.

ReportStatusToSCMgr(ssStatus.dwCurrentState,        // service state

NO_ERROR,                        // exit code

3000);                                // wait hint

}

We strongly recommend that you set a service callback. It won't harm your program and it will remove any likelihood of your service being killed by the service control manager.

Troubleshooting - Service starts, Thread Validator gets no data

If you have problems getting Thread Validator to monitor your service you'll need to find out what's failing.

Until Thread Validator loads correctly and successfully connects to the graphical user interface you have no way of knowing what is happening.

The solution is to set a log file that Thread Validator can write status messages to. You can also write your own status messages to this log file.

Set the log file using svlTVStub_setLogFileName. Write to it using svlTVStub_writeToLogFile(), svlTVStub_writeToLogFileA(), svlTVStub_writeToLogFileW().

Then when things are not working as expected take a look at the log file to see the errors. The Thread Validator will often suggest what the problem is.

We strongly recommend that you configure the log file and use it when working with services. It has saved us a lot of time.


Working with IIS

Navigation: Working with IIS and Services >

Working with IIS

 Return to chapter overview

Configuring IIS for use with ISAPI

We assume that you are familiar with IIS. This is not a topic we can provide advice for.

That said, we wrote a blog article about configuring IIS for use with ISAPI.

Example ISAPI

We have provided an example ISAPI extension configured for use with Thread Validator.

This example is provided as source code and project files. You will need to build it yourself, you may need to change an include path to find the appropriate headers. The resulting ISAPI will need to be copied to your website for testing and the website configured to allow the ISAPI to execute (please see the above mentioned blog article for details on that).

You can find the example ISAPI in the isapiExample folder in the Thread Validator installation directory.

Using Thread Validator with IIS

IIS is a service application. It runs as one of the more restricted applications on Microsoft Windows.

Thread mapped files created by IIS cannot be opened by user mode programs (Thread Validator, for example). DLLs, executables and files cannot be opened by IIS except if they are in directories which IIS has access to. These are security measures intended to make your computer secure from attack.

These security measures make it hard for tools like Thread Validator to work.

·We have to communicate settings information to Thread Validator via text file

·All DLLs and helper programs we want to use need to be copied to the web root (or a subdirectory within the web root) so that they can be used.

·We need to have our own data transport because our usual high speed memory mapped data transport is not available.

It's also not possible to launch IIS or inject into a running IIS instance.

The only way to work with IIS is by using the NT Service API, and using the svlTVStub_StartThreadValidatorForIIS() function instead of svlTVStub_StartThreadValidator().

We've provide some example code to show you how to attach and detach from your ISAPI extension.

Workflow

1) Start monitoring your ISAPI by using the Monitor ISAPI dialog.

menu Launch menu instructionStep IIS menu instructionStep Monitor ISAPI...

2) When you have finished interacting with the web pages that use the ISAPI component shutdown IIS, wait for Thread Validator's status to indicate "Ready" and examine the results.

menu Launch menu instructionStep IIS menu instructionStep Stop IIS


Example Source Code

Navigation: Working with IIS and Services >

Example Source Code

 Return to chapter overview

Service Example

Example demonstrating how to monitor a service.

Also see the example service that ships with Performance Validator.

You can find this in the \examples\service directory in the Performance Validator install directory.

Also see the example service and child process that ships with Performance Validator.

You can find this in the \examples\serviceWithAChildProcess directory in the Performance Validator install directory.

IIS Example

Example demonstrating how to monitor an ISAPI DLL.

Also see the example ISAPI DLL that ships with Performance Validator.

You can find this in the \examples\isapiExample directory in the Performance Validator install directory.


Example Service Source Code

Navigation: Working with IIS and Services > Example Source Code >

Example Service Source Code

 Return to chapter overview

Show/Hide Hidden Text

Where to put your code

When you use the functions to load and unload Thread Validator from your service, it is important that you put the function calls in the correct place in your software.

The correct place to put them is in a 'balanced' location, such that you would expect no memory leaks to occur between the load and the unload function call, assuming the service was working correctly.

Typically, this means that Thread Validator is:

·loaded as the first action in the service_main() function

·unloaded just before the service control manager is informed of the stopped status

The source code shown below shows an example service_main() function used in a service, demonstrating where to load and unload Thread Validator.

The long comment covers problems with the way services are stopped and what may be displayed in a debugger if this happens.

seeAlso The code is extracted from service\service.cpp, part of the full example of an NT service, client and a utility for controlling whether the service uses Thread Validator.

doc-collapse-icon Show the C++ example service_main() function

void serviceCallback(void *userParam)
{
// just tell the Service Control Manager that we are still busy
// in this example userParam is not used

static DWORD dwCheckPoint = 1;

ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
ssStatus.dwServiceSpecificExitCode = 0;

ssStatus.dwControlsAccepted = 0;

ssStatus.dwCurrentState = dwCurrentState;
ssStatus.dwWin32ExitCode = dwWin32ExitCode;
ssStatus.dwWaitHint = dwWaitHint;
ssStatus.dwCheckPoint = dwCheckPoint++;

// Report the status of the service to the service control manager.

return SetServiceStatus(sshStatusHandle, &ssStatus);
}

//-NAME---------------------------------
// service_main
//.DESCRIPTION..........................
//
// Initializes the service, then calls the function to do the work.
// This function is typically where you will load and unload Thread Validator
//
//.PARAMETERS...........................
//
// dwArgc - number of command line arguments
// lpszArgv - array of command line arguments
//
//.RETURN.CODES.........................
//--------------------------------------

static CRITICAL_SECTION nativeExampleCritSect;

void WINAPI service_main(DWORD dwArgc,
LPTSTR *lpszArgv)
{
if (bLogging)
{
svlTVStub_setLogFileName(SZLOGFILENAME);
svlTVStub_deleteLogFile();
}

InitializeCriticalSection(&nativeExampleCritSect);
InitializeCriticalSection(&testCritSect);

// register our service control handler:

sshStatusHandle = RegisterServiceCtrlHandler(TEXT(SZSERVICENAME), service_ctrl);
if (sshStatusHandle != 0)
{
DWORD dwErr = 0;

// **TV_EXAMPLE** start

if (bThreadValidator)
{
// load Thread Validator (but if monitoring a 32 bit service with Thread Validator x64 use svlTVStub_LoadThreadValidator6432())

if (bLogging)
{
svlTVStub_writeToLogFileW(_T("About to load Thread Validator\r\n"));
}

SVL_SERVICE_ERROR errCode;

#ifdef IS6432
// x86 with x64 GUI
errCode = svlTVStub_LoadThreadValidator6432();
#else //#ifdef IS6432
// x86 with x86 GUI
// x64 with x64 GUI
errCode = svlTVStub_LoadThreadValidator();
#endif //#ifdef IS6432
if (bLogging)
{
if (errCode != SVL_OK)
{
DWORD lastError;

lastError = GetLastError();
svlTVStub_writeToLogFileW(_T("Thread Validator load failed. \r\n"));
svlTVStub_writeToLogFileLastError(lastError);
svlTVStub_writeToLogFile(errCode);

svlTVStub_dumpPathToLogFile();
}
else
{
svlTVStub_writeToLogFileW(_T("Thread Validator load success. \r\n"));
}
}

// setup a service callback so that the Service Control Manager knows the service
// is starting up even if instrumentation takes longer than 10 seconds (which it will
// for a non-trivial application)

if (bLogging)
svlTVStub_writeToLogFileW(_T("Setting service callback Thread Validator\r\n"));

errCode = svlTVStub_SetServiceCallback(serviceCallback, // the callback
NULL); // some user data (we don't have any, so set NULL)
if (bLogging)
{
if (errCode != SVL_OK)
{
svlTVStub_writeToLogFileW(_T("Setting service callback failed. \r\n"));
svlTVStub_writeToLogFile(errCode);
}

svlTVStub_writeToLogFileW(_T("Starting Thread Validator\r\n"));
}

errCode = svlTVStub_StartThreadValidator();
if (bLogging)
{
if (errCode != SVL_OK)
{
DWORD lastError;

lastError = GetLastError();
svlTVStub_writeToLogFileW(_T("Starting Thread Validator failed. \r\n"));
svlTVStub_writeToLogFileLastError(lastError);
svlTVStub_writeToLogFile(errCode);
}

svlTVStub_writeToLogFileW(_T("Finished loading Thread Validator\r\n"));
}
}
else
{
if (bLogging)
svlTVStub_writeToLogFileW(_T("Not using Thread Validator, DLL will not be loaded\r\n"));
}

// **TV_EXAMPLE** end

// SERVICE_STATUS members that don't change in example

ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
ssStatus.dwServiceSpecificExitCode = 0;

// report the status to the service control manager.

if (ReportStatusToSCMgr(SERVICE_START_PENDING, // service state
NO_ERROR, // exit code
3000)) // wait hint
{
// deliberately enter a critical section so that we can see that with Thread Validator

EnterCriticalSection(&nativeExampleCritSect);

// do work

dwErr = ServiceStart(dwArgc, lpszArgv);

// finished doing work

LeaveCriticalSection(&nativeExampleCritSect);
}

// **TV_EXAMPLE** start

if (bThreadValidator)
{
// unload Thread Validator here
// IMPORTANT.
// Because of the way services work, you can find that this thread which is trying to gracefully unload
// ThreadValidator is ripped from under you by the operating system. This prevents Thread Validator from
// removing all its hooks successfully. If Thread Validator does not remove all of its hooks successfully
// because this happens, then you may get a crash when the service stops.
//
// An alternative fix is to spawn another thread which then unloads Thread Validator.
// See the code for ServiceStop() for comments relating to this.
//
// A callstack for such a crash is shown below. If you see this type of crash you need to put you code to
// unload Thread Validator somewhere else. The stack trace may be different, but a fundamental point is the
// code calling through doexit(), exit() and ExitProcess()
//
//NTDLL! 77f64e70()
//SVLTHREADVALIDATORSTUB!
//MSVCRT! 78001436()
//MSVCRT! 7800578c()
//DBGHELP! 6d55da25()
//DBGHELP! 6d55de83()
//DBGHELP! 6d53705d()
//DBGHELP! 6d51cc69()
//DBGHELP! 6d51f6e8()
//DBGHELP! 6d524ebf()
//DBGHELP! 6d52a7b0()
//DBGHELP! 6d52b00a()
//DBGHELP! 6d526487()
//DBGHELP! 6d5264d7()
//DBGHELP! 6d5264f7()
//SVLTHREADVALIDATORSTUB!
//SVLTHREADVALIDATORSTUB!
//SVLTHREADVALIDATORSTUB!
//SVLTHREADVALIDATORSTUB!
//SVLTHREADVALIDATORSTUB!
//SVLTHREADVALIDATORSTUB!
//SVLTHREADVALIDATORSTUB!
//SVLTHREADVALIDATORSTUB!
//MSVCRT! 78001436()
//MSVCRT! 780057db()
//KERNEL32! 77f19fdb()
//SVLTHREADVALIDATORSTUB! ExitProcess hook
//doexit(int 0x00000000, int 0x00000000, int 0x00000000) line 392
//exit(int 0x00000000) line 279 + 13 bytes
//mainCRTStartup() line 345
//KERNEL32! 77f1b9ea()

svlTVStub_UnloadThreadValidator();
}

// **TV_EXAMPLE** end

// try to report the stopped status to the service control manager.

(VOID)ReportStatusToSCMgr(SERVICE_STOPPED, dwErr, 0);
}

DeleteCriticalSection(&testCritSect);
DeleteCriticalSection(&nativeExampleCritSect);

return;
}

void WINAPI service_main(DWORD dwArgc, LPTSTR *lpszArgv)

{

// load Thread Validator here

svlTVStub_LoadThreadValidator();

         // register our service control handler:

sshStatusHandle = RegisterServiceCtrlHandler(TEXT(SZSERVICENAME), service_ctrl);

// SERVICE_STATUS members that don't change in example

ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;

ssStatus.dwServiceSpecificExitCode = 0;

// report the status to the service control manager.

if (!ReportStatusToSCMgr(SERVICE_START_PENDING, NO_ERROR, 3000))

{

if (sshStatusHandle)

ReportStatusToSCMgr(SERVICE_STOPPED, dwErr, 0);

}

// do the work of the service

doWork(dwArgc, lpszArgv);

// unload Thread Validator here

// IMPORTANT.

// Because of the way services work, you can find that this thread which is trying to gracefully unload

// ThreadValidator is ripped from under you by the operating system. This prevents Thread Validator from

// removing all its hooks successfully. If Thread Validator does not remove all of its hooks successfully

// because this happens, then you may get a crash when the service stops.

//

// A callstack for such a crash is shown below. If you see this type of crash you need to put your code to

// unload Thread Validator somewhere else. The stack trace may be different, but a fundamental point is the

// code calling through doexit(), exit() and ExitProcess()

//

//NTDLL! 77f64e70()

//SVLTHREADVALIDATORSTUB!

//MSVCRT! 78001436()

//MSVCRT! 7800578c()

//DBGHELP! 6d55da25()

//DBGHELP! 6d55de83()

//DBGHELP! 6d53705d()

//DBGHELP! 6d51cc69()

//DBGHELP! 6d51f6e8()

//DBGHELP! 6d524ebf()

//DBGHELP! 6d52a7b0()

//DBGHELP! 6d52b00a()

//DBGHELP! 6d526487()

//DBGHELP! 6d5264d7()

//DBGHELP! 6d5264f7()

//SVLTHREADVALIDATORSTUB!

//SVLTHREADVALIDATORSTUB!

//SVLTHREADVALIDATORSTUB!

//SVLTHREADVALIDATORSTUB!

//SVLTHREADVALIDATORSTUB!

//SVLTHREADVALIDATORSTUB!

//SVLTHREADVALIDATORSTUB!

//SVLTHREADVALIDATORSTUB!

//MSVCRT! 78001436()

//MSVCRT! 780057db()

//KERNEL32! 77f19fdb()

//SVLTHREADVALIDATORSTUB! ExitProcess hook

//doexit(int 0x00000000, int 0x00000000, int 0x00000000) line 392

//exit(int 0x00000000) line 279 + 13 bytes

//mainCRTStartup() line 345

//KERNEL32! 77f1b9ea()

svlTVStub_UnloadThreadValidator();

// try to report the stopped status to the service control manager.

if (sshStatusHandle)

ReportStatusToSCMgr(SERVICE_STOPPED, dwErr, 0);

// tried putting the call to svlTVStub_UnloadThreadValidator(); here but often the thread

// was pulled from under it by the operating system

return;

}


Example ISAPI Source Code

Navigation: Working with IIS and Services > Example Source Code >

Example ISAPI Source Code

 Return to chapter overview

Show/Hide Hidden Text

Where to put your code

When you use the functions to load and unload Thread Validator from your service, it is important that you put the function calls in the correct place in your ISAPI extension.

Typically, this means that Thread Validator is:

·loaded as the first action in the GetExtensionVersion() function of your ISAPI extension.

·unloaded in the TerminateExtension() function of your ISAPI extension.

Example source code

The source code shown below shows an example GetExtensionVersion() and an example TerminateExtension() used in an ISAPI, demonstrating where to load and unload Thread Validator.

This example code logs errors. We strongly recommend that you do this in your example. Because IIS is a protected process that can't communicate to the outside world except via HTTP/HTTPS when anything fails during the loading and start of Thread Validator the only means we have of communicating that failure to you is via the log file. Please use the log file, it will make debugging any mistakes very much easier, simpler and quicker than any other method.

This process is almost identical to working with a regular service, except that svlTVStub_StartThreadValidator() is replaced with svlTVStub_StartThreadValidatorForIIS().

This example assumes the web root is located C:\\testISAPIWebsite

doc-collapse-icon Show the C++ example ISAPI functions

#include "svlTVStubService.h"

#include "svlServiceError.h"

BOOL WINAPI GetExtensionVersion(HSE_VERSION_INFO *pVer)

{

// some setup work to define what the extension is

pVer->dwExtensionVersion = HSE_VERSION;

strncpy(pVer->lpszExtensionDesc, "Validate ISAPI Extension", HSE_MAX_EXT_DLL_NAME_LEN);

// load Validator here

svlTVStub_setLogFileName(L"C:\\testISAPIWebsite\\svl_TV_log.txt");

svlTVStub_deleteLogFile();

SVL_SERVICE_ERROR   errCode;

#ifdef IS6432

// x86 with x64 GUI

errCode = svlTVStub_LoadThreadValidator6432();

#else   //#ifdef IS6432

// x86 with x86 GUI

// x64 with x64 GUI

errCode = svlTVStub_LoadThreadValidator();

#endif   //#ifdef IS6432

if (errCode != SVL_OK)

{

             DWORD   lastError;

             lastError = GetLastError();

             svlTVStub_writeToLogFileW(L"Thread Validator load failed. \r\n");

             svlTVStub_writeToLogFileLastError(lastError);

             svlTVStub_writeToLogFile(errCode);

             svlTVStub_dumpPathToLogFile();

}

else

{

             svlTVStub_writeToLogFileW(L"Thread Validator load success. \r\n");

errCode = svlTVStub_StartThreadValidatorForIIS();

if (errCode != SVL_OK)

{

DWORD   lastError;

lastError = GetLastError();

svlTVStub_writeToLogFileW(L"Starting Thread Validator failed. \r\n");

svlTVStub_writeToLogFileLastError(lastError);

svlTVStub_writeToLogFile(errCode);

}

svlTVStub_writeToLogFileW(L"Finished starting Thread Validator\r\n");

}

return TRUE;

}

BOOL WINAPI TerminateExtension(DWORD        dwFlags)

{

// unload Validator here

svlTVStub_UnloadThreadValidator();

return TRUE;

}


Examples

Navigation: »No topics above this level«

Examples

 Return to chapter overview

The need for examples

We know Thread Validator is a complex product, but the programs that need to be tested are often even more complex, and are certainly all different.

For this reason, it's important to be able to test and demonstrate the features of Thread Validator in an easy and repeatable way.

The example application provides a safe test demonstration:

·It lets you trigger time consuming calculations in your own time so you can observe performance hotspots

·It provides source code to demonstrate usage, correctly or otherwise!

This section has help for the example application followed by some examples of using it in conjunction with Thread Validator.

Some additional projects provide examples of using NT Services.

All example projects are supplied as source code and projects. You'll need to build the examples or services before you can use them.


Example Application

Navigation: Examples >

Example Application

 Return to chapter overview

The example application

The example application is a great way to explore the capabilities of Thread Validator.

The source and projects are included in the installation, but you'll need to build the example application yourself.

You can then use nativeExample.exe in conjunction with Thread Validator to generate thread errors, waits, deadlocks and potential deadlocks, and monitor the behaviour of the application as you use it.

After launching the example application from Thread Validator, the following dialog appears showing counters reflecting the status of various tests you can run from the Test menu.

How to use these examples

The best way to understand how Thread Validator works is by example.

We recommend launching the example application from Thread Validator and observing how the menu actions affect threads, locks and synchronization objects.

Examining the source code is the best way to see what's going on in the example application.

The examples create threads and engage critical sections in different scenarios. For convenience, below we have provided the source locations where each menu action runs a test.

Most test locations are in the CTeststakView class of nativeExample\TESTSVW.CPP

File menu

menu File menu instructionStep Exit instructionStep closes the example application

Test menu

menu Test menu instructionStep ...

instructionStep 2 Thread deadlock | OnHandlesStartthread1() OnHandlesStartthread2() Creates two named threads that increment counter1 and counter 2 in the midst of repeatedly locking and unlocking two critical sections with an interim Sleep. Sooner or later the two threads will deadlock and the counters being updated in the view will stop.
instructionStep 3 Thread deadlock | OnHandlesStartthreadA() OnHandlesStartthreadB() OnHandlesStartthreadC() Creates three named threads that increment counterA,B,C in the midst of repeatedly locking and unlocking three critical sections with interim Sleeps. Sooner or later the threads will deadlock and the counters being updated in the view will stop.
instructionStep Start 2 Thread deadlock | OnTestStart2ThreadDeadlock() Combines the above 2 Thread deadlock operations into a single function.
instructionStep Start 3 Thread deadlock | OnTestStart3threaddeadlock() Creates three named threads that increment counter3A,3B,3C in the midst of repeatedly locking and unlocking two of three critical sections with no interim Sleeps, and with a circular dependency. The threads will deadlock and the counters being updated in the view will stop.
instructionStep Start 3 Thread deadlock (two) | OnTestStart3threaddeadlock2() Similar to above but with interim Sleeps and no circular dependency. The threads will still soon deadlock and the counters being updated in the view will stop.
instructionStep Start 2 Thread deadlock with infinite wait | OnTestStart3threaddeadlockwithinfinitewait() See comments in this function for an explanation. Deadlock occurs when CounterIa,Ib stop incrementing.
instructionStep Start 2 Thread deadlock with thread suspend | OnTestStart3threaddeadlockwiththreadsuspend() See comments in this function for an explanation. Deadlock occurs when CounterSa,Sb stop incrementing.
instructionStep Start 2 Thread deadlock with infinite sleep | OnTestStart3threaddeadlockwithinfinitesleep() See comments in this function for an explanation. Deadlock occurs when CounterSleepIa,Ib stop incrementing.
instructionStep Bad lock strategy example | OnTestBadlockstrategyexample() Create two threads that both use the same incorrect lock strategy. These two threads exhibit a bad lock strategy, but will probably not deadlock each other for a long time. Deadlock occurs when CounterBa,Bb stop changing.
instructionStep Good lock strategy example | OnTestGoodlockstrategyexample() Create two threads that both uses a good lock strategy. These two threads should never deadlock. Deadlock occurs when CounterGa,Gb,Gc shouldn't stop changing.
instructionStep Good lock strategy example (faster) | OnTestGoodlockstrategyexampleEx() As above but much faster.
instructionStep Create deadlock then determine stack traces | OnTestCreatedeadlockthendeterminestacktraces() Forces a deadlock with two threads and leaves them running so that Thread Validator can determine stack traces
instructionStep Recursion test | OnTestRecursiontest() Enters the same critical section 3 times in a row.
instructionStep Leave non-entered critical section | OnTestLeavenonenteredcriticalsection() Enters a critical section once and then leaves it twice without entering it again.
instructionStep Delete still active critical section | OnTestDeletestillactivecriticalsection() Enters a critical section once and then deletes it without leaving.
instructionStep Leave critical sections in the wrong order | OnTestLeavecriticalsectionsinthewrongorder() Simple test to lock three sections and then unlock them in the same order instead of the reverse order.
instructionStep Potential deadlock 2 threads | OnTestPotentialdeadlock2threads() Two threads enter and leave four critical sections, but two of them are in different orders to the other thread. There is a potential for deadlock here.
instructionStep Potential deadlock 3 threads | OnTestPotentialdeadlock3threads() Two threads enter and leave four critical sections, but three of them are in different orders to the other thread. There is a potential for deadlock here.
instructionStep Test ExitThread() | OnTestTestexitthread() Creates two named threads, one of which explicitly calls ExitThread.
instructionStep Force crash inside a locked critical section (part 1) | OnTestForcecrashinsidecrtleavingapermanentlockoncrtthendeadlock() Arranging a crash inside a critical section while it is locked and failing to unlock it - so as to show the deadlock this can cause (infinite wait on a contended lock) - see part 2. These functions has changed their mechanism due to Microsoft CRT fixes.
instructionStep Force crash inside a locked critical section (part 2) | OnTestForcecrashinsidecrtpart2() When preceded by part 1 (above) this call should deadlock (cause an infinite wait on a contended lock) as the lock is held by the waiting main UI thread that crashed before unlocking the critical section.

Help menu

menu Help menu instructionStep ...

instructionStep About Thread Validator Tester

nativeExampleApp::OnAppAbout()

Shows a simple information dialog using code in nativeExample.cpp


Building the example application

Building the example applications

Navigation: Examples > Example Application >

Building the example applications

 Return to chapter overview

Where to find the example applications

The example projects are in the examples sub-directory of the Thread Validator installation directory.

If the directory is not present, reinstall your software and choose custom or full installation to include the examples.

note To avoid permission issues creating some of the output files, you may need to copy the project out of the Program Files folder, if that's where it's installed.

Solutions and projects

For modern Visual Studio use examples.sln to build all the examples. Some may not build on the first pass because a dependency hasn't yet been built. Two or three builds should resolve that.

·examples.sln instructionStep for Microsoft® Visual Studio / .net

If you're using Visual Studio 6, build nativeExample.dsp and the dependent projects in dllADependentOnB.dsp, dllBDependentOnC.dsp, dllC.dsp.

Configurations

There are only two configurations in each project:

·Debug Non Link / Release Non Link instructionStep with the wWinMainCRTStartup unicode entry point

Using Visual Studio Express?

You might find you can't build the example application with Express versions of Visual Studio because it doesn't provide all the necessary libraries.

If that's the case, try searching for the missing libraries in one of the freely available Windows SDKs externalLink from the Microsoft website.

note If you use Visual Studio Express to build your own application, Thread Validator will still work with it just fine.


Example NT Service

Navigation: Examples >

Example NT Service

 Return to chapter overview

The example NT Service

As well as the example application, an example service is provided along with details about building it.

There's also an example client.

The example service demonstrates how to use the NT Service API to call the two functions required to use Thread Validator with NT Services.

The following tasks are performed when the service is started:

· Loads the Thread Validator stub DLL into the service

·Performs the normal work of the service until it's stopped

· Unloads the Thread Validator stub DLL from the service

·Informs the service control manager that a stop is pending

seeAlso Read more about working with NT Services.


Building the example service

Navigation: Examples > Example NT Service >

Building the example service

 Return to chapter overview

Example service project files

The example project can be found in the service sub-directory in the directory where Thread Validator was installed.

If the directory is not present, reinstall your software and choose custom or full installation.

There are two project files in the directory:

·service.dsp instructionStep for Microsoft® Developer Studio® 6.0

·service.vcproj instructionStep for Microsoft® Visual Studio / .net

Configurations

There are just two simple configurations in each project:

·Debug / Release instructionStep dynamically links to the svlTVStubService(_x64).lib demonstrating use with the NT Service API

Using the service

To run the service, you will need administrator privileges.

Once the service is installed and started, you can use the provided serviceClient to interact with it.

The service is named SVL x86/x64 TV Simple Service in the control panel Services dialog.

Once you start the service, it will show as 'Running'

The service provides the following command line options:

·-install instructionStep Install the service

·-remove instructionStep Uninstall the service

·-start instructionStep Start the service

·-stop instructionStep Stop the service

·-debug instructionStep Run as a console application for debugging

·-? instructionStep Display the help message

·-help instructionStep Display the help message

Open a cmd prompt in administrator mode, navigate to the location of the service executable, and use one of these commands to install, remove, start, stop the service.

Examples:

serviceTV.exe -install

serviceTV.exe -start

serviceTV.exe -stop

serviceTV.exe -remove


Building the example client

Navigation: Examples > Example NT Service >

Building the example client

 Return to chapter overview

If you've already built the sample service, the build process is very similar.

Project files

The example project can be found in the serviceClient sub-directory in the directory where Thread Validator was installed.

If the directory is not present, reinstall your software and choose custom or full installation.

There are two project files in the directory:

·serviceClient.dsp instructionStep for Microsoft® Developer Studio® 6.0

·serviceClient.vcproj instructionStep for Microsoft® Visual Studio / .net

Configurations

There are two configurations in each project:

·Debug / Release instructionStep dynamically links to the svlTVStubService(_x64).lib demonstrating use with the NT Service API

Using serviceClient

The client interacts with the running service and provides the following command line options:

·-string instructionStep Sends the text that follows the option (quoted if it has spaces) to the service

If the service is running the service will return the string in reverse order:

·-? instructionStep Display the help message (usage)

·-help instructionStep Display the help message (usage)

If the service is not running you'll see a message including something like "CallNamedPipe failed".


Building the example service utility

Navigation: Examples > Example NT Service >

Building the example service utility

 Return to chapter overview

The serviceMutex project demonstrates a way of controlling whether Thread Validator is used without having to rebuild your service.

Project files

The example project can be found in the serviceMutex sub-directory in the directory where Thread Validator was installed.

If the directory is not present, reinstall your software and choose custom or full installation.

There are two project files in the directory:

·serviceMutex.dsp instructionStep for Microsoft® Developer Studio® 6.0

·serviceMutex.vcproj instructionStep for Microsoft® Visual Studio / .net

Configurations

There are just two configurations in each project:

·Debug / Release instructionStep dynamically links to the svlTVStubService(_x64).lib demonstrating use with the NT Service API

Using the service utility

The utility provides a dialog box interface to allow the control over the creation of a mutex object with the name specified in the service.h header file.

Only if the service is started with the mutex created, does the service load Thread Validator.

If you don't like using mutexes in this way, you could change the code in the service and the utility to communicate through shared memory, a registry setting, or another method of your choice.


Monitoring the service

Navigation: Examples > Example NT Service >

Monitoring the service

 Return to chapter overview

Once the example service and example client has been built, the next step is to test them using Thread Validator.

Installing the service

If you haven't installed the service, do the following:

·open an administrator mode cmd prompt

·navigate to the directory containing the serviceTV.exe to install

·serviceTV.exe -install

Monitoring the service

Prerequisites

·example service has been installed, but not started (if service has been started, stop the service)

·example service and example client have been built

The following process is used to monitor the application launched by the service:

·From the Launch menu choose Services > Monitor a Service...

·The Monitor a service dialog is displayed

·Use Browse... to open the file chooser dialog and choose the service that will be monitored by Thread Validator.

·Click OK

·Thread Validator sets up a variety of parameters then displays a dialog box asking you to start you service. Click OK to dismiss the dialog

·Start your service. For the example serviceTV.exe do the following

oopen an administrator mode cmd prompt

onavigate to the directory containing the serviceTV.exe to start

oserviceTV.exe -start

oserviceTV.exe starts will be monitored by Thread Validator

·The target application contacts Thread Validator

·Data is collected until the service finishes executing

·Thread Validator displays the results


Example Application Launched from a Service

Navigation: Examples >

Example Application Launched from a Service

 Return to chapter overview

The example Application launched from a Service

This pair of projects create an application that is launched from a service.

The purpose of this example is to show how to monitor the application that is launched from the service. This is also the same process for monitoring an application launched by an application launched from a service.

This process is subtly different to the method for working with services (see the example service for that).

Service

The service project is serviceWithAChildProcess.vcxproj

The following tasks are performed when the service is started:

·the test application is launched from the service

Application

The application project is serviceChildProcess.vcxproj

The application's first task is to load Thread Validator into the application.

· Loads the Thread Validator stub DLL into the application

·Configures the NT Service API to communicate to Thread Validator

·Does some work that can be monitored by Thread Validator

·Exits

Implementation Details

For implementation details see attachToThreadValidator(); in serviceChildProcess.cpp.

The application will need to link to the NT Service API, for example ..\..\..\svlTVStubService\release_2010_x64\svlTVStubService_x64.lib (for a release x64 EXE/DLL).

Important. Call attachToThreadValidator() as close to the start of your application as possible, before any threads have been created.

seeAlso Read more about working with NT Services.


Building the service and application

Navigation: Examples > Example Application Launched from a Service >

Building the service and application

 Return to chapter overview

Example solution files

The example solution can be found in the examples\serviceWithAChildProcess subdirectory in the directory where Thread Validator was installed.

If the directory is not present, reinstall your software and choose custom or full installation.

Example project files

The example projects can be found in the subdirectories in the directory where Thread Validator was installed.

examples\serviceWithAChildProcess\serviceWithAChildProcess

·serviceWithAChildProcess.vcproj instructionStep for Microsoft® Visual Studio / .net

examples\serviceWithAChildProcess\serviceChildProcess

·serviceChildProcess.vcproj instructionStep for Microsoft® Visual Studio / .net

Configurations

There are a small number of configurations in each project:

·Debug / Release instructionStep dynamically links to the svlTVStubService(_x64).lib demonstrating use with the NT Service API

Using the service

The service is named SVL *** TV Child Process in the control panel services dialog (*** changes depending on the build configuration), and provides the following command line options:

·-install instructionStep Install the service

·-remove instructionStep Uninstall the service

·-start instructionStep Start the service

·-stop instructionStep Stop the service

·-debug instructionStep Run as a console application for debugging

·-? instructionStep Display the help message

·-help instructionStep Display the help message

Open a cmd prompt in administrator mode, navigate to the location of the service executable, and use one of these commands to install, remove, start, stop the service.

Examples:

serviceWithAChildProcess.exe -install

serviceWithAChildProcess.exe -start

serviceWithAChildProcess.exe -stop

serviceWithAChildProcess.exe -remove


Monitoring the application launched from the service

Navigation: Examples > Example Application Launched from a Service >

Monitoring the application launched from the service

 Return to chapter overview

Once the example service and example application are built, the next step is to test them using Thread Validator.

Installing the service

If you haven't installed the service, do the following:

·open an administrator mode cmd prompt

·navigate to the directory containing the serviceWithAProcess.exe to install

·serviceWithAProcess.exe -install

Monitoring the application launched by the service

Prerequisites

·example service has been installed, but not started (if service has been started, stop the service)

·example service and example application have been built (application must use the NT Service API as demonstrated in attachToThreadValidator())

·example application executable is in the same directory as the example service (this is only a requirement for the example)

The following process is used to monitor the application launched by the service:

·From the Launch menu choose Services > Monitor a Service...

·The Monitor a service dialog is displayed

·Use Browse... to open the file chooser dialog and choose the application that will be monitored by Thread Validator. This is the application that is launched by the service. Do not choose the service

·Click OK

·Thread Validator sets up a variety of parameters then displays a dialog box asking you to start you service. Click OK to dismiss the dialog

·Start your service. For the example serviceWithAChildProcess.exe do the following

oopen an administrator mode cmd prompt

onavigate to the directory containing the serviceWithAProcess.exe to start

oserviceWithAProcess.exe -start

oserviceWithAProcess.exe starts and launches the child process serviceChildProcess.exe that will be monitored

·The target application contacts Thread Validator

·Data is collected until the target process finishes executing

·Thread Validator displays the results


Hook Reference

Navigation: »No topics above this level«

Hook Reference

 Return to chapter overview

Enabling and disabling the hooks

The lists on the following page show the hooks used by Thread Validator and are for reference only.

New hooks may be added in later versions of the software.

You can individually enable and disable the hook settings as well as whole groups at a time.

Hooking DLLS

You can enable or disable hooks on a per-DLL basis using the Hooked DLLs settings.


Synchronization Hooks

Navigation: Hook Reference >

Synchronization Hooks

 Return to chapter overview

These hooks are used by Thread Validator and are for reference only.

New hooks may be added in later versions of the software.

You can individually enable and disable the hook settings as well as whole groups at a time.

Critical sections

·DeleteCriticalSection()

·EnterCriticalSection()

·InitializeCriticalSection()

·InitializeCriticalSectionEx()

·InitializeCriticalSectionAndSpinCount()

·LeaveCriticalSection()

·SetCriticalSectionSpinCount()

·TryEnterCriticalSection()

Events

·CreateEventA()

·CreateEventW()

·OpenEventA()

·OpenEventW()

·PulseEvent()

·SetEvent()

·ResetEvent()

File

·CreateFileA()

·CreateFileW()

·FindCloseChangeNotification()

·FindFirstChangeNotificationA()

·FindFirstChangeNotificationW()

Jobs

·CreateJobObjectA()

·CreateJobObjectW()

Misc

·QueueUserAPC()

·Sleep()

·SleepEx()

Mutexes

·CreateMutexA()

·CreateMutexW()

·OpenMutexA()

·OpenMutexW()

·ReleaseMutex()

Process

·CreateProcessA()

·CreateProcessW()

·CreateProcessAsUserA()

·CreateProcessAsUserW()

·CreateProcessWithLogonW()

·DuplicateHandle()

·FreeLibraryAndExitThread()

·OpenProcess()

·TerminateProcess()

Semaphores

·CreateSemaphoreA()

·CreateSemaphoreW()

·OpenSemaphoreA()

·OpenSemaphoreW()

·ReleaseSemaphore()

Threads

·CloseHandle()

·CreateRemoteThread()

·CreateThread()

·ExitThread()

·OpenThread()

·ResumeThread()

·SuspendThread()

·TerminateThread()

Timers

·CancelWaitableTimer()

·CreateWaitableTimerA()

·CreateWaitableTimerW()

·OpenWaitableTimerA()

·OpenWaitableTimerW()

·SetWaitableTimer()

Timer Queues

·ChangeTimerQueueTimer()

·CreateTimerQueue()

·CreateTimerQueueTimer()

·DeleteTimerQueue()

·DeleteTimerQueueEx()

·DeleteTimerQueueTimer()

Waits

·MsgWaitForMultipleObjects()

·MsgWaitForMultipleObjectsEx()

·SignalObjectAndWait()

·RegisterWaitForSingleObject()

·RegisterWaitForSingleObjectEx()

·UnregisterWait()

·UnregisterWaitEx()

·WaitForSingleObject()

·WaitForMultipleObjects()

·WaitForSingleObjectEx()

·WaitForMultipleObjectsEx()


Debug Information, Symbols, Filenames, Line Numbers

Navigation: »No topics above this level«

Debug Information, Symbols, Filenames, Line Numbers

 Return to chapter overview

Depending on which IDE or compiler/linker combination the process to create debug information to ensure that you have symbols, filenames and line numbers is different.

This section shows you what to do to ensure you have symbols for your compiler and linker.


Visual Studio

Navigation: Debug Information, Symbols, Filenames, Line Numbers >

Visual Studio

 Return to chapter overview

Enabling debug information in Visual Studio has changed over the years depending on the version of Visual Studio you are using.

It's generally the same, but there have been some changes in recent versions that can cause confusion.

By default debug configurations create debug information, but for some versions of Visual Studio, release configurations do not create debug information.

You need to set both compiler and linker settings to get debug information. Setting just one or the other will not give you debug information you can use.

Configurations

In the help below we show you how to modify one configuration, for example Release | Win32.

You need to modify all configurations appropriately. Release, Debug, Win32, Win64 and any other configurations you are using.

Visual Studio 2017 - 2021

Compiler Settings

Linker Settings

If you're building on a different machine to the machine you're working on (for example a build server), you should choose /DEBUG:FULL, not /DEBUG or /DEBUG:FASTLINK.

When you have edited the project options you need to rebuild the software for the options to take effect and create the debug information.

Visual Studio 2010 - 2015

Compiler Settings

Linker Settings

When you have edited the project options you need to rebuild the software for the options to take effect and create the debug information.

Visual Studio 2002 - 2008

Compiler Settings

Linker Settings

When you have edited the project options you need to rebuild the software for the options to take effect and create the debug information.

Visual Studio 6.0

Compiler Settings

Linker Settings

When you have edited the project options you need to rebuild the software for the options to take effect and create the debug information.


C++ Builder

Navigation: Debug Information, Symbols, Filenames, Line Numbers >

C++ Builder

 Return to chapter overview

Debug information can be provided using two methods.

·Debugging information (TDS or DWARF format)

·MAP files

Debugging Information

Debug configurations of C++ Builder projects automatically generate debug information that provides symbols, filenames and line numbers.

However the release configurations of C++ Builder projects do not automatically generate debug information. You need to configure that yourself.

Here's how you do that. It's slightly different if you're building 32 bit applications rather 64 bit applications.

You need to set both compiler and linker settings to get debug information. Setting just one or the other will not give you debug information you can use.

32 bit C++ Builder

Project Configuration

Change your project settings to target 32 bit builds.

Compiler Settings

Linker Settings

When you have edited the project options you need to rebuild the software for the options to take effect and create the debug information.

64 bit C++ Builder

Project Configuration

Change your project settings to target 64 bit builds.

Compiler Settings

Linker Settings

When you have edited the project options you need to rebuild the software for the options to take effect and create the debug information.

MAP files

MAP files are not generated by default. You need to enable the option to generate a detailed map file.

The method is the same for 32 bit and 64 bit C++ Builder.

Select the project configuration as shown in the Debugging Information section above, then modify the C++ Linker, Output settings.

Linker Settings

When you have edited the project options you need to rebuild the software for the options to take effect and create the debug information.

Debugging Information or MAP files?

If you can create both debugging information and MAP files which should I use?

Thread Validator uses this information to provide symbols, filenames and line numbers in stack traces.

For this purpose it doesn't matter whether you use Debugging Information or MAP files.


Delphi

Navigation: Debug Information, Symbols, Filenames, Line Numbers >

Delphi

 Return to chapter overview

Debug information can be provided using two methods.

·Debugging information (TDS format)

·MAP files

Debugging Information

Debug configurations of Delphi projects automatically generate debug information that provides symbols, filenames and line numbers.

However the release configurations of Delphi projects do not automatically generate debug information. You need to configure that yourself.

Here's how you do that. It's slightly different if you're building 32 bit applications rather 64 bit applications.

You need to set both compiler and linker settings to get debug information. Setting just one or the other will not give you debug information you can use.

32 bit Delphi

Project Configuration

Change your project settings to target 32 bit builds.

Compiler Settings

Linker Settings

When you have edited the project options you need to rebuild the software for the options to take effect and create the debug information.

64 bit Delphi

Project Configuration

Change your project settings to target 64 bit builds.

Compiler Settings

Linker Settings

When you have edited the project options you need to rebuild the software for the options to take effect and create the debug information.

MAP files

MAP files are not generated by default. You need to enable the option to generate a detailed map file.

The method is the same for 32 bit and 64 bit Delphi.

Select the project configuration as shown in the Debugging Information section above, then modify the Delphi Compiler, Linking settings.

Linker Settings

When you have edited the project options you need to rebuild the software for the options to take effect and create the debug information.

Debugging Information or MAP files?

If you can create both debugging information and MAP files which should I use?

Thread Validator uses this information to provide symbols, filenames and line numbers in stack traces.

For this purpose it doesn't matter whether you use Debugging Information or MAP files.


MingW, gcc, g++

Navigation: Debug Information, Symbols, Filenames, Line Numbers >

MingW, gcc, g++

 Return to chapter overview

The following compiler options are available if you are using MingW, gcc or g++.

-g

This is the default debug format. This will normally choose the DWARF symbol format.

-gdwarf

The DWARF symbol format.

-gstabs

The STABS symbol format.

-gCoff

The COFF symbol format. This does create a lot of unnecessary symbols, making symbol parsing slower.


Dev C++

Navigation: Debug Information, Symbols, Filenames, Line Numbers >

Dev C++

 Return to chapter overview

Dev C++ uses the gcc and g++ compilers.

The following compiler options are available if you are using gcc or g++.

-g

This is the default debug format. This will normally choose the DWARF symbol format.

-gdwarf

The DWARF symbol format.

-gstabs

The STABS symbol format.

-gCoff

The COFF symbol format. This does create a lot of unnecessary symbols, making symbol parsing slower.

You can edit the compiler and linker options by choosing Project Options... from the Project menu.

Compiler and Linker options

When you have edited the project options you need to rebuild the software for the options to take effect and create the debug information.


Salford Software FORTRAN 95

Navigation: Debug Information, Symbols, Filenames, Line Numbers >

Salford Software FORTRAN 95

 Return to chapter overview

Salford FORTRAN95 symbolic information is embedded in the .exe/.dll as COFF (Common Object File Format) information, with some proprietary extensions to Salford Software (which they have kindly shared with us).

Please consult the documentation for Salford FORTRAN95 to include debug information (including filenames and line numbers) in the COFF information.

If you still have problems, please contact us giving as much detail as possible, including what you've tried.


Metrowerks

Navigation: Debug Information, Symbols, Filenames, Line Numbers >

Metrowerks

 Return to chapter overview

Metrowerks symbolic information is embedded in the .exe/.dll as CodeView information.

Please consult the documentation for CodeWarrior in order to include debug information (including filenames and line numbers) in the CodeView information.

If you still have problems, please contact us giving as much detail as possible, including what you've tried.


Visual Basic 6

Navigation: Debug Information, Symbols, Filenames, Line Numbers >

Visual Basic 6

 Return to chapter overview

To get debug symbols for Visual Basic you need to open the Properties dialog box from the Project menu (you'll find it at the bottom of the menu).

When you have changed your project properties you need to build the application.

Go to the File menu and choose Make <projectname.exe>.


Frequently Asked Questions

Navigation: »No topics above this level«

Frequently Asked Questions

 Return to chapter overview

Here's a brief description about the type of question included in each of the following sections:

· General questions

How Thread Validator works and how to do a few of the more common tasks.

· Not getting results

Missing or unhooked data and not finding the data or callstacks you expected.

· Seeing unexpected data

The data you are finding looks wrong or is unexpected.

· Crashes and error reports

Your program crashes with Thread Validator or Thread Validator itself has a problem.

· DbgHelp

Troubleshooting search paths for DbgHelp.dll, and finding or installing different versions.

· System and environment

Your environment on the machine you are using Thread Validator with.


General Questions

Navigation: Frequently Asked Questions >

General Questions

 Return to chapter overview

Show/Hide Hidden Text

doc-collapse-icon Does Thread Validator work with NT Services?

Absolutely. There is a help section on working with NT Services.

doc-collapse-icon Why might Inject or Launch fail?

Not using CreateProcess

The Inject and Wait for Application to Start functionality use CreateRemoteThread to inject into an application.

For the reasons below, injection using CreateRemoteThread does not always work.

Common reasons for injection failure

·A missing DLL in your application

Check your application is complete.

·The target application is a .NET application or .NET service

Check your application or service is not written using .NET technology.

·A missing DLL in Thread Validator

Check Thread Validator is installed correctly.

·The application may have started and finished before the DLL could be injected

This only applies if you are launching the application.

·The application security settings do not allow process handles to be opened

·The application is a service and is running with different privileges than Thread Validator

If the application being injected into is a service it is recommended that the service and Thread Validator are both run on the same user account. See the topic on working with NT services.

Application Specific Reasons for Failure

A small percentage of applications/services will not allow any DLL to be injected into them.

The reasons for this are unknown, but our testing shows that the reason for failure to inject is a combination of application, operating system and hardware that causes an inconsistency during injection (we think it is a timing issue) that causes a failure.

Our tests show that on NT 4 about 1% of all applications fail to inject, 2% on Windows 2000 rising to 5% with Windows XP.

We expect that subsequent operating systems (Windows 2003 and Windows Vista) will have higher failure rates.

doc-collapse-icon How do I name a thread?

Some features such as the Callstack tab can use thread names to make things a bit more intuitive.

Windows 10

Use the SetThreadDescription() Win32 API (or the methods described in the next section).

Earlier versions of Windows

From within your application you can provide a name for use by a debugger or debugging tool by using the Win32 RaiseException() API.

Add the function below to your application. This is based on an example from Microsoft and there are other examples available on the web; some specify a buffer size of 8 characters and one terminator, others specify no strict buffer size limit.

doc-collapse-icon Show code

// This function is documented as being callable from outside of the thread which is being
// named, however it appears that it works more reliably if called from within the code of
// the thread being name, passing a threadId of -1 to indicate "current thread"

#ifndef DWORD_PTR

#ifdef _WIN64
#define DWORD_PTR unsigned __int64
#else //#ifdef _WIN64
#define DWORD_PTR DWORD
#endif //#ifdef _WIN64

#endif //#ifndef DWORD_PTR

void CTeststakApp::nameThread(const DWORD threadId,
const char *name)
{
// You can name your threads by using the following code.
// Thread Validator will intercept the exception and pass it along (so if you are also running
// under a debugger the debugger will also see the exception and read the thread name

// NOTE: this is for 'unmanaged' C++ ONLY!

#define MS_VC_EXCEPTION 0x406D1388
#define BUFFER_LEN 16

typedef struct tagTHREADNAME_INFO
{
DWORD dwType; // must be 0x1000
LPCSTR szName; // pointer to name (in user addr space) buffer must be 8 chars + 1 terminator
DWORD dwThreadID; // thread ID (-1 == caller thread)
DWORD dwFlags; // reserved for future use, must be zero
} THREADNAME_INFO;

THREADNAME_INFO ThreadInfo;
char szSafeThreadName[BUFFER_LEN]; // buffer can be any size, just make sure it is large enough!

memset(szSafeThreadName, 0, sizeof(szSafeThreadName)); // ensure all characters are NULL before
strncpy(szSafeThreadName, name, BUFFER_LEN - 1); // copying name
//szSafeThreadName[BUFFER_LEN - 1] = '\0';

ThreadInfo.dwType = 0x1000;
ThreadInfo.szName = szSafeThreadName;
ThreadInfo.dwThreadID = threadId;
ThreadInfo.dwFlags = 0;

__try
{
RaiseException(MS_VC_EXCEPTION, 0, sizeof(ThreadInfo) / sizeof(DWORD_PTR), (DWORD_PTR *)&ThreadInfo);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
// do nothing, just catch the exception so that you don't terminate the application
}
}

After adding this function declaration you can call it from inside the thread procedure of any executing thread to name.

nameThread(-1, "example");

To name a thread from outside of the thread procedure pass the thread id instead of -1.

The example application shipped with Thread Validator demonstrates how to use nameThread. See nativeExample.cpp.

doc-collapse-icon How do I clear the symbol cache?

To clear Thread Validator's in-memory symbol cache, delete all sessions first:

·Managers Menu instructionStep Session Manager instructionStep Delete All instructionStep Close

Then flush the cache:

·Settings Menu instructionStep Edit Settings instructionStep General instructionStep File Cache / Subst Drives instructionStep click Flush Cache button instructionStep OK

Flush Cache disabled? Delete all the sessions first.

seeAlso See also: Clearing coverage cache.

doc-collapse-icon I have an idea for a feature, can it be added to Thread Validator?

We have tried to add as many features to Thread Validator that we thought would be useful to our users.

In fact, every feature in Thread Validator has been used to solve problems and bugs for clients who consult us, and in our own business, so we know the features we have are useful.

However, maybe we overlooked a feature that you would find very useful.

We'll happily consider most ideas for new features to Thread Validator. But no Quake, FlightSim or Flappy Bird Easter eggs though, sorry!

Please contact us to let us know your thoughts.


Not getting results

Navigation: Frequently Asked Questions >

Not getting results

 Return to chapter overview

Show/Hide Hidden Text

doc-collapse-icon Why don't I get any information about critical sections?

If you have started (or re-started) your application with data collection turned off, then Thread Validator will not collect or show any data.

doc-collapse-icon Why can't I get callstacks for sleeping or suspended threads?

Thread Validator can display callstacks for sleeping or suspended threads.

To do this Thread Validator must hook the SuspendThread, Sleep and SleepEx functions.

Thread Validator will only hook these functions if you enable Functions allocating waitable handles on the Hook Insertion settings dialog and check the required options.

In addition, callstack collection must be enabled. See the Collect and Callstack tabs.

doc-collapse-icon Why are my ordinal to symbol conversions not working?

If you have used the Ordinal Handling utility, you may still find the ordinal names have not been converted in symbol names,

·You haven't defined the ordinal to symbol conversion for the correct DLL in which the ordinals are defined

Double check the DLL for which you defined the conversions really include those ordinals.

seeAlso See the topic on Ordinal Handling


Seeing unexpected data

Navigation: Frequently Asked Questions >

Seeing unexpected data

 Return to chapter overview

Show/Hide Hidden Text

doc-collapse-icon Why do I get <UNKNOWN> symbols?

Some callstacks may not have a symbol name and can display the value <UNKNOWN>.

There are several reasons this may happen:

·The program you are monitoring has no debugging information

You'll need to enable debugging information in your program.

Debugging information is controlled from the Linker Tab on your Visual C++ project settings, and is available for Debug and Release builds.

·The PDB files with the debug information can't be found

The program you are monitoring may have the debug information but Thread Validator can't find the debug information if it's stored in PDB files that are not in the current directory.

Use the File Paths dialog to set where the PDB files can be found.

If you don't have PDB files for a particular DLL, but do have MAP files, you can also set the location of these too.

·A stack trace contains a location not present inside a DLL

This sometimes happens when hooks cause the program to jump to dynamically allocated memory holding the hook.

These hooks will not have any debugging information referencing them.

·The DLL has no filename and line-number data in the debugging information

This is the case for some release mode DLLs from Microsoft such as mfc42(u).dll and mfc80(u).dll.

These only have symbol name information available, with filename and line-number removed.

If you have this problem, you could try and get more up to date symbol information from Microsoft using the symbol server support page in the global settings dialog.

note Note that this will only work if the symbol server symbols do actually contain filename and line-number information - they might not!

If none of the above solves your problem and all symbols are still displayed as <UNKNOWN> please drop us a line. We have found that newer versions of Visual Studio sometimes change the debug information format and need a newer version of DbgHelp.dll. The version of DbgHelp.dll that is shipped with Thread Validator is compatible with Visual Studio.net and all previous versions of Visual Studio.

doc-collapse-icon Some symbols are displayed as Ordinalxxx, why?

If Thread Validator can't find debug information for DLLs that have their functions exported as ordinal values, the functions are named OrdinalXXX, using the decimal number of the function.

These ordinal values can be displayed as function names, but only if the linker definition (.def) file that refers to each relevant DLL is known.

You can define the Ordinal Handling, but don't forget to also select the Convert DLL exported function ordinals to symbols check box on the Symbols and Warnings page of the global settings dialog.

Here's an example of Ordinal function names without debug information: Ordinal711 and Ordinal187

And here's the same thing without debug information but after ordinal to symbol conversion, showing __cdecl operator new() and int AfxWinMain()

doc-collapse-icon What is address 0x006d0065?

This is relevant to one version of the VisualStudio.net DbgHelp library that sometimes does not correctly identify the end of a stack walk.

When this happens, a stack trace can have numerous addresses of value 0x006d0065 tacked onto the end of it, even if the stack walking callback informs DbgHelp that the address is not valid.

note This bug will not affect Thread Validator. All stack traces shown will be valid. A few stack traces may have extra data, but no data will be missing.

We don't filter these addresses out, in case a valid DLL does get loaded and uses this address space, producing symbols for this address.

Callstacks that contain this error look like this:

As you can see from the image, the program started at the UNICODE entry point wWinMainCRTStartup, so there should be no symbols (other than GetPriorityBoost or other kernel32.dll symbols) after this entry.

Subsequent versions of the DbgHelp.dll from Microsoft fix this bug.


Crashes and error reports

Navigation: Frequently Asked Questions >

Crashes and error reports

 Return to chapter overview

Show/Hide Hidden Text

doc-collapse-icon The program I'm trying to monitor keeps crashing, why?

The following assumes your crash is one that only happens when using Thread Validator.

Here's a few scenarios in which your program might crash:

·Third party DLLs are using system wide hooks

Some DLLs from third party vendors use system wide hooks and do not interact with Thread Validator and the target program very well.

If you can identify such DLLs, prevent them being hooked by adding the DLL name to the Hooked DLLs page of the global settings dialog as in the example below.

·Third party DLLs are using global hooks

A global hook DLL from a third party vendor could be adversely affecting Thread Validator when hooking your program.

Read about handling global hooks on the Global Hooks page of the settings dialog.

Judging by multiple independent error reports, we believe there may be an incompatibility between Thread Validator and the global hooks that come with the Matrox G400 and the Matrox Millenium II PCI video cards released in the late 1990's.

·There may be a bug in Thread Validator

It happens. We've tried to make Thread Validator as robust as possible, but bugs and new scenarios do occur.

First, ensure that the crash never happens if you are not using Thread Validator.

Second, check all the suggestions above.

Then drop us a line sending details of the error and we'll try to reproduce the crash with a view to fixing any bugs found in as timely a manner as possible.

doc-collapse-icon Thread Validator gives an Unrecoverable Error?

The Thread Validator Unrecoverable Error dialog is displayed when an unexpected internal error means Thread Validator cannot continue to execute.

A stack trace and register dump is shown and you can Copy to Clipboard so that the data can be sent to us with a description of the activities that caused the error.

We'll aim to fix any problems in as timely manner as possible.

The data shown in the dialog is also written to c:\users\<user name>\AppData\Roaming\Software Verify\Thread Validator\tvExceptionLogUI.txt.

The picture below shows a stack overflow exception report (artificially generated).

doc-collapse-icon What is in tvExceptionLogUI.txt and tvExceptionLog.txt?

In the event of a crash, the file c:\users\<user name>\AppData\Roaming\Software Verify\Thread Validator\tvExceptionLogUI.txt contains information that identifies where Thread Validator was executing when it crashed.

In the event of a crash, the file c:\users\<user name>\AppData\Roaming\Software Verify\Thread Validator\tvExceptionLog.txt contains information that identifies where the target process was executing when it crashed. This crash may be caused by an error in the target process or an error in the Thread Validator's instrumentation code.

The file contains a stack trace and register dump and is the same information that is displayed in the Unrecoverable Error dialog (above) when a crash occurred.

The file contains only the data for the most recent exception.


Debug symbols and DbgHelp

Navigation: Frequently Asked Questions >

Debug symbols and DbgHelp

 Return to chapter overview

Show/Hide Hidden Text

doc-collapse-icon Why does Thread Validator fail to load my symbols?

In a few cases Thread Validator will fail to load symbols for a DLL that you believe you have provided symbols for.

This topic describes the possible causes. Please read the suggested course of action for each compiler.

doc-collapse-icon Microsoft Visual Studio or Developer Studio

Symbols are defined in PDB files with the same name as the .exe or .dll to which it refers.

Thread Validator uses the Microsoft supplied DbgHelp.dll to perform all symbol handling activities.

Correct PDB name and location?

To ensure that the correct PDB is found to match a DLL the following must be true:

·The DLL and PDB file have the same name, except for the extension

For example test.pdb matches for test.dll or test.exe.

·The first matching PDB file in the PDB search path has the correct checksum

If DbgHelp finds a PDB file with a different checksum, loading symbols will fail but the search will still stop.

Verify that there are no PDB files with the same file name that are on the PDB search path, except for the PDB file you expect to be used.

You can check the DbgHelp symbol search path to troubleshoot symbol loading failures relating to the symbol search path.

Are compiler and linker producing symbols?

If DbgHelp is still failing to load your symbols, check the following:

·Your program is compiled to include symbol information

·Your program is linked to include symbol information

Linker options are different to the compiler options

Running correct version of DLL?

Check that you are using:

·The most recent version of your DLL

·The correct build version of your DLL

For example release DLL with release builds, debug DLL with debug builds

Checking for correctly loaded modules

When your application is running, check the modules being loaded by the application.

In Thread Validator, you can check the modules by using the Loaded Modules dialog, or by inspecting the Diagnostics tab.

You need to be sure that your application is not loading a different DLL with the same name from a different directory that is on the search path.

Correct version of DbgHelp.dll?

Try checking the version of DbgHelp.dll used by your Visual Studio installation and the version of DbgHelp.dll distributed with Thread Validator.

If the version used by Visual Studio is higher, it's possible Microsoft changed the PDB file format, making the symbols unreadable by Thread Validator.

To fix this:

·Copy the DbgHelp.dll from Visual Studio to the Thread Validator installation directory

·Remove any DbgHelp.dll from your application directory

When Thread Validator launches an application it copies Thread Validator's DbgHelp.dll to the directory of the executable.

This ensures that the DbgHelp.dll used is more recent than the default system32\dbghelp.dll which may not get updated.

You need to find and remove these dlls - e.g. c:\myapplication\debug\DbgHelp.dll etc.

If all else fails...

Sometimes symbolic information will not load for unknown reasons.

In this circumstance, after trying the above suggestions, try changing the location in which symbols are sourced.

You could also try flushing and disabling the caching of symbols.

If you still have problems, please contact us giving as much detail as possible, including what you've tried.

doc-collapse-icon Visual Studio 2005 (8.0) and later versions

You may find that symbols for the msvcr80.dll, msvcr80d.dll, mf80.dll, mfc80u.dll, mfc80d.dll and mfc80ud.dll DLLs are not loaded.

The reason for this is that these symbols are stored in c:\windows\symbols\dll rather than with the DLLs themselves.

This is due to the Windows.NET Side-by-Side (WinSxS) DLL/assembly loading.

To resolve this, add the path c:\windows\symbols\dll to the list of paths for Program Database (PDB) Files on the File Locations tab:

You may need to restart Thread Validator to get valid symbols for MFC80(u)(d).dll if you have already recorded a session for which you did not get symbols.

Alternatively follow the instructions in the question on how to clear the symbol cache:

doc-collapse-icon Metrowerks CodeWarrior for Windows V8 / V9

Metrowerks symbolic information is embedded in the .exe/.dll as CodeView information.

Please consult the documentation for CodeWarrior in order to include debug information (including filenames and line numbers) in the CodeView information.

If you still have problems, please contact us giving as much detail as possible, including what you've tried.

doc-collapse-icon Salford Software Fortran 95

Salford Fortran 95 symbolic information is embedded in the .exe/.dll as COFF (Common Object File Format) information, with some proprietary extensions to Salford Software (which they have kindly shared with us).

Please consult the documentation for Salford FORTRAN95 to include debug information (including filenames and line numbers) in the COFF information.

If you still have problems, please contact us giving as much detail as possible, including what you've tried.

doc-collapse-icon MingW compiler

We recommend compiling your software with -gstabs to create stabs debugging information.

The -gCoff option is also supported, but this does create a lot of unnecessary symbols, making symbol parsing slower.

doc-collapse-icon Troubleshooting DbgHelp.dll

Thread Validator uses the Microsoft Debugging DLL, DbgHelp.dll externalLink, copying the correct private version to your application's directory as your program is started.

However, there are cases where your application can be started independently, and you must ensure that your application uses the correct DbgHelp.dll.

Diagnostic error messages appear on the Diagnostics tab as in the example below detailing which version of DbgHelp.dll was expected and what was actually loaded.

If you see any DbgHelp warning dialogs, or get diagnostic errors, ensure the correct DbgHelp.dll is used by:

·Copy (don't move) DbgHelp.dll

from: the Thread Validator install directory

to: the location of the application being tested (the same directory as the .exe).

Rerun your test.

·Try updating the versions of DbgHelp.dll in:

c:\windows\system32

and

c:\windows\system32\dllcache

Accept any Windows permission warnings if you try to do this.

Rerun your test.

If you still continue to have problems, please drop us a line via our support email.

doc-collapse-icon How do I examine (and fix) the DbgHelp symbol search path?

It can sometimes be quite confusing to see why symbols fail to load for modules built with compilers that generate PDB files, e.g.: Microsoft, Intel.

There are typically three reasons for failure: the PDB file is...

·missing, for example it was not provided with the executable

·in the wrong place, so the debugging library can't find it

·the wrong version, for example from a different build

The diagnostic tab

The Diagnostic tab of Thread Validator displays lots of messages that can help diagnose many problems.

To show only DbgHelp debug information, use the message filter drop down at the top of the diagnostic tab. This lets you examine where DbgHelp.dll looks for symbols.

Examine the output to see if it's finding the PDB file you think it should, and if it rejects the contents of any PDB file it finds.

Output for alternate modules is shown in alternating coloursets, and the messages are the exact same output from the DbgHelp.dll debugging stream.

Examples of examining the diagnostics

Below we show three examples using nativeExample.exe and nativeExample.pdb from our example application.

·Correct symbol file found

DbgHelp first searches in various places looking for nativeExample.pdb

Depending on your machine, there may be other search paths included.

Finally nativeExample.pdb is found in the same directory as the .exe file of the target program

DbgHelp loads private symbols and lines, (the alternative being that DbgHelp loads public symbols).

Outcome:

Success. Symbols are loaded.

·Missing symbol file

As before, DbgHelp first searches in various places looking for nativeExample.pdb

But, nativeExample.pdb doesn't get found in the same directory as the .exe file of the target program.

nativeExample.pdb never gets found on the search path.

SymSrv might then look for additional locations for nativeExample.pdb, but has no luck.

DbgHelp might find some COFF symbols in the executable, however these don't contain filename or line number information.

Finally all options are exhausted.

Outcome:

Failure. The PDB file could not be found. Some default symbols are loaded but are not of much use.

Resolution:

Check the File Locations PDB paths to ensure that all the possible paths for PDB files are listed.

·Incorrect symbol file

As before, DbgHelp first searches in various places looking for nativeExample.pdb

This time, nativeExample.pdb does get found in the same directory as the .exe file of the target program.

DbgHelp tries to load the symbols but fails - the checksum inside the PDB file does not match the module.

This might be because the symbols are for a different build of the software, or it's an incorrectly named PDB file belonging to another program.

Finally all options are exhausted.

Outcome:

Failure. A PDB file was found, but it was not the right one.

Resolutions:

Double check the PDB is the correct one for the build you are running.

When copying builds from another machine (or from a build server), make sure to copy the correct PDB as well.

Check the File Locations PDB paths to ensure that all the possible paths for PDB files are listed.

Check the order of those PDB paths in case there are multiple paths resulting in the wrong PDB being found first.

doc-collapse-icon How can I create a map file with line numbers

If you don't have the ability to use .PDB files for debug information, you may be able to use .MAP files with line information.

The following is only applicable to Debug builds. Map files for Release builds can't have line number data.

note Microsoft discontinued support for including line information in .MAP files with Visual Studio 8.0 (2005). There is no easy workaround to this.

To select the /MAPINFO:LINES option for Visual Studio 6.0 use the following steps. If you are using Visual Studio 7.0, 7.1 (i.e .NET 2002 or 2003) the project settings user interface is slightly different, but the basic principle remains the same.

In Visual Studio:

menu Project Menu instructionStep Settings... instructionStep Select project instructionStep Shows project settings

The example image below shows a project called nativeExample.

·Generate mapfile instructionStep check option to request MAP file output

·Project Options instructionStep add the text /MAPINFO:LINES to add line information to the file instructionStep OK

Save your project workspace and build your project.

note Due to daylight saving times it is possible for a MAP file to have an embedded timestamp that is different than the DLL timestamp by an hour. In these situations Thread Validator will not recognise the MAP as valid. The solution to this problem is to rebuild the application.


Extensions, services and tools

Navigation: Frequently Asked Questions >

Extensions, services and tools

 Return to chapter overview

Show/Hide Hidden Text

doc-collapse-icon Including stublib.h in my project doesn't compile. Why?

You may encounter problems when including stublib.h in order to link directly with Thread Validator.

Include path problems

Ensure that your project C preprocessor include paths reference both of the stub and stublib subdirectories in the installation directory of Thread Validator.

For example, if Thread Validator is installed in:

C:\Program Files (x86)\Software Verify\Thread Validator

Then add the following paths for all configurations; Debug, Release, etc:

C:\Program Files (x86)\Software Verify\Thread Validator\stub

C:\Program Files (x86)\Software Verify\Thread Validator\stublib

Compiler errors

If you include stublib.h, your project must have included windows.h first, (or see below for an alternative).

If you fail to include windows.h then stublib.h will refer to some none-existent datatypes, causing compiler errors similar to the ones shown below.

Here's an example program that will not compile:

#include "stdafx.h"
#include "stublib.h"

int main(int argc, char* argv[])
{
return 0;
}

doc-collapse-icon See the compiler errors from the above code

--------------------Configuration: testMV_allEnum - Win32 Debug--------------------

Compiling...

testMV_allEnum.cpp

c:\program files\software verification\thread validator\stub\allenum.h(70) : error C2146: syntax error : missing ';' before identifier 'lRequest'

c:\program files\software verification\thread validator\stub\allenum.h(70) : error C2501: 'LONG' : missing storage-class or type specifiers

c:\program files\software verification\thread validator\stub\allenum.h(70) : error C2501: 'lRequest' : missing storage-class or type specifiers

c:\program files\software verification\thread validator\stub\allenum.h(71) : error C2146: syntax error : missing ';' before identifier 'reserved3'

c:\program files\software verification\thread validator\stub\allenum.h(71) : error C2501: 'DWORD' : missing storage-class or type specifiers

c:\program files\software verification\thread validator\stub\allenum.h(71) : error C2501: 'reserved3' : missing storage-class or type specifiers

c:\program files\software verification\thread validator\stub\allenum.h(73) : error C2143: syntax error : missing ';' before '*'

c:\program files\software verification\thread validator\stub\allenum.h(73) : error C2501: 'BYTE' : missing storage-class or type specifiers

c:\program files\software verification\thread validator\stub\allenum.h(74) : error C2501: 'dde_pbData' : missing storage-class or type specifiers

To fix this problem simply include windows.h before stublib.h

#include "stdafx.h"
#include <windows.h> // new line to fix compile errors
#include "stublib.h"

int main(int argc, char* argv[])
{
return 0;
}

Can't include windows.h?

If including windows.h is not an option, you can just define the following types:

#define LONG long
#define DWORD unsigned long
#define BYTE unsigned char
#define HANDLE void *

doc-collapse-icon What do I do if I cannot use svlMVStubService.lib?

You may find that you can't use svlTVStubService.lib / svlTVStubService_x64.lib because your linker doesn't understand the format of the lib file.

If that happens you can use the code below to compile the two functions that would be provided by those libraries.

doc-collapse-icon See the header file

#ifndef _SVL_TVSTUB_SERVICE_H
#define _SVL_TVSTUB_SERVICE_H

#include "svlServiceError.h"

// IMPORTANT.
// If you use svlTVStub_LoadThreadValidator() to load svlThreadValidatorStub.dll into your
// application, you must also use svlTVStub_UnloadThreadValidator() to unload the DLL prior to
// your application being closed down. Failure to do so will almost certainly result in a crash.
// It does not matter how the application is closed down, you must ensure that you use
// svlTVStub_UnloadThreadValidator() to unload the DLL if you have loaded it.
//
// The DLL prepares itself in different ways and shuts itself down differently depending on if
// it is:-
// a) Directly linked to the application for use with the API or injected with Thread Validator.
// When the DLL is used in this manner to DLL expects to oversee and manage the application
// shutdown.
// b) Loaded by using svlTVStub_LoadThreadValidator().
// When the DLL is used in this manner to DLL expects to be removed prior to application shutdown
// and the behaviour of the DLL is undefined once you enter the program shutdown sequence.
//
// This difference in behaviour is intentional and is done to allow the use of the stub DLL in
// services.

#ifdef __cplusplus
extern "C" {
#endif

SVL_SERVICE_ERROR svlTVStub_LoadThreadValidator(serviceCallback_FUNC callback,
void *userParam);

SVL_SERVICE_ERROR svlTVStub_UnloadThreadValidator();

#ifdef __cplusplus
}
#endif

#endif

doc-collapse-icon See the implementation file

#include "svlTVStubService.h"

#include <windows.h>
#include <tchar.h>

//-NAME---------------------------------
//.DESCRIPTION..........................
//.PARAMETERS...........................
//.RETURN.CODES.........................
//--------------------------------------

static HMODULE hModule = NULL;

//-NAME---------------------------------
//.DESCRIPTION..........................
//.PARAMETERS...........................
//.RETURN.CODES.........................
//--------------------------------------

typedef void (*ENABLE_STUB_SYMBOL_FUNC)();

SVL_SERVICE_ERROR svlTVStub_LoadThreadValidator(serviceCallback_FUNC callback,
void *userParam)
{
SVL_SERVICE_ERROR errCode = SVL_OK;

if (hModule == NULL)
{
hModule = LoadLibraryW(L"svlThreadValidatorStub.dll"); // change this to svlThreadValidatorStub6432.dll or svlThreadValidatorStub_x64.dll as appropriate
if (hModule != NULL)
{
// DLL loaded, set the service callback function

SETCALLBACK_FUNC setCallbackFunc;

setCallbackFunc = (SETCALLBACK_FUNC)GetProcAddress(hModule, "apiSetServiceCallback");
if (setCallbackFunc != NULL)
{
(*setCallbackFunc)(callback, userParam);
}

// now start the profiler

PROC *p;

p = GetProcAddress(hModule, "startProfiler");

if (p != NULL)

(*p)();

// now turn on provision of symbols by the stub

ENABLE_STUB_SYMBOL_FUNC enableSymbolFunc;

enableSymbolFunc = (ENABLE_STUB_SYMBOL_FUNC)GetProcAddress(hModule, "apiEnableStubSymbols");
if (enableSymbolFunc != NULL)
{
(*enableSymbolFunc)();
}
else
{
errCode = SVL_FAILED_TO_ENABLE_STUB_SYMBOLS;
}
}
else
{
errCode = SVL_LOAD_FAILED;
}
}
else
{
errCode = SVL_ALREADY_LOADED;
}

return errCode;
}

//-NAME---------------------------------
//.DESCRIPTION..........................
//.PARAMETERS...........................
//.RETURN.CODES.........................
//--------------------------------------

typedef void (*UNLOAD_FUNC)();
typedef HANDLE (*GET_STUB_HEAP_FUNC)();

SVL_SERVICE_ERROR svlTVStub_UnloadThreadValidator()
{
SVL_SERVICE_ERROR errCode = SVL_OK;

if (hModule != NULL)
{
// get the stub heap before we shut down the DLL

HANDLE hStubHeap = NULL;
GET_STUB_HEAP_FUNC getHeapFunc;

getHeapFunc = (GET_STUB_HEAP_FUNC)GetProcAddress(hModule, "apiGetInternalMVstubHeap");
if (getHeapFunc != NULL)
{
hStubHeap = (*getHeapFunc)();
}

// get the unload stub function

UNLOAD_FUNC unloadFunc;

unloadFunc = (UNLOAD_FUNC)GetProcAddress(hModule, "apiShutdownThreadValidator");
if (unloadFunc != NULL)
{
(*unloadFunc)();

// get the function

HMODULE hModule;

hModule = GetModuleHandleW(L"svlThreadValidatorStub.dll");
if (hModule != NULL)
{
// unload the stub

FreeLibrary(hModule);

// destroy the stub's heap (which was still in use whilst FreeLibrary() was in progress

if (hStubHeap != NULL)
HeapDestroy(hStubHeap);
else
{
if (errCode == SVL_OK)
errCode = SVL_FAIL_TO_CLEANUP_INTERNAL_HEAP;
}
}
else
{
errCode = SVL_FAIL_MODULE_HANDLE;
}
}
else
{
errCode = SVL_FAIL_UNLOAD;
}

hModule = NULL;
}
else
errCode = SVL_NOT_LOADED;

return errCode;
}


System and environment

Navigation: Frequently Asked Questions >

System and environment

 Return to chapter overview

Show/Hide Hidden Text

doc-collapse-icon How do I create a Power User on Windows XP?

Windows 2000 and Windows XP Pro allow Power User accounts that stop short of full Administrator permissions.

To make an existing user (say Test User) a Power User do the following:

·Start Menu instructionStep Right click on My Computer instructionStep Manage

The Computer Management window appears

·On the left, expand System Tools instructionStep Local Users and Groups instructionStep Users

·On the right, select and Right click on 'Test User' instructionStep Properties

The User Properties dialog appears

·Select the Member Of tab instructionStep Add...

The Select Groups dialog appears

·In the bottom box, type Power Users instructionStep OK

·In the user properties dialog select Users instructionStep Remove instructionStep OK

·Close Computer Management

Your Test User is now a member of the Power Users group - and probably not really a 'Test' User any more!

doc-collapse-icon What file extensions does Thread Validator use?

Most configuration data is stored in the registry, but some information is file-based such as settings, coverage, hook and filter data.

Thread Validator uses the following extensions:

Sessions, Settings, Hooks and File Locations

·tvm ·tvm_x64 | Session files for 32 bit or 64 bit Thread Validator
·tvs ·tvs_x64 | Settings for 32 bit or 64 bit
·tvx | Hooked DLLs
·tvxfl | File locations

Session Export

·html | HTML export files
·xml | XML export files

Program Launch, Extensions

·dll | Extension DLLs
·exe | Program files


Installing Floating Licensing

Navigation: »No topics above this level«

Installing Floating Licensing

 Return to chapter overview

How to install floating licences

Floating licences float globally. Your team members in an office on the other side of the world can share a floating licence with you.

If you have floating licences install the software on all machines in your business unit that wish to use the software.

For an overview of how floating licences work, please read this.

Floating licence server

The floating licence server is managed by Software Verify.

No server to setup, no licences to misconfigure. All the things that are bad about floating licences, we've removed all that.

If you need to acquire a licences or release a licence, see the Floating Licences tab.

Floating licence help

If you have problems with the floating licences please contact support@softwareverify.com

If you need to purchase additional floating licences for a new floating licence please visit https://www.softwareverify.com/purchasing/.

If you need to purchase additional floating licences to add to an existing floating licence please contact sales@softwareverify.com.


Udis86

Navigation: Copyright notices >

Udis86

 Return to chapter overview

This software uses the library svlUdis86.dll and svlUdis86_x64.dll. These libraries are modified binary versions of the open source disassembler udis86.

udis86 was hosted at http://udis86.sourceforge.net/

udis86 is currently hosted at https://github.com/vmt/udis86 although the current distribution (at the time of writing) appears to be missing some files required to compile.

The 1.7.0 version of the udis source code contains this copyright notice: Copyright (c) 2005, 2006, Vivek Mohan

The 1.7.2 version of the udis source code contains this copyright notice: Copyright (c) 2002-2009 Vivek Thampi

These copyright notices appear to conflict and the latter copyright notice completely ignores the claims set forth in the 1.7.0 copyright notice.

In accordance with the license terms in the 1.7.2 software we include this binary license.

* 1.7.2 Copyright (c) 2002-2009 Vivek Thampi

* All rights reserved.

*

* Redistribution and use in source and binary forms, with or without modification,

* are permitted provided that the following conditions are met:

*

* * Redistributions of source code must retain the above copyright notice,

* this list of conditions and the following disclaimer.

* * Redistributions in binary form must reproduce the above copyright notice,

* this list of conditions and the following disclaimer in the documentation

* and/or other materials provided with the distribution.

*

* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND

* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED

* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE

* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR

* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES

* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;

* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON

* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT

* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS

* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.