Rss Feed
Tweeter button
Facebook button
Technorati button
Reddit button
Myspace button
Linkedin button
Webonews button
Delicious button
Digg button
Flickr button
Stumbleupon button
Newsvine button

Posts tagged: C

Getting code coverage for a child process?

By , May 31, 2017 5:43 pm

In this blog post I’m going to explain how to collect code coverage for a process that is launched by another process. We’ll be using C++ Coverage Validator to collect the code coverage.

For example you may have a control process that launches helper programs to do specific jobs and you wish to collect code coverage data for one of the helper programs. I’m first going to show how you do this with the GUI, then I’ll show you how to do this with the command line.

For the purposes of this blog post I’m going to use a test program called testAppFromOtherProcess.exe as the child program and testAppOtherProcessCpp.exe as the parent process. Once I’ve explained this for C++, I’ll also provide examples for programs launched from Java and for programs launched from Python.

The test program

The test program is simple. It takes two numbers and calculates the sum of all the products. If less than two arguments are supplied they default to 10.

int _tmain(int argc, _TCHAR* argv[])
{
	int	nx, ny;
	int	x, y;
	int	v;

	nx = 10;
	ny = 10;
	v = 0;

	if (argc == 2)
	{
		nx = _tcstol(argv[1], NULL, 10);
	}
	else if (argc >= 3)
	{
		nx = _tcstol(argv[1], NULL, 10);
		ny = _tcstol(argv[2], NULL, 10);
	}

	for(y = 0; y < ny; y++)
	{
		for(x = 0; x < nx; x++)
		{
			v += (x + 1) * (y + 1);
		}
	}

	return v;
}

The parent C++ program

The parent C++ program is a simple MFC dialog that collects two values and launches the test program. The code for launching the child process looks like this:

void CtestAppOtherProcessCppDlg::OnBnClickedOk()
{
	// get data values

	CString	str1, str2;
	DWORD	v = 0;

	GetDlgItemText(IDC_EDIT_COUNT1, str1);
	GetDlgItemText(IDC_EDIT_COUNT2, str2);

	// create command line

	CString	commandline;

	commandline += _T("testAppFromOtherProcess.exe");
	commandline += _T(" ");
	commandline += str1;
	commandline += _T(" ");
	commandline += str2;

	// run child process

	STARTUPINFO         stStartInfo;
	PROCESS_INFORMATION stProcessInfo;

	memset(&stStartInfo, 0, sizeof(STARTUPINFO));
	memset(&stProcessInfo, 0, sizeof(PROCESS_INFORMATION));

	stStartInfo.cb = sizeof(STARTUPINFO);
	stStartInfo.dwFlags = STARTF_USESHOWWINDOW;
	stStartInfo.wShowWindow = SW_HIDE;

	int	bRet;

	bRet = CreateProcess(NULL,
			(TCHAR *)(const TCHAR *)commandline,
			NULL,
			NULL,
			FALSE,
			0,
			NULL,
			NULL,
			&stStartInfo,
			&stProcessInfo);
	if (bRet)
	{
		// wait until complete then get exit code

		WaitForSingleObject(stProcessInfo.hProcess, INFINITE);

		GetExitCodeProcess(stProcessInfo.hProcess, &v);

		// tidy up

		CloseHandle(stProcessInfo.hProcess);
		CloseHandle(stProcessInfo.hThread);
	}

	// display result

	SetDlgItemInt(IDC_STATIC_VALUE, v, FALSE);
}

Configuring the target C++ program

Before we can collect code coverage we need to tell C++ Coverage Validator about the target program and the program that is going to launch it. We do this from the launch dialog (or launch wizard). From the launch dialog, select the program to launch using the Browse... button and selecting the file with the File dialog. Once a file has been chosen a default value will be selected for the Application to Monitor. This is the same program as you just selected with the File dialog.

CVLaunchDialogApplicationToMonitor

To allow us to monitor other programs we need to edit the list of applications we can monitor. Click the Edit... button to the right of the Application to monitor combo box. The Applications To Monitor dialog is displayed.

CVApplicationsToMonitorDialog

We need to add our target program to the list of programs to monitor. Click Add.... The Application To Monitor dialog is displayed. Choose our launch program testAppOtherProcessCpp.exe using Browse.... C++ Coverage Validator will identify any other executables in the same folder and add these to the list of target programs you may want to monitor. You can remove any programs you don't want to monitor with the Remove and Remove All buttons. Your dialog should look like the one shown below.

CVApplicationToMonitorDialog

Click OK to close the Application To Monitor dialog.

Click OK to close the Applications To Monitor dialog.

The Application to monitor combo will now have additional entries in it. Select testAppFromOtherProcess.exe in the Application to monitor combo. Leave the launch count set to 1. The first time testAppFromOtherProcess.exe is launched it will be monitored. Click Go! to start the parent process.

CVApplicationToMonitorParentProcess

You will notice that C++ Coverage Validator is not collecting data. Now click on the Launch Child Process button. The child process is launched, C++ Coverage Validator recognises the parent process is launching a child process that is configured to be monitored and has the correct launch count (this is the first time it is being launched and the launch count is set to "1") - the child process is instrumented for code coverage. You can see the instrumentation progress in the title bar and pretty soon code coverage statistics are being displayed by C++ Coverage Validator.

CVCodeCoverageResults

Command Line, example for C++

OK, that's wonderful, we can collect code coverage using the GUI to launch one program and collect data from a child process. All without any coding. Super. So how do we do that from the command line? Glad you asked!

"c:\C++ Coverage Validator\coverageValidator.exe" 
-program "e:\test\release\testAppOtherProcessCpp.exe"
-directory "e:\test\release" 
-programToMonitor "e:\test\release\testAppFromOtherProcess.exe" 

How does this work?

  • -directory. Specify the startup directory.
  • -program. Specify the program to launch.
  • -programToMonitor. Specify the program to that will be monitored for code coverage.

Very straightforward and simple. Paths must have quotes if they contain spaces. If in doubt always use quotes. Note also that where you've installed C++ Coverage Validator will be different, most likely in C:\Program Files (x86)\Software Verification. We shortened it for the example to make it fit the page.

Java

The parent program in Java is very simple. It takes any arguments passed to it and passes them to the target program.

