Using FlowTrace


Now that you have a basic understanding of what function hooking looks like with the Profiling API, I want to turn to describing how to use FlowTrace. Knowing how to use it will make understanding some of its implementation issues easier. As with anything that uses the Profiling API, you face environment variable city to get your profiler set up and running. Like ExceptionMon from Chapter 10, FlowTrace lets you specify whether you'd like to trigger a DebugBreak call on startup (FLOWTRACEBREAK) as well as specify exactly which process you want to profile (FLOWTRACEPROC). Additionally, to specify where you want the output files written, you can set the FLOWTRACEFILEDIR environment variable to point to a specific directory. I'll discuss the FlowTrace .FLS settings file in a moment, but if you specify FLOWTRACEFILEDIR, FlowTrace will look for the .FLS file in that directory instead of the directory in which the executable resides.

To keep everything straight for multithreaded applications, FlowTrace's output writes each thread to a different file. The file naming is as follows:

<process name>_<Win32 process ID>_<managed thread ID>.FLOW

The different parts of the filename should be self-explanatory. The only interesting part is that I used the managed thread ID instead of a Win32 thread ID. As you'll see later in the implementation section, there's no correlation between a managed thread and a Win32 thread.

Your final task before using FlowTrace is setting up the optional settings file. The file is a simple initialization file located in the same directory as the executable or where the FLOWTRACEFILEDIR environment variable points, and it is the program name with an .FLS extension. Although I could have used the ultramodern technique of an XML file, I just didn't feel like spending several months writing and testing code that uses MSXML3.DLL from C++ and bloating the FlowTrace working set by tens of megabytes. There is no sense in making things more complicated than they have to be.

The first of the three optional settings supported by FlowTrace is determining whether inlining should be on. By default, inlining is turned on so that the process running under FlowTrace will run faster. The second option is disabling logging of the finalizer thread. All .NET processes have the garbage collector running in a separate thread. I found that the majority of calls made on the finalizer thread were related to cleaning up the CLR-created objects. To keep the output to a minimum, I preferred to record only the real process flow on the other threads because that's more informational in my opinion. Therefore, by default, FlowTrace doesn't record the finalizer thread, but you can easily enable that recording. The third option lets you decide whether to record the startup code for the initial AppDomain created on the main thread since the System.AppDomain.SetupDomain method creates huge amounts of trace output. By default, I don't record the startup. In Listing 11-2 is a default .FLS file. To enable a particular option, set it to 1; a 0 (zero) disables it.

Listing 11-2: A Default .FLS File

start example
; This is an example .FLS configuration file. Name this file ; the same name as the executable and put it in the same ; directory as the EXE.     ; All general options are here. All values shown are the defaults ; if no .FLS file is present for the executable. [General Options] ; Turns off inlining if set to 1. This will lead to much ; larger trace flows. TurnOffInlining=0     ; Does not process anything in the finalizer thread. IgnoreFinalizerThread=1     ; Skips all AppDomain startup calls on the main thread. SkipStartupCodeOnMainThread=1
end example




Debugging Applications for Microsoft. NET and Microsoft Windows
Debugging Applications for MicrosoftВ® .NET and Microsoft WindowsВ® (Pro-Developer)
ISBN: 0735615365
EAN: 2147483647
Year: 2003
Pages: 177
Authors: John Robbins

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net