Monday, April 6, 2015

Alternate Download linkSampleApplicaiton.zipSource.zipIn big projects, it is common to have thousands of unit test cases. In one of our projects we used boost framework for writing unit TCs and used to run all the TCs in build server after every check-in. The number of TCs eventually grew to thousands and it takes around 3, 4 hours to finish all the test cases. Even though our build server was running on a 32 core machine, we couldn't take advantage of it because boost's framework always run test cases in one thread. Running in multiple thread is not a generic solution as the testcases might be accessing some shared object that could cause synchronization issues. There is one alternate solution available via CMake which is describe in the post Run your Boost Tests in parallel with CMake . The only down side of this solution is that, you have to list down each testcase of your unit test application in the makefile. When we have thousands of test cases, it is not a very feasible solution. Then we started looked into the boost test framework and see if anything cane be done at the framework side.

Tweeking startup code

Supported OS: Windows and Unix - compatible OS

Tested on boost 1.47

This solution actually works with a slight modification in main function of boost test case. All you have to do is to include unit_test_main_parallel.hpp instead of boost/test/unit_test.hpp in your unit test case project.After building your unitestcase application, to run the testcases in parallel simply add the option "--dist_tc="

For eg:

c:\Naveen\tmp>UnitTestApp.exe --dist_tc=5

The above command will start one parent UnitTestApp.exe and 5 child UnitTestApp.exe , each executing one test case at a time. Here is how it looks in process explorer.

Once a child application finishes the unit test case assigned to it, the child process exit by itself and another child application is spooled by the parent to execute the next TC. Please note that this option is incompatible with --run_test option. if --run_test is specified, --dist_tc option will be ignored.

Under the Hood

Underlying implementation is actually quite simple.

When application starts, it traverse though all test case in the application and create a list of test cases.

For each test case in the list, invoke child process with an additional --run_test option specifying the test case name.

Redirect the console output of child process back to the parent application and print it.

Files

There are 3 files in this source

unit_test_main_parallel.hpp - Main header file that you need to include.

unit_test_main_unix.ipp - unix specific code.

unit_test_main_win.ipp - windows specific code.

Since Windows doesn't support POSIX API's, I had to write separate implementation for windows OS's. The unit_test_main_parallel.hpp will choose one of the .ipp file depending the platform in which it is getting compiled.

Monday, May 23, 2011

This is the 3rd post related to the LeakMon tool. In this post we will see how the DumpViewer( DumpViewer is an application used to analyze the leak dump created by LeakMon ) is able to open a perticular file in Visual Studio and highlight the specified line.

Step 1:- Finding out the version of Visual studio to use
It is 2011 now and we have Visual studio 2010. But there are peoples or companies who still use Visual Studio 6. Things have changed a lot from Visual Studio 6 to Visual Studion 10, even the EXE name has changed. So the first task is to find out which verion of Visual Studio to use.

DumpViewer uses the same Visual Studio version that is reigstered as the default program for documents such as .c, .cpp, .h, .hpp in your machine. For instance, say we have the following line shown in DumpViewer..

func2 t:\naveen\pgms\cpp\2008\mulitthread\mulitthreaddlg.cpp(178)

DumpViewer will extract the file path and line number, from the above line and pass it to the FindExecutable function. This function will return the path of executable that is registered for above file types, which will be usually Visual Studio. If it is not Visual Studio, sorry it will fail!

In the file name of the executable returned by FindExecutable function, we will check there is a string "msdev.exe" or "devenv.exe" in it. If there is "msdev.exe" in the string, code that does the automation of Visual Studio 6 is called or otherwise the code to handle higher version of Visual Studio.

Since we are going to open a file through auotmation, we need a pointer of either IApplication or _DTE (IApplication for Visual Studio 6 and _DTE for Visual Studio 7 and higher ) . We can create and instance of above type using the CoCreateInstance by passing the IID and CLSID. But this will create a new instance of VisualStudio each time we try to open a new file. So what we want is to get a pointer to IApplication / _DTE of an already running instance of Visual Studio if any. This can be done by enumerating the Moniker in the ROT (Running Object Table).

As you can in the above code, if we failed to get a vaild instance pointer of Visual Studio, we create a new one using CoCreateInstance. In Visual Studio 7 and higher, as soon as we release the com pointer that we got from CoCreateInstance, Visual Studio will terminate. To prevent Visual Studio from exiting like this, we need to call put_UserControl of DTE interface.

Step 3 Opening a File and selecting a line of it
From this part on, the processing is different for Visual Studio 6 and other versions of Visual Studio.