import java.io.IOException;
import java.lang.ProcessBuilder;
import java.util.ArrayList;

public class testAppFromOtherProcessJava 
{
    public static void main(String[] args) throws IOException, InterruptedException
	{
		String			target = "e:\\om\\c\\testApps\\testAppFromOtherProcess\\Release\\testAppFromOtherProcess.exe";
        	ProcessBuilder	p = new ProcessBuilder();

		// add the args to be passed to the target program, unlike C/C++, args[0] is not the program name

		ArrayList	targetArgs;

		targetArgs = new ArrayList();
		targetArgs.add(target);
		for(int i = 0; i < args.length; i++)
		{
			targetArgs.add(args[i]);
		}

		p.command(targetArgs);

		// run the process, wait for it to complete and report the value calculated

		Process			proc;

	        proc = p.start();
		proc.waitFor();

		System.out.println("Result: " + proc.exitValue()); 
    }
}

You can compile this program with this simple command line. This assumes you have a Java Development Kit installed and javac.exe on the command line.

javac testAppFromOtherProcessJava.java

Configuring the target Java program

As with the C++ target program we need to tell C++ Coverage Validator about the target program and the program that is going to launch it. We're running a Java program so the executable to launch is the Java runtime. Click the Browse... button and select the Java runtime you are using.

CVLaunchDialogJava

The launch directory is automatically configured to be the same as the launch program. In the case of a Java program, that is almost certainly incorrect. We're going to choose the directory where our Java class is located. Click the Dir... button and choose that directory.

CVLaunchDialogJavaDirectory

We also need to tell the Java runtime what class to execute. This is provided as an argument to the program being run (the Java rutnime). In the arguments field, type the name of the class. In this case testAppFromOtherProcessJava (without the .class extension).

CVLaunchDialogJavaArguments

To allow us to monitor other programs we need to edit the list of applications we can monitor. Click the Edit... button to the right of the Application to monitor combo box. The Applications To Monitor dialog is displayed.

CVApplicationsToMonitorDialog

We need to add our target program to the list of programs to monitor. Click Add.... The Application To Monitor dialog is displayed. Choose the Java runtime java.exe using Browse.... C++ Coverage Validator will identify any other executables in the same folder and add these to the list of target programs you may want to monitor. You can remove any programs you don't want to monitor with the Remove and Remove All buttons. We now need to add the target program to the list of programs we want to monitor. Click Add... and select testAppFromOtherProcess.exe. Your dialog should look like the one shown below.

CVApplicationToMonitorDialogJava

Select testAppFromOtherProcess.exe in the Application to monitor combo. Leave the launch count set to 1. The first time testAppFromOtherProcess.exe is launched it will be monitored. Click Go! to start the parent process.

CVLaunchDialogApplicationToMonitorJava

The Java process launches testAppFromOtherProcess.exe immediately. As such you will notice that C++ Coverage Validator starts collecting code coverage almost instantly because it has recognised the Java process is launching a child process that is configured to be monitored and has the correct launch count.

CVCodeCoverageResultsJava

Command Line, example for Java

As you can see, it's slightly more complicated for Java than for C++, but only because the Java runtime is located in a different folder than the test executable and because we also have to specify a Java class to execute. We still managed to collect code coverage for a child process of a just in time compiled language without any coding.

Of course, you now want to know how to do this for the command line. Is this any more complicated than for the C++ example? No! Just as easy. Here's how you do it:

"c:\C++ Coverage Validator\coverageValidator.exe" 
-program "c:\program files\java\jdk1.8.0_121\bin\java.exe"
-directory "e:\test\release" 
-arg testAppFromOtherProcessJava
-programToMonitor "e:\test\release\testAppFromOtherProcess.exe"

How does this work?

  • -arg. Specify an argument to the program to launch. In this example this specifies the Java class to execute.
  • -directory. Specify the startup directory.
  • -program. Specify the program to launch. In this example this specifies the Java runtime.
  • -programToMonitor. Specify the program to that will be monitored for code coverage.

Use as many -arg options as you need. We only used one because that's all we need for the example.

Python

The parent program in Python is very simple.

import sys
import subprocess

cmdLine = r"E:\om\c\testApps\testAppFromOtherProcess\Release\testAppFromOtherProcess.exe"
for arg in range(1, len(sys.argv)):
  cmdLine += " "
  cmdLine += sys.argv[arg]
  
subprocess.call(cmdLine, stdin=None, stdout=None, stderr=None, shell=False)

Configuring the target Python program

As with the C++ target program we need to tell C++ Coverage Validator about the target program and the program that is going to launch it. We're running a Python program so the executable to launch is the Python interpreter. Click the Browse... button and select the Python interpreter you are using.

CVLaunchDialogPython

The launch directory is automatically configured to be the same as the launch program. In the case of a Python program, that is almost certainly incorrect. We're going to choose the directory where our Python script is located. Click the Dir... button and choose that directory.

CVLaunchDialogPythonDirectory

We also need to tell Python what script to launch. This is provided as an argument to the program being run (the Python interpreter). In the arguments field, type the name of the script. In this case testAppFromOtherProcess.py.

CVLaunchDialogPythonArguments

To allow us to monitor other programs we need to edit the list of applications we can monitor. Click the Edit... button to the right of the Application to monitor combo box. The Applications To Monitor dialog is displayed.

CVApplicationsToMonitorDialog

We need to add our target program to the list of programs to monitor. Click Add.... The Application To Monitor dialog is displayed. Choose the Python interpreter python.exe using Browse.... C++ Coverage Validator will identify any other executables in the same folder and add these to the list of target programs you may want to monitor. You can remove any programs you don't want to monitor with the Remove and Remove All buttons. We now need to add the target program to the list of programs we want to monitor. Click Add... and select testAppFromOtherProcess.exe. Your dialog should look like the one shown below.

CVApplicationToMonitorDialogPython

Select testAppFromOtherProcess.exe in the Application to monitor combo. Leave the launch count set to 1. The first time testAppFromOtherProcess.exe is launched it will be monitored. Click Go! to start the parent process.

CVLaunchDialogPythonAppToMonitor

