I recently wrote a function level tracing program. It produces output like this:

loading symbols for module hello
loading symbols for module ntdll
loading symbols for module kernel32
loading symbols for module USER32
loading symbols for module GDI32
loading symbols for module ADVAPI32
loading symbols for module RPCRT4
-> WinMain(00400000, 00000000, 00141ee9, 0000000a)
  -> MyRegisterClass(00400000)
  <- MyRegisterClass ret=c36c
  -> InitInstance(00400000, 0000000a)
    -> WndProc(001b1e00, 00000024, 00000000, 0012f6d0)
    <- WndProc ret=0
    -> WndProc(001b1e00, 00000081, 00000000, 0012f6bc)
    <- WndProc ret=1
    -> WndProc(001b1e00, 00000083, 00000000, 0012f6f0)
    <- WndProc ret=0
  <- InitInstance ret=1
  -> WndProc(001b1e00, 00000008, 00000000, 00000000)
  <- WndProc ret=0
  -> WndProc(001b1e00, 00000002, 00000000, 00000000)
  <- WndProc ret=0
  -> WndProc(001b1e00, 00000082, 00000000, 00000000)
  <- WndProc ret=0
<- WinMain ret=0

The program you are tracing must have been compiled with debugging information. On win32 this means you need an appropriate PDB file in the same directory or in your search path. On linux it means you need binaries that have not been stripped.

You can download from this page source and binaries for win32 (or x64) and try it out. To compile it you will need the latest Debugging Tools for Windows. Make sure you select "custom install" and check the SDK.

One way to start the trace is to attach to an already running process (assuming it was compiled with debug info). This can be useful when you're trying to figure out "what code does that?". You'll need to know the pid of the running process. This can be found using Process Explorer and other task management utilities.

I've also written a Linux version, you can download the source for i386 or the source for amd64. It uses nm to generate a "map" file which it then parses. If there's functions in the output you're not interested in remove the appropriate line from the map file. If you change the input program (say, to fix a bug) make sure you delete the map file before functracing again :)

If you want similar output on Solaris, just use dtrace.

<< back to my home page