Wednesday, March 30, 2011

Consider the case of tracking memory allocation. In this case, Leakmon will hook all the possible memory allocation and de-allocation functions. So when ever a function allocates some memory it will keep the pointer to the newly allocated memory as a key in a map and the call stack as value. If this memory is de-allocated, this entry in the map is removed. So at any point all the entries in the map are those memory pointers which haven't de-allocted. When you ask the Leakmon to Dump the leak, all it does is dumping the entries in the map.

This application has the following distinguishing features from the other resource leak tracking applications in codeproject and around.

1. You dont have to modify any single line of code to start tracking

2. It will track the allocation from all the binaries in the process. Means the tracking is not restricted to only the EXE binary of the process. It will track allocation from all the dependent DLL's as well

OK, Let's start with the working of LeakMon from the first binary, Injector.exe

Injector application

﻿

The Injector.exe allows you to select the process of which you want to track leak. It will list all the process in the system with the help of CreateToolhelp32Snapshot, Process32First and Process32Next functions.

So, when if you select a process and press the "Inject" button, what it does is, It will inject the "HookDll.dll" to the traget process' address space. This is done with the help of CreateRemoteThread API. Injecting a DLL using CreateRemoteThread API is explained detailed in the article Three Ways to Inject Your Code into Another Process. Anyway in Injector.exe the following code part does the injection.

HookDll.dll is the core part of the LeakMon. It performs almost all of the resource tracking stuffs. HookDll starts its working once it got injected into the target process. The BOOL CHookDllApp::InitInstance function gets called when this dll is loaded in the target process. This function however doesn't do much other than just creating a worker thread, DumpController.

Now when the DumpController starts, it will first show the configuration dialog, where you can,
1. Select what kind of resource allocation you want to track
2. Select the path of the PDB's of the application
3. Stack depth

DebugHelp Functions

HookDll creates the call the stack, with the help of DebugHelp Functions. For the DebugHelp function to return the call stack correctly, it is necessary that you specify the correct PDB path of the application. Also it always good to use the latest version of the dbghelp.dll that comes with latest version of Debugging tool for windows. Another good feature that LeakMon support is integration with symbol server. However, adding the Symbol server functionality is very easy. All you have to do is to ensure that, the symsrv.dll is present in the same directory from where dbghelp.dll is loaded.

So now once you click the OK button, in the config dialog, the HookDll will start initializing symbol handler. To initialize symbol handler we have to call SymInitialize. When you call SymInitialize with the value of fInvadeProcess as TRUE, it will load symbol table for all the dlls in the process. But wait, we do better, we can show the progress of loading the symbols of each dll. Showing the progress of symbol loading is important especially when you are downloading a symbol from symbol server, which may take significant time.You might have seen this feature in Visual studio. when you start debugging an application in VS, it will show the symbol loading progress of each dll in the status bar.

To show the progress, we can register one call back with the function SymRegisterCallback64. Our callback function will get called before loading each symbol.

To intercept the allocation and de-allocation calls(functions) made by dll's, LeakMon relies on User mode API hooking though IAT patching. I am not going to explain the IAT patching because there are already several articles in codeproject and other sites having a detailed explanation. Here is one good article to start with API hooking revealed.

How ever one thing that is different in LeakMon with usual custom is that, it doesn't walk through the dependency chain of dll. I mean, if A.exe has statically linked to B.dll and again if B.dll is linked to C.dll, what usually does for API hooking is, it will hook the API imported by A.exe, then find out the dependency of A.exe, which is B.dll, so hook its imported functions. Then it find out the depended dll of B.dll which is C.dll, hook it functions and so on. The problem with this approach is that only statically linked dlls will be hooked. If you are making some calls to a COM dll or if I you are creating an Active-X control in your application, those dll will never get hooked. So instead of walking through the dependency chain, Leakmon, enumerates all the dll's in that process and hooks it. In fact this approach is a little more easier too. It make use of the Module32First and Module32Next set of functions for this purpose.

As you can see, this application can track three kind of resource allocation and de-allocation namely Memory, GDI objects and HANDLES. Windows have a wider set of function for allocation and de-allocation for each of of resources. The following table shows the list of API's LeakMon hooks for tracking allocations/de-allocation of resources.

Memory allocation and de-allocation functions

HeapAlloc

HeapFree

HeapReAlloc

VirtualAllocEx

VirtualFreeEx

GlobalAlloc

GlobalReAlloc

GlobalFree

LocalAlloc

LocalReAlloc

LocalFree

GDI object creation and deletion functions

Bitmaps

LoadBitmapA

LoadBitmapW

LoadImageA

LoadImageW

CreateBitmap

CreateBitmapIndirect

CreateCompatibleBitmap

CreateDIBitmap

CreateDIBSection

CreateDiscardableBitmap

CopyImage

GetIconInfo

GetIconInfoExA

GetIconInfoExW

Icons

CopyIcon

CreateIcon

CreateIconFromResource

CreateIconFromResourceEx

CreateIconIndirect

DestroyIcon

DuplicateIcon

ExtractAssociatedIconA

ExtractAssociatedIconW

ExtractAssociatedIconExA

ExtractAssociatedIconExW

ExtractIconA

ExtractIconW

ExtractIconExA

ExtractIconExW

LoadIconA

LoadIconW

PrivateExtractIconsA

PrivateExtractIconsW

Cursor

CreateCursor

DestroyCursor

LoadCursorA

LoadCursorW

LoadCursorFromFileA

LoadCursorFromFileW

Brush

CreateBrushIndirect

CreateSolidBrush

CreatePatternBrush

CreateDIBPatternBrush

CreateDIBPatternBrushPt

CreateHatchBrush

Device context

CreateCompatibleDC

CreateDCA

CreateDCW

CreateICA

CreateICW

GetDC

GetDCEx

GetWindowDC

ReleaseDC

DeleteDC

Font

CreateFontA

CreateFontW

CreateFontIndirectA

CreateFontIndirectW

Metafile

CreateMetaFileA

CreateMetaFileW

CreateEnhMetaFileA

CreateEnhMetaFileW

GetEnhMetaFileA

GetEnhMetaFileW

GetMetaFileA

GetMetaFileW

DeleteMetaFile

DeleteEnhMetaFile

CopyEnhMetaFileA

CopyEnhMetaFileW

CloseEnhMetaFile

CloseMetaFile

Pen

CreatePen

CreatePenIndirect

ExtCreatePen

Region

PathToRegion

CreateEllipticRgn

CreateEllipticRgnIndirect

CreatePolygonRgn

CreatePolyPolygonRgn

CreateRectRgn

CreateRectRgnIndirect

CreateRoundRectRgn

ExtCreateRegion

Palette

CreateHalftonePalette

CreatePalette

Common Function

DeleteObject

Handle creation and deletion functions

Synchronization objects

CreateEventA

CreateEventW

CreateEventExA

CreateEventExW

OpenEventA

OpenEventW

CreateMutexA

CreateMutexW

CreateMutexExA

CreateMutexExW

OpenMutexA

OpenMutexW

CreateSemaphoreA

CreateSemaphoreW

CreateSemaphoreExA

CreateSemaphoreExW

OpenSemaphoreA

OpenSemaphoreW

CreateWaitableTimerA

CreateWaitableTimerW

CreateWaitableTimerExA

CreateWaitableTimerExW

OpenWaitableTimerA

OpenWaitableTimerW

File function

CreateFileA

CreateFileW

CreateFileTransactedA

CreateFileTransactedW

FindFirstFileA

FindFirstFileW

FindFirstFileExA

FindFirstFileExW

FindFirstFileNameTransactedW

FindFirstFileNameW

FindFirstFileTransactedA

FindFirstFileTransactedW

FindFirstStreamTransactedW

FindFirstStreamW

FindClose

OpenFileById

ReOpenFile

CreateIoCompletionPort

Authorization function

CreateRestrictedToken

DuplicateToken

DuplicateTokenEx

OpenProcessToken

OpenThreadToken

Directory management

FindFirstChangeNotificationA

FindFirstChangeNotificationW

FindCloseChangeNotification

File mapping

CreateMemoryResourceNotification

CreateFileMappingA

CreateFileMappingW

CreateFileMappingNumaA

CreateFileMappingNumaW

OpenFileMappingA

OpenFileMappingW

Memory

HeapCreate

HeapDestroy

GlobalAlloc

GlobalReAlloc

GlobalFree

LocalAlloc

LocalReAlloc

LocalFree

Process and thread

CreateProcessA

CreateProcessW

CreateProcessAsUserA

CreateProcessAsUserW

CreateProcessWithLogonW

CreateProcessWithTokenW

OpenProcess

CreateThread

CreateRemoteThread

OpenThread

CreateJobObjectA

CreateJobObjectW

Mail slot

CreateMailslotA

CreateMailslotW

pipe

CreatePipe

CreateNamedPipeA

CreateNamedPipeW

Registry

RegCreateKeyExA

RegCreateKeyExW

RegCreateKeyTransactedA

RegCreateKeyTransactedW

RegOpenCurrentUser

RegOpenKeyA

RegOpenKeyW

RegOpenKeyExA

RegOpenKeyExW

RegOpenKeyTransactedA

RegOpenKeyTransactedW

RegOpenUserClassesRoot

RegCreateKeyA

RegCreateKeyW

RegCloseKey

Common functions

DuplicateHandle

CloseHandle

Note:- I have tried my best to include all the functions I know which allocates or de-allocate resources. Still, if know some function that i have missed, please let me know.

Now lets see how the hooking works. For each of the function in the above table LeakMon have a dummy function ( Which is actually 199 dummy functions ). So after hooking, the application will be calling my dummy function instead of the original function. In the dummy function what it does is,

The CreateCallStack function creates the current function call stack and save it in a map. The key of the map is the memory address returned by original HeapAlloc and value is a structure which holds the call stack and size of memory allocated.

Now when the application calls HeapFree, the dummy function just removes the entry from the map and then call the original HeapFree function.

This is the only part which actually has different processing for 64 bit and 32 bit. In 32 bit applications the call stack is created using the StackWalk64 function. You can either check the code ( StackDump function ) or read this nice article Walking the callstack, to learn more about the StackWalk64 function.

After the hook dll have setup all the hooks, it will wait for couple of events. One among those event is Dump event. When user clicks on the Dump button in the Injector application, it will set the dump event to signalled state. When this event is signalled the thread in the HookDll will start dumping each entry in the map to a user specified file. The format of the dumpfile is mentioned in the previous post.

That's all the main thing about the Injector and HookDll. There is one more application DumpViewer, which actually has some nice features done using Visual Studio automation. I will explain those things in another post.

Open Source

I got couple of request to make this project open source, so I have opened a project in code.google.com and is available at http://code.google.com/p/leakmon/ . So if you have some idea or got some improvement points you are welcome to join me there. Suggestions are also welcome.

Tuesday, January 25, 2011

LeakMon is a light weight resource leak tracking utility which can track Memory leaks, GDI object leaks and handle leaks of a process. This tool is suitable mainly for tracking down the leaks that happens in between an operation.

This tool consists of three binaries, Injector, HookDll and a DumpViewer.
To start with, run the Injector.exe.

﻿

• Refresh :- Refresh the process list
• Inject :- Injects the hook DLL to the target process to start tracking of the leak
• Dump : - Dumps the leak found so far to a file.
• Reset: :- Ignore/Clear all the leaks found up to this point.
• PDB Info : - After Injecting the DLL to the target process, you can click this button to view and make sure that all the pdb’s of necessary DLL’s are loaded correctly.

Using the injector.exe, select the target process that you want to debug. In this case say "MultiThread.exe". Now to start tracking, click the “Inject” button. On doing this, a settings window as in the below figure will pop up. (Note: The settings window is actually shown in the target process' context).

The setting window allows you to choose the “type of leak” you want to track. The types include memory leak, GDI leak and Handle leak.

The next option in the Settings dialog is “Stack Depth”. The value in the stack depth controls the number of functions that will be retrieved while tracking the allocation call stack. The value you enter in here can considerably affect the speed of the application. Lesser the value, the faster the application will be.

Collecting the call stack will never be perfect, without proper PDB files. So to get proper call stack information, specify the path PDB files of the binaries used in your application. Without the pdb’s of Microsoft dll’s such as MSVCRT.dll, MFCxx.dll etc, you will not be able to see the call stack of memory allocated using new and new[] sometimes. If you don’t have the symbols for Microsoft dlls, click on the “Add Symbol server”. Also it is a must that you have to specify the Folder in which the LeakMon binary resides. (“T:\LeakMon” in the below sample). Once you have set all the necessary pdb’s path click OK. The tracking starts from this moment

So now, once you have finished your processing and want to see all the allocations that haven’t de-allocated, press the “Dump” button in the injector. If there is some leak, it will prompt you with a save dialog, though which you can save the leak information file.Analyzing the leak dump file

I will explain the format of the dump file with the following example. Consider the below code

i.e. The sequence of calling is in the order

CMulitThreadDlg::OnBnClickedButton1()->func1()->func2().

Now the information regarding the memory leak in the above code will look as follows.

Starting from the top function, traverse down, until you find a function from your file. In the above case, func2().So it can be concluded that, some memory that has allocated from the func2() haven’t de-allocated.

Analyzing the leak with DumpViewer

Even though you can viewer the dump file in any text editor, DumpViewer provides you some extra features that are really handy. Most of the features are self explanatory. One of the main feature is that, when you double click on a particular function in the tree, it will open the source file in visual studio with the line in which leak occurred as selected.

Under the Hood

This application basically works by hooking all the possible functions that allocates and de allocates a resource. For example when tracking memory leak it hooks the memory allocation API's such as HeapAlloc, HeapFree, VirtualAlloc, VirtualFree etc. A more detailed step by step explanation of this tool will be posted in next posts.

I have tried my best to remove the bugs in this application. But still if you encounter any bugs, let me know. Suggestions or improvements are highly appreciated.

Tuesday, October 20, 2009

My development environment usually includes large number of binaries. And I was working in some core library module which is used by many other dlls. So whenever I change something in the header file of this code library, I have to rebuild all the dependent libraries. Rebuilding the entire environment was not practical all times. So I had to create such an utility so that I can find out who all uses this code library and can rebuild those modules only.

How to Use

In the “Dll Name” edit box, enter the name of the dll for which we have to search for.

In the “Path” edit box, enter the folder in which we have to search for dlls/exe/ocx that uses dll entered in the “Dll Name” edit box.

Click “Start” button.

Upon clicking the Start button, the list control starts’ populating the Dll, OCX and EXE’s that uses the specified dll. Please note that this application will not list dynamic dependencies and so we cannot enter ocx or COM dll as “Dll Name”.

How it works

When the start button is clicked, the application loop through each Dll, OCX and EXE’s in the specified folder. It opens each binary, parse the PE (Portable Executable) file format.For example consider that user32.dll is specified in the "Dll name" edit box and the path is "c:\windows\system32". When user clicks on the “start” button, the application took a loop to find EXEs, dll's and OCXs in the specified folder. Intitally it enumarets all the EXEs. Suppose we got "calc.exe" as file name. The next thing to do is to map the binary file to memory. This is performed with the help of CreateFileMapping() and MapViewOfFile() function.

As you can see in the above code, after the binary is loaded to the memory, the memory address is passed to the CheckForDependecy() function. The function cast the memory address to a IMAGE_DOS_HEADER pointer.

PIMAGE_DOS_HEADER pDOSHeader = (PIMAGE_DOS_HEADER) lpStartAddress;

After this, it will try to get the IMAGE_NT_HEADERS from pDOSHeader. Usually the 16 bit binaries will not be having this header. So we will ignore such binaries at this point.

May be because of the property of data in the file, it may occur that the pNTHeader points to a valid memory. So we will add one more checking to confirm that we are dealing with PE file (The famous DRWATSON.EXE fails at this checking!!!ya it is not a PE file).

The next task is to find the IMAGE_IMPORT_DESCRIPTOR. The IMAGE_NT_HEADERS.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]. VirtualAddress holds the relative address of IMAGE_IMPORT_DESCRIPTOR from the starting of the memory. We can use the ImageRvaToVa() API to convert the relative adress to virtual address. There's one IMAGE_IMPORT_DESCRIPTOR for each imported executable. So we will loop through each item and check whether it is for importing the specified dll (“user32.dll” in our case )

Saturday, April 18, 2009

Normally when we call the DoModal() function of a dialog, the dialog will created and displayed at the center of the parent dialog.

But when a modless dialog is displayed, the child dialog will be displayed at the top left portion of the parent dialog.

I noticed this when a codeproject user asked how to centralize a modeless child dialog. Initially I thought that MFC might be doing some thing in the DoModal() function. So I stepped into the DoModal() function. But I couldn't find any difference in the dialog creation in CDialog::DoModal and CDialog::Create().Another difference that I know between a modal and modeless dialog is that, in the case of the modal dialog, the parent window will be disabled. MFC does this inside the DoModal() function. To try my luck I disabled the parent window before calling the Create function of dialog. Surprisingly it worked! The modeless child dialog came at the center of parent dialog.

So if you want to centralize a modeless dialog, just disable the parent dialog before create and re-enable it after the creation.

Saturday, December 20, 2008

A codeproject poster asked this question. He was already aware of the NetLocalGroupGetMembers function with which, was can the list of users in any groups in the system. How were he wasn't quite sure how to use it and there wasn't any sample code in the internet. So I wrote a sample and posted in codeproject and here is the copy of it.