The Python process launches testAppFromOtherProcess.exe immediately. As such you will notice that C++ Coverage Validator starts collecting code coverage almost instantly because it has recognised the Python process is launching a child process that is configured to be monitored and has the correct launch count.

CVCodeCoverageResultsPython

Command Line, example for Python

As you can see, it's slightly more complicated for Python than for C++, but only because the Python interpreter is located in a different folder than the test executable and because we also have to specify a Python script. We still managed to collect code coverage for a child process of a scripted language without any coding.

Of course, you now want to know how to do this for the command line. Is this any more complicated than for the C++ example? No! Just as easy. Here's how you do it:

"c:\C++ Coverage Validator\coverageValidator.exe" 
-program "c:\python36-32\python.exe"
-directory "e:\test\release" 
-arg testAppFromOtherProcess.py
-programToMonitor "e:\test\release\testAppFromOtherProcess.exe"

How does this work?

  • -arg. Specify an argument to the program to launch. In this example this specifies the Python script to run.
  • -directory. Specify the startup directory.
  • -program. Specify the program to launch. In this example this specifies the Python interpreter.
  • -programToMonitor. Specify the program to that will be monitored for code coverage.

Use as many -arg options as you need. We only used one because that's all we need for the example.

Conclusion

We've demonstrated how to monitor code coverage in a target program launched from C++, Java and Python, using both the GUI and the command line. Each example is slightly different, showing you the changes required for each situation. If you have any questions please email support@softwareverify.com

You can download the C++, Java and Python code used in these examples here.

Share

Problems when subclassing controls

By , November 19, 2010 2:56 pm

I’m developing a graph control for use in our Memory Validator software tool.

Graph custom control

Tracking a mouse
One of the requirements was that we need to monitor mouse move messages on the control so that we can update some on-the-fly statistics related to where the mouse cursor is in the graph. No problem, add a ON_WM_MOUSEMOVE() message map entry and an OnMouseMove() method to the class (I’m using MFC) and that should be it. Easy.

Transparent hit tests
That’s what I thought until it didn’t work. Very confusing. Checked some other controls we’ve written and they all work OK. What is different about this control? After some head scratching and testing I decided to run Spy++ to monitor the windows messages being sent to our custom control. What a surprise that was. The only messages the custom control was generating were WM_NCHITTEST messages to see if the mouse cursor was in the control. Rather than return HTCLIENT or something similar the control was returning HTTRANSPARENT. Why would it do that?

Why is it transparent?
The reason the control is returning HTTRANSPARENT is because I’ve used a CStatic frame control to place my control in the resource editor and then I subclass that CStatic with my custom control. If I don’t override OnNcHitTest() method and add WM_ON_NCHITTEST() to the message map then I get the hit testing functionality from the CStatic. The CStatic’s job is to display a frame and let other control be displayed inside it (even though they are not child controls). For CStatic to do that it needs to return HTTRANSPARENT.

Getting mouse move messages
To fix this problem is straightforward.

  • Add a WM_ON_NCHITTEST() entry to the custom control message map.
  • Add a OnNcHitTest() method to the custom control and make it return HTCLIENT;

Once these are in place, the hit test works and then mouse move messages are sent to the custom control.

Conclusion
Sometimes the reason you are not getting messages is because something else is setup incorrectly. In this case the lack of correct hit testing was affecting many other messages, of which the mouse move message was one. I hope this article will help prevent you wasting any time on a bug like this.

Share

Don’t try this at home – custom control time sink

By , November 16, 2010 11:44 am

There are time when writing a custom control will waste your time like nothing on earth.

I’m going to share with you a particularly painful timewaster than bit my behind last night.

The custom control
I’m writing a custom control that will take data from an arbitrary data source via a data provider and then display this data as a graph. The screenshots in this article are not from the finished control, just some mockups to test various ideas I am experimenting with. As you can see it is a graph with a pastel block colour and a harder solid outline. All configurable of course.

Graph custom control

The problem
The problem was first noticed when I wanted to change some settings in the host program. I clicked on the toolbar button to open the settings dialog and nothing happened. Button depressed, but nothing. Clicking elsewhere on the screen and I get a beep – hmmm, not allowed. GUI is totally frozen.

It felt like a deadlock. But all the code I’d written had its multithreading code locked down and everything I’m doing is on the GUI thread. No chance of a deadlock. Still I go investigating, several times in the debugger, use Thread Validator and Thread Status Monitor. No sign of a deadlock. Thats odd.

Try a different tack. Comment out the subclassing of the graph controls – effectively disabling them. Does the settings dialog display? Yes it does. OK, so it is something to do with the custom control. But what? Identify by process of elimination. Comment out all message map handlers except erase background and paint. Do I still get the problem? Yes, OK, so the problem is with erase background or paint. Turns out the problem is in paint. I’ll show you the code below.

void CSvlGraphCtrl::OnPaint()
{
    if (GetSafeHwnd() == 0)
        return;

    CRect    rCl;

    GetClientRect(&rCl);

    CClientDC    dc(this);
    CMemDC     dcMem(&dc, rCl);

    OnDraw(&dcMem);
}

Can you spot the problem? I’ve forgotten to call CWnd::OnPaint() which sets the I’ve been drawn bits inside the class and causes various other drawing related operations to happen. Without this call, the settings dialog I’ve been trying interact with (which is displayed on top of this graph custom control in this case) does not get drawn properly – or at all. So the settings dialog which is nothing to do with the custom control is displayed but doesn’t get drawn due to an incorrect cascade of events caused by failing to call CWnd::OnPaint() from the custom control’s OnPaint() handler.

The code should look like this (added line in bold)

void CSvlGraphCtrl::OnPaint()
{
    CWnd::OnPaint();

    if (GetSafeHwnd() == 0)
        return;

    CRect    rCl;

    GetClientRect(&rCl);

    CClientDC    dc(this);
    CMemDC     dcMem(&dc, rCl);

    OnDraw(&dcMem);
}

Conclusion
Sometimes the bug isn’t what you think it is. I started thinking this was a deadlock as the GUI appeared to freeze (pressing ALT caused the display to fix itself, but I found that by accident several hours later) but the fix was a missing call to a base class method. I’ve been writing MFC for years and yet this trivial bug eluded me for some time.

Hopefully sharing this with you will help prevent you from making the same mistake.

Share

How to read embedded data from a resource

By , August 8, 2010 9:48 am

In the previous article I showed you how to embed data into a custom resource in your executable.

In this article I’m going to show you how to extract the same data using the Win32 API for use in your executable at runtime.

To extract data from a resource in an executable we need some information:

  • Executable name.
  • Custom resource type name.
  • Custom resource name.

In our previous example, the executable name was mvJavaDetective.dll, the custom resource type name was “CLASSFILE” and the custom resource name was “myJavaSpy”.

The API

FindResource

    HRSRC FindResource(HMODULE hModule,
                       LPCTSTR lpName,
                       LPCTSTR lpType);

Call FindResource() to find a resource in an executable and return a resource handle. The executable is specified using a module handle that represents a module loaded in the current program. If the module is not currently loaded you can load it with LoadLibrary(). The resource is identified by its custom resource name and custom resource type.

LoadResource

    HGLOBAL LoadResource(HMODULE hModule,
                         HRSRC   hResInfo);

Call LoadResource() to load the resource specified by the module handle and the resource handle. The returned handle should not be passed to any Global memory function for deallocation.

LockResource

    LPVOID LockResource(HGLOBAL hResData);

Call LockResource() to lock the resource in memory. Pass the handle returned by LoadResource() as the input parameter. If the call succeeds a pointer to the data represented by the handle is returned.

SizeofResource

    DWORD SizeofResource(HMODULE hModule,
                         HRSRC   hResInfo);

Call SizeofResource() to determine the size of a resource. Pass the module handle and the handle returned from FindResource() as input parameters.

Putting it together

In the previous example our example DLL myJavaDetective.dll had a class myJavaSpy.class embedded into a resource with the type “CLASSFILE” and name “myJavaSpy”. I will now show you how to extract the myJavaSpy.class byte codes from the resource.

First we need to get the module handle of the executable (myJavaDetective.dll) containing the myJavaSpy.class. For this example we will assume that myJavaDetective.dll is already loaded into memory.

	HMODULE	hModJavaDetective;

	hModJavaDetective = GetModuleHandle("myJavaDetective.dll");

Once we have the module handle we can attempt to find the resource in the executable. We don’t need to check for a NULL module handle as FindResource() handles and will return a NULL resource handle (just as it will if the resource is not embedded in the executable).

	jbyte	*classBytes = NULL;
	DWORD	classBytesLength = 0;
	HRSRC	hResource;

	hResource = FindResource(hModJavaDetective,
							 _T("myJavaSpy"),
							 _T("CLASSFILE"));
	if (hResource != NULL)
	{

If FindResource() returns a non NULL handle the resource has been found. Now we must load the resource using a LoadResource().

		HGLOBAL	hResourceMemory;

		hResourceMemory = LoadResource(hModInjectedJVMTI, hResource);
		if (hResourceMemory != NULL)
		{

If LoadResource() returns a non NULL handle the resource has been correctly loaded from the executable. This returns a handle of type HGLOBAL. Caution you must not pass this handle to any HGLOBAL related functions such as GlobalFree() or GlobalRealloc() as this handle does not represent a memory allocation. This type is used for backward compatibility with earlier versions of the Windows API.

Before we can use the data we must convert the returned handle into a pointer to the data by calling LockResource(). We also want to know the size of the data in the resource so we call SizeofResource() to determine the size. The pointer returned by LockResource() must not be passed to any memory deallocation functions – it does not need to be deallocated or unlocked.

			void	*ptr;
			DWORD	size;

			ptr = LockResource(hResourceMemory);
			size = SizeofResource(hModInjectedJVMTI, hResource);
			if (ptr != NULL)
			{

If LockResource() returns a non NULL pointer the pointer represents the data embedded in the executable.

Now we have the data we make a copy for our own use and continue as normal. This step is optional, you can use the data directly from the returned pointer if you wish.

				classBytes = new jbyte [size];
				if (classBytes != NULL)
				{
					memcpy(classBytes, ptr, size);
					classBytesLength = size;
				}
			}
		}

		// CAUTION! LoadResource() and LockResource() DO NOT allocate handles or locks, 
		// read the documentation
	}

Now that we have extracted the data from the resource embedded into the executable we can use the data as normal. For this example I will conclude by using the extracted Java class bytescodes to define a Java class in a Java Virtual Machine.

	if (classBytes != NULL)
	{
		// define our class, must have same name as class file bytes
		// pass NULL for the class loader - use default class loader

		jclass		klass = 0;

		klass = jniEnv->DefineClass(SVL_COVERAGE_CLASS, NULL, classBytes, classBytesLength);
		if (klass != 0)
		{
                    // class defined correctly
		}

		// tidy up

		delete [] classBytes;
	}

Wrap up

Now you know how to embed data in an executable at runtime (and after the fact with the utility presented in the previous article) and how to extract data from an executable at runtime. The techniques are quite straightforward to master and allow you to easily embed data for you to use at runtime without worrying about distributing and locating extra data files.

Share

Thread Validator x64 enters BETA

By , August 6, 2010 8:57 am

Thread Validator x64 is now available for beta testing.

Thread locking history

Thread Validator x64 is the 64 bit version of our successful 32 bit Thread Validator software tool that runs on Microsoft Windows operating systems. Thread Validator x64 is a deadlock detection and thread analysis software tool, running on Windows 7 64 bit, Windows Vista 64 bit and Windows XP 64 bit.

Thread Validator has multiple displays to provide you with different perspectives onto the data you have collected.

What does Thread Validator do?

Thread Validator x64 identifies thread deadlocks, potential deadlocks and locks with a high contention rate.

Thread deadlocks usually mean that one or more threads can no longer function correctly because they are waiting on a lock that will never be released. This is an error condition and usually manifests as an unresponsive computer program.

Potential deadlocks are locking sequences that have not triggered a deadlock but may lead to a deadlock under slightly different conditions.

High contention rate locks result in your program spending too much time waiting for access to a lock. A different program design can often reduce a high contention rate to a less demanding contention rate.

How does Thread Validator work?

Thread Validator instruments your computer program so that it can monitor the appropriate synchronization APIs used to control access to locks, mutexes, semaphores and wait conditions. Using the information gained from monitoring these APIs, Thread Validator can calculate deadlock conditions, potential deadlock conditions and detect locks with high contention rates.

Thread Validator gathers data for all locks, all threads, all mutexes, all semaphores and all wait conditions. The data is organised into various displays allowing you to view information:

  • All active locks.
  • All active locks, organized by thread.
  • All locks that are locked at a given time.
  • Allocation information for all allocated synchronization objects, showing callstack and source code.
  • Thread locking history. View all threads, see what each threads is doing and when.
  • Thread lock order. View the order locks are acquired across threads for a given lock sequence.
  • List of all application objects that can be used in wait conditions.
  • How Thread Validator helps you be more productive

    Thread Validator x64 can help you:

    • Identify deadlocks in your application – quickly identify and fix hard threading problems.
    • Identify potential deadlocks in your application – prevent problems before they get serious.
    • Identify busy contended critical sections in your application – improve performance.
    • View thread locking behaviour in real time.
    • Improve your software quality by modifying your threading behaviour.
    • View all open handles that your application can wait on.

    Join the beta test

    If you are developing 64 bit software and have some multi-threading problems you would like to analyze, please join the beta, analyze your multi-threading problems and let us know your thoughts.

    Share

How to prevent a memory tool from monitoring your C/C++ allocations

By , July 10, 2010 10:53 am

A little known fact is that the Microsoft C Runtime (CRT) has a feature which allows some allocations (in the debug runtime) to be tagged with flags that causes these allocations to be ignored by the built in memory tracing routines. A good memory allocation tool will also use these flags to determine when to ignore memory allocations – thus not reporting any allocations that Microsoft think should remain hidden.

A customer problem

The inspiration for this article was a customer reporting that Memory Validator was not reporting any allocations in a particular DLL of his mixed mode .Net/native application. The application was interesting in that it was a combination of C#, C++ written with one version of Visual Studio and some other DLLs also written in C++ with another version of Visual Studio. Only the memory for one of the DLLs was not being reported by Memory Validator and the customer wanted to know why and could we please fix the problem?

After some investigation we found the problem was a not with Memory Validator but with the DLL in question making a call to _CrtSetDbgFlag(0); which turned off all memory tracking for that DLL. Memory Validator honours the memory tracking flags built into Visual Studio and thus did not report these memory allocations. Armed with this information the customer did some digging into their code base and found that someone had deliberately added this call into their code. Removing the call fixed the problem.

The rest of this article explains how Microsoft tags data to be ignored and what flags are used to control this process.

Why does Microsoft mark these allocation as ignore?

The reason for this is that these allocations are for internal housekeeping and sometimes also for one-off allocations that will exist until the end of the application lifetime. Such allocations could show up as memory leaks at the end of the application – that would be misleading as they were intended to persist. Better to mark them as “ignore” and not report them during a memory leak report.

Microsoft debug CRT header block

Microsoft’s debug CRT prefixes each allocation with a header block. That header block looks like this:

#define nNoMansLandSize 4

typedef struct _CrtMemBlockHeader
{
    struct _CrtMemBlockHeader * pBlockHeaderNext;
    struct _CrtMemBlockHeader * pBlockHeaderPrev;
    char *                      szFileName;
    int                         nLine;
#ifdef _WIN64
    /* These items are reversed on Win64 to eliminate gaps in the struct
     * and ensure that sizeof(struct)%16 == 0, so 16-byte alignment is
     * maintained in the debug heap.
     */
    int                         nBlockUse;
    size_t                      nDataSize;
#else  /* _WIN64 */
    size_t                      nDataSize;
    int                         nBlockUse;
#endif  /* _WIN64 */
    long                        lRequest;
    unsigned char               gap[nNoMansLandSize];
    /* followed by:
     *  unsigned char           data[nDataSize];
     *  unsigned char           anotherGap[nNoMansLandSize];
     */
} _CrtMemBlockHeader;

How does Microsoft tag an allocation as ignore?

When the CRT wishes an allocation to be ignored for memory tracking purposes, six values in the debug memory allocation header for each allocation are set to specific values.

Member Value #define
nLine 0xFEDCBABC IGNORE_LINE
nBlockUse 0x3 IGNORE_BLOCK
lRequest 0x0 IGNORE_REQ
szFileName NULL
pBlockHeaderNext NULL
pBlockHeaderPrev NULL

The Microsoft code goes out of its way to ensure no useful information can be gained from the header block for these ignored items.

When we first created MV we noticed that items marked as ignored should be ignored, otherwise you can end up with FALSE positive noise reported at the end of a memory debugging session due to the internal housekeeping of MFC/CRT.

How can you use this information in your application?

Microsoft also provides some flags which you can control which allows you to influence if any memory is reported as leaked. This is in addition to the CRT marking its own allocations as “ignore”. You can set these flags using the _CrtSetDbgFlag(int); function.

The following flags can be passed to _CrtSetDbgFlag() in any combination.

Flag Default Meaning
_CRTDBG_ALLOC_MEM_DF On On: Enable debug heap allocations and use of memory block type identifiers.
_CRTDBG_CHECK_ALWAYS_DF Off On: Call _CrtCheckMemory at every allocation and deallocation request. (Very slow!)
_CRTDBG_CHECK_CRT_DF Off On: Include _CRT_BLOCK types in leak detection and memory state difference operations.
_CRTDBG_DELAY_FREE_MEM_DF Off Keep freed memory blocks in the heap’s linked list, assign them the _FREE_BLOCK type, and fill them with the byte value 0xDD. CAUTION! Using this option will use lots of memory.
_CRTDBG_LEAK_CHECK_DF Off ON: Perform automatic leak checking at program exit via a call to _CrtDumpMemoryLeaks and generate an error report if the application failed to free all the memory it allocated.

How do I disable memory tracking for the CRT?

If you call _CrtSetDbgFlag(0); any memory allocated after that point will not be tracked.

With the above settings, all blocks are marked as ignore. You can see the code for this in the Microsoft C runtime.

The code that marks the block as “ignore” is at line 404 in dbgheap.c in the Microsoft C runtime (also used by MFC). When your code arrives here, nBLockUse == 1 and _crtDbgFlag == 0.

dbgheap.c line 404 (line number will vary with Visual Studio version)
                if (_BLOCK_TYPE(nBlockUse) != _CRT_BLOCK &&
                     !(_crtDbgFlag & _CRTDBG_ALLOC_MEM_DF))
                     fIgnore = TRUE;

This sets fIgnore to TRUE. From this point onwards the memory tracking code ignores the memory and sets the values mentioned above in the memory block header.

Default values

The default value for _crtDbgFlag is set elsewhere in the Microsoft code with this line:

extern "C"
int _crtDbgFlag = _CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_DEFAULT_DF;
Share

Don’t use srand(clock()), use srand((unsigned)time(NULL)) instead

By , July 9, 2010 9:42 am

Typically you use srand() when you need to start the random number generator in a random place. You may do this because you are going to generate some keys or coupons and want them to start in an unpredictable place.

From time to time we provide special offers to customers in the form of a unique coupon code that can be used at purchase to get a specific discount. These coupons are also used to provide discounts to customers upgrading from say Performance Validator to C++ Developer Suite so that they do not pay for Performance Validator twice.

When the coupon management system was written, we used srand(clock()) thinking that would be an acceptable random value for generating coupons. The thinking was the management system would be running all the time and thus clock() would return a value that was unlikely to be hit twice for the number of valid coupons at any one time. However, the way the system is used is that users close the coupon management system when not in use and thus clock() will return values close to the starting time (start the app, navigate to the appropriate place, generate a coupon).

Result: Sooner or later a duplicate coupon is created. And that is when we noticed this problem.

This resulted in a confused customer (“My coupon has already been used”), a confused member of customer support (“That shouldn’t be possible!”) followed by some checking of the coupon files and then the code to see how it happened. Easy to fix, but better selection of the seed in the first place would have prevented the problem.

So if you want better random numbers don’t use clock() to seed srand().

Better seeds

  • Use time(NULL) to get the time of day and cast the result to seed srand().
    time(NULL) returns the number of seconds elapsed since midnight January 1st, 1970.
  • Use rdtsc() to get the CPU timestamp and cast the result to seed srand().
    rdtsc() is unlikely to return duplicate values as it returns the number of instructions executed by the processor since startup.
Share

The cost of using OutputDebugString

By , May 21, 2010 10:02 am

Should you use OutputDebugString? Is that an unusual question to ask? How often have you thought about the potential cost of using OutputDebugString (or TRACE, which uses OutputDebugString under the hood)?

Benefits of using OutputDebugString

The benefit of using OutputDebugString is the ability to leave a relatively benign function in your code that can output useful textual information which can be monitored by a debugger or a suitable utility (such as DebugView).

The TRACE() macro allows you to output information, but only in Debug builds. OutputDebugString() allows you to output the information in Debug and Release builds.

Problems caused by using OutputDebugString

The problem of using OutputDebugString is that it has a performance overhead, which although minimal outside a debugger is much higher in a debugger. If in a busy loop this overhead can be an unwanted burden.

It may be that the information being output by OutputDebugString is not information that you want your customers (or competitors!) to see.

Finally, depending on your software application, it may be that your customers will be using your software component (for example our injected monitoring DLLs) with their software in their debugger, debugging their software. In that situation, your customer may not appreciate the extra OutputDebugString() information filling up their Output tab with information and obscuring whatever information their own OutputDebugString() usage is providing.

I’m sorry to say it, but we have been guilty of this in the past! You may want to check your code to ensure you are not doing this by accident. Its all to easy to let things like this happen – after all there is no obvious adverse effect (like a crash or undefined behaviour) to fail your testing patterns.

Performance cost of using OutputDebugString

I’ve noticed questions asking about the cost of OutputDebugString() on a few forums but never seen any hard numbers to go with the received opinions offered. Being a curious animal I decided that I should investigate. The benefits being that I get to scratch this curious itch and if the news is bad we get to make a few modifications to the software at Software Verification.

OutputDebugString() comes in two flavours, OutputDebugStringA() for ANSI builds and OutputDebugStringW() for Unicode builds. The tests I ran tested both of these WIN32 APIs on Windows XP 64 bit, on a dual quad core Intel Xeon running at 2.83GHz. All tests done under the same load.

Testing OutputDebugString

To test the APIs we need to test a few scenarios:

  • Calling the API when running the test application outside of a debugger. This will be the equivalent of if you leave OutputDebugString() calls in your release mode application and ship it to your customer.
  • Call the API when running the test application in a debugger. This tests the overhead of OutputDebugString() communicating with the debugger so that the debugger can display the message on its output pane (assuming the debugger does that).
  • Call the API when running the test application in a debugger, adding a \r\n at the end of each line. This tests the overhead of OutputDebugString() communicating with the debugger so that the debugger can display the message on its output pane (assuming the debugger does that).

We have chosen to test with Visual Studio 6.0, Visual Studio 2005 and Visual Studio 2010. We have chosen these two IDEs/debuggers since VS6 is the old pre-.Net IDE which is still well loved by a lot of developers. We have also chosen VS2005 because based on what we can tell from our customer base this is a very popular IDE/debugger.

The test for each scenario consists of outputting three different size strings 4000 times. The three strings are a zero length strings, a short string and a longer string. The test is also repeated with the same strings with \r\n appended to the non-zero length strings. We added this test when we realized that the Visual Studio output panel behaves differently between VS6 and VS2005 for lines that do not contain \r\n at the end.

You can download full source code and project files for both VS6 and VS2005 so that you can build and run these tests for yourself. For VS2010 you can load the VS2005 solution file and convert it automatically during the load.

timeOutputDebugString screenshot

Results

We have 7 groups of test results spanning no debugger, Visual Studio 6, Visual Studio 2005, and Visual Studio 2010.

Test 1 – No Debugger

OutputDebugString() called 4000 times, no debugger monitoring the process. No \r\n per output.
What we can see is that OutputDebugStringW() is 9% slower than OutputDebugStringA() and that both calls are very fast.

Function String Time
OutputDebugStringA "" 0.0112s
OutputDebugStringA short string 0.0198s
OutputDebugStringA long string 0.0255s
Average 0.00000470s
 
OutputDebugStringW "" 0.0121s
OutputDebugStringW short string 0.0214s
OutputDebugStringW long string 0.0281s
Average 0.00000513s

Test 2 – Visual Studio 6

OutputDebugString() called 4000 times, Visual Studio 6 monitoring the process. No \r\n per output.
What we can see is that OutputDebugStringW() is 1% slower than OutputDebugStringA() and that both calls are over 19 times slower than without the debugger.

Function String Time
OutputDebugStringA "" 0.03631s
OutputDebugStringA short string 0.03837s
OutputDebugStringA long string 0.3885s
Average 0.00009641s
 
OutputDebugStringW "" 0.3693s
OutputDebugStringW short string 0.3977s
OutputDebugStringW long string 0.4068s
Average 0.00009782s

Test 3 – Visual Studio 6

OutputDebugString() called 4000 times, Visual Studio 6 monitoring the process. One \r\n per output.
What we can see is that OutputDebugStringW() is 2% slower than OutputDebugStringA() and that both calls are over 22 times slower than without the debugger.

Function String Time
OutputDebugStringA "" 0.4048s
OutputDebugStringA short string 0.4247s
OutputDebugStringA long string 0.4267s
Average 0.00010468s
 
OutputDebugStringW "" 0.4127s
OutputDebugStringW short string 0.4346s
OutputDebugStringW long string 0.4419s
Average 0.00010743s

Test 4 – Visual Studio 2005

OutputDebugString() called 4000 times, Visual Studio 2005 monitoring the process. No \r\n per output.
What we can see is that OutputDebugStringW() is 54% slower than OutputDebugStringA() and that both calls are over 65 times (95 times slower for OutputDebugStringW) slower than without the debugger.

Function String Time
OutputDebugStringA "" 1.0270s
OutputDebugStringA short string 1.2200s
OutputDebugStringA long string 1.3982s
Average 0.00030377s
 
OutputDebugStringW "" 1.5850s
OutputDebugStringW short string 1.8874s
OutputDebugStringW long string 2.1672s
Average 0.00046997s

Test 5 – Visual Studio 2005

OutputDebugString() called 4000 times, Visual Studio 2005 monitoring the process. One \r\n per output.
What we can see is that OutputDebugStringW() is 48% slower than OutputDebugStringA() and that both calls are over 68 times (92 times slower for OutputDebugStringW) slower than without the debugger.

Function String Time
OutputDebugStringA "" 1.1133s
OutputDebugStringA short string 1.2766s
OutputDebugStringA long string 1.4455s
Average 0.00031962s
 
OutputDebugStringW "" 1.6444s
OutputDebugStringW short string 1.9108s
OutputDebugStringW long string 2.1501s
Average 0.00047543s

Test 6 – Visual Studio 2010

OutputDebugString() called 4000 times, Visual Studio 2010 monitoring the process. No \r\n per output.
What we can see is that OutputDebugStringW() is 2% slower than OutputDebugStringA() and that both calls are over 133 times (142 times slower for OutputDebugStringA) slower than without the debugger.

Function String Time
OutputDebugStringA "" 2.8112s
OutputDebugStringA short string 2.6041s
OutputDebugStringA long string 2.6408s
Average 0.00067134s
 
OutputDebugStringW "" 2.5735s
OutputDebugStringW short string 2.5891s
OutputDebugStringW long string 3.0845s
Average 0.00068727s

Test 7 – Visual Studio 2010

OutputDebugString() called 4000 times, Visual Studio 2010 monitoring the process. One \r\n per output.
What we can see is that OutputDebugStringW() is 2% slower than OutputDebugStringA() and that both calls are over 132 times (141 times slower for OutputDebugStringA) slower than without the debugger.

Function String Time
OutputDebugStringA "" 2.6517s
OutputDebugStringA short string 2.6604s
OutputDebugStringA long string 2.6423s
Average 0.00066287s
 
OutputDebugStringW "" 2.6675s
OutputDebugStringW short string 2.7529s
OutputDebugStringW long string 2.7410s
Average 0.00068011s

Conclusion

Calling OutputDebugString() when the application is not being monitored by a debugger does not incur significant overhead, although in tight loops this could be problematic.

Calling OutputDebugString() when the application is monitored by Visual Studio 6 can result in OutputDebugString() running between 19 and 22 times slower than without Visual Studio 6 monitoring the application.

Calling OutputDebugString() when the application is monitored by Visual Studio 2005 can result in OutputDebugString() running between 65 and 95 times slower than without Visual Studio 2005 monitoring the application.

Calling OutputDebugString() when the application is monitored by Visual Studio 2010 can result in OutputDebugString() running between 132 and 142 times slower than without Visual Studio 2005 monitoring the application.

The most surprising aspect is that the newer, more modern Visual Studio 2005 and Visual Studio 2010 are so much slower at handling OutputDebugString() than the old Visual Studio 6 IDE, which is now 12 years old. The performance difference is a factor of 3x or 4x (for VS2005) and a factor of 6x or 7x (for VS2010) depending on the test. Our initial tests ran OutputDebugString 100,000 times, but the tests using Visual Studio 2005 were so slow we had to reduce the test run to 4,000 times so that we could get a result in a realistic time frame to do the test.

The other interesting aspect is that with Visual Studio 2005 monitoring the application, the disparity in performance between OutputDebugStringA() and OutputDebugStringW() is even greater. With Visual Studio 2010, the disparity is not so great, but the actual performance level is worse than for Visual Studio 2005.

It may be tempting to write off all of the above information with the remark that this test does not reflect real world usage of OutputDebugString because we are calling it in a tight loop. It is the case that our loop is exceptionally tight as we are trying to time just the function call, but we see in our own development work occasions where OutputDebugString is called frequently enough that while in the debugger there is a serious drop off in performance. For example our interprocess comms for sending data from our monitoring stub to the GUI, if we are debugging so items we either enable some logging or OutputDebugString. This data is provided from the application being monitored at a rate and volume determined by what the application is doing. For Memory Validator, say, monitoring certain apps, that could be 500,000 events just to start the target application. That is 500,000 OutputDebugString calls in our GUI, reporting comms activity. In such a case, using logging may be more efficient. I mention this just to show that although our test has a tight loop, the actual test number (4,000) is well within real world usage.

Share

Thread Lock Checker now available

By , April 22, 2010 6:20 pm

We’ve just released Thread Lock Checker.

Took a bit longer than we anticipated (sorry about that) due to some website maintenance work. Anyway its available now, go and give your source code some TLC and find any latent lock errors in your code!

Thread Lock Checker

Share

Improving how you use CSingleLock

By , April 2, 2010 9:44 pm

Thread Lock Checker Logo

This posting covers a brief background:

  • Win32 critical sections.
  • How CCriticalSection and CSingleLock can be used instead of Win32 critical sections.
  • An improved way to use CSingleLock.
  • Some ways CSingleLock can be used that do not have the desired effect.

Critical Sections in Win32

The Win32 API uses InitializeCriticalSection, EnterCriticalSection, LeaveCriticalSection and DeleteCriticalSection to manage critical sections (CRITICAL_SECTION). Using these APIs is not particularly hard, but nonetheless it is possible to use critical sections that have not been initialized or that have been deleted. It is also possible to forget to leave a critical section that has been entered. In addition, any exceptions that get thrown may result in a critical section being left in its locked state.

This can cause serious performance problems as locks are held for too long, or in the case of a lock not being released, it can prevent other threads gaining access to the resource the lock was protecting, possibly resulting in a deadlock.

Example Win32 usage (assume critical section initialized in a different function):

void someFunc()
{
	doWork();

	EnterCriticalSection(&cs);

	doWorkEx();

	LeaveCriticalSection(&cs);
}

Why use CSingleLock and CMultiLock?

When using critical sections in MFC you use the CCriticalSection class instead of CRITICAL_SECTION objects.

You can directly call Lock() and Unlock() on the CCriticalSection, but it is recommended that you use CSingleLock and CMultiLock to manage your CCriticalSection objects.

The benefits of using a class such as CSingleLock (and its related class CMultiLock) are that:

  • The CSingleLock manages the activities of entering and leaving the critical section – you do not have to think about the critical section at all.
  • Any CCriticalSection object used with CSingleLocks will automatically be initialized before the CSingleLock gets to work with it.
  • The CSingleLock is automatically unlocked (if it was locked) when the CSingleLock is deleted and thus the CCriticalSection that was associated with this CSingleLock is not held locked .
  • If an exception is thrown, C++ objects are cleaned up by the exception handling chain, thus automatically deleting any CSingleLock objects and releasing any locks they hold.
  • CSingleLock can be used to lock and unlock critical sections just like the old Win32 methods, allowing for easy conversion of code from Win32 style to CSingleLock style.
  • It is possible to create a CSingleLock that is automatically locked. This is very useful for set-and-forget critical section management. Just put the CSingleLock in the right place and you can ignore it in the rest of the code. Very neat, convenient and elegant.

One way of using CSingleLock

As described above a typical style of using CSingleLocks echoes the Win32 style of using critical sections.

void someFunc()
{
	CSingleLock	lock(&csSect);

	doWork();

	lock.Lock();
	doWorkEx();
	lock.Unlock();
}

As you can see, the CSingleLock lock manager is created, the doWork() function is called outside of the protected area, the lock is locked, doWorkEx() is called, then the lock is unlocked. This is a very similar style of writing to Win32 equivalent.

A better way of using CSingleLock

The problem with the previous way of using CSingleLock is that most of the power and convenience of CSingleLock is ignored. Lock management has been made explicit via calls to Lock() and Unlock(). This means there is potential for forgetting to lock the CSingleLock, or for unlocking the CSingleLock later than desirable.

An improved way of using CSingleLock is to always create CSingleLocks in the locked state and to create CSingleLocks as close to the resource they are need to protect.

The following example shows the same function written using a CSingleLock that is automatically locked, created just before it is required and automatically destroyed at the end of the function.

void someFunc()
{
	doWork();

	CSingleLock	lock(&csSect, TRUE);

	doWorkEx();
}

If I wanted to some more work after doWorkEx() but I didn’t want that protected by the lock I could do it by using C++’s scoping capabilities. I simply create a new scope and place the CSingleLock in there. At the end of the scope the CSingleLock is destroyed and the lock is unlocked.

void someFunc()
{
	doWork();

	{
		CSingleLock	lock(&csSect, TRUE);

		doWorkEx();
	}

	doMoreWork();
}

Some problems we have seen…

During the development of code for the software tools at Software Verification and our private tools we’ve found a few interesting mistakes. Mistakes often made not through poor design, but simply a typing oversight or mistake, possibly due to tiredness of the person working on the code – the type of mistake you can only put down to the fact that humans do make mistakes, not matter how talented they are in any given field.

Where possible we like to use the CSingleLock lock(&csSect, TRUE) automatic locking style coupled with tight scoping to make the lock lifetime short. As a result we are interested in find the following coding constructs which will result in errors in expected behaviour in our software:

  • CSingleLock created without a lock argument. This defaults to an unlocked CSingleLock.
    CSingleLock	lock(&csSect);
  • CSingleLock created with a FALSE lock argument. This is an unlocked CSingleLock.
    CSingleLock	lock(&csSect, FALSE);
  • CSingleLock created with a variable declaration. This compiles but creates a lock that is immediately destroyed. Any of these three variants are interesting as none of the are useful, but all compile OK.
    CSingleLock(&csSect);
    CSingleLock(&csSect, FALSE);
    CSingleLock(&csSect, TRUE);

Thread Lock Checker

Thread Lock Checker

The problem with the examples we show above is that looking for them is hard work because humans often read what they expect to read (this is part of our predictive pattern recognition built into how we process shapes and text). As a result you may be looking right an error and not see it, but you may see the error the next time you come to the code (having forgotten all about it).

To aid in the discovery of these types of lock usage (for both CSingleLock, CMultiLock and any named classes that have the same style of behaviour) we have written a software tool, Thread Lock Checker.

We use Thread Lock Checker before we release any software. We use Thread Lock Checker to scan our codebase looking for any mistakes not identified by our software engineers. Its a very useful tool. We hope that you will also find Thread Lock Checker useful. Please check back next week for your free download.

We will be releasing Thread Lock Checker during the week of 5 April to 9 April.

Share

Panorama Theme by Themocracy