Qlockwork very rarely crashes, so we don’t get much practice with this (haven’t done it in 10 years!), so thought we’d write it up as we went along. Windows has a very neat feature called crash dumps. You can create these from a crashing application and it includes a snapshot of all of the application’s memory. Very handy!
- Reproduce the issue (application crash)
- Do not close the Application has stopped working window
- Run Windows Task Manager (press Ctrl-Shift-Esc or right click in the bar at the bottom of the screen and select “Start Task Manager”)
- The Task manager will open
- Go to the Processes tab and right-click on the crashed process (qlockmon.exe or qwtrackv3.exe)
- Select the Create Dump File item
Get your customer to send the .DMP file to you.
Now you need a debugger to read this. Install the windbg debugger, which you can get from downloading the “Windows Kit” for Windows 8.
Run Windbg.exe and choose File->Open Crash Dump to open your dump file.
Now choose View->Callstack to see the call stack at the time of failure.
Below is a callstack for an application called qlockmon that we are going to analyse:

The top is where the application crashed (in this case inside an unhandledexceptionfilter).
We want to know where in the code qlockmon+0x17785 is.
For that, you need the .map file and .cod files from your build.
A .map file is set of linker outputs that tell you where particular functions are within your code. a .map file is produced when you link with the linker option /map.
A .cod file is a mixture of the assembler and code for each function, which will tell you where a particular line is within a function and what code it corresponds to. To get a .cod file, compile (in VS) with the option /FAsc.
With an address like qlockmon+0×17785 your first port of call is the .map file for your executable or dll. At the top of this is the preferred load address (typically 00400000 for an exe). Note this down.
Next, scoot down to the list of functions in columns. In this section you are interested in the columns “Publics by Value” (the function names), “Rva+Base” (the function start addresses) and “Lib:Object” (lib or exe).
Take qlockmon+0×17785 as our example. This is somewhere in a function in qlockmon, but which function?
first add the preferred load address for qlockwork to the supplied address:
x00400000 + 0×17785 = 0×00417785
Now, we need to find that in our rva+base column. Since this will be in the middle of a function, we just need to find which function contains the address (i.e. starts before the address and finishes after it).
Once we’ve done that, we note down the start address of that function. Let’s say the function was foobar() and it started at 0×00417700.
We are looking for the line of assembler at offset 0×00417785-0×00417700 = 0×85 within the identified function (foobar) .
We need to know which line in foobar() this offset refers to. For that we need the .cod file. Open the .cod file which contains the function. Search down through the file to find the function, then count off until you get to the assembly line offset x85 within that function. That should be the assembly line you crashed in. Step back up to the preceding code line that’s in your stack. Reconstruct your callstack, and you are 90% of the way to solving your problem.