Unfortunately, setting up kernel debugging with the DDK debugger, WinDbg, is notoriously difficult. This setup was useful for another reason: if we did something that led to a reboot or reinstallation of the operating system, the development environment was unaffected.
The debugger monitors and controls the target machine through a serial cable connecting the two machines.
To address this we used a two-system debugging environment: the debugger runs on the host machine (the development machine), and the software that is being tested runs on the target machine.
Since much of the code in a tracer is executed before the system has completely started up, it runs before a debugger program can be launched.
Creating a Debugging Environmentīecause a tracer contains and interacts with a lot of code that runs in kernel mode, we needed a kernel-mode debugger. We'll explain the issues we encountered in that exercise, and also discuss our performance benchmarks. We developed VTrace for Windows NT and later ported it to Windows 2000. Finally, we wrote code to log context switches, to log system calls to the Win32® subsystem and the kernel, to monitor the file system, and to log the beginning and end of all processes and threads.
Then we modified the Windows keyboard filter to log key presses, Russinovich and Cogswell's Filemon filter driver (from their SysInternals Web site at ) to monitor file system activity, and a physical disk filter to log physical disk activity, in addition to writing a network filter driver. How did we do it? We set up a debugging environment and wrote what we call an initialization driver (which we'll explain later) for VTrace and a logger driver that time-stamped and logged all events.
VTrace contains over 30,000 lines of code in C, C++, and assembler. We wanted the tracer to be unintrusive and to respect the confidentiality of user data so that users would let us trace their systems. This required traces of many different types of system objects: processes, threads, messages, waitable objects, key presses, file systems, disks, and the network. Because we were studying the effects of varying the CPU voltage and clock speed and of powering down various system components, we needed to know when power-consuming components (such as the CPU, the disk, and the network interface card) were active and what they were doing at each instant. We needed time-stamped traces of certain activities in Windows NT and Windows 2000 to study new energy management techniques for laptop computers. In building VTrace, the tracer we created for Windows NT and Windows 2000, we had to deal with all these problems. Writing a tracer for Windows NT® and Windows® 2000 is even more difficult because source code isn't available, descriptions of internal operations are incomplete, and even the interface isn't always well documented. Many runs require rebooting the computer, and failed runs can require reinstalling the operating system or even reformatting the hard drive.
The size and complexity of an operating system complicates debugging, and it's especially tricky to debug code that runs before the system has fully started up. Riting a tracer for an operating system can be a nightmare. The technique uses a DLL loaded into the address space of every process to intercept Win32 system calls establishes hook functions for Windows NT kernel system calls modifies the context switch code in memory to log context switches and uses device filters to log accesses to devices. VTrace collects data about processes, threads, messages, disk operations, network operations, and devices. This article describes the techniques used to construct VTrace, a system tracer for Windows NT and Windows 2000. This article assumes you�re familiar with C, Windows NT, and Windows 2000 Level of Difficulty 1 2 3 The VTrace Tool: Building a System Tracer for Windows NT and Windows 2000