Special Command—Using !for_each_frame to Run Commands

!for_each_frame is a favorite among debuggers. It's a very flexible and powerful command that enables you to run commands for each frame of the call stack.

You can use basically any command. 

For instance, let’s say you want to see all local variables from each frame of a specific stack. Of course, to see local variables you must have private symbols.

0:025> !for_each_frame dv /i /t /V

_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

00 0532fcd0 776f8edc ntdll!NtWaitForSingleObject+0x15

Unable to enumerate locals, HRESULT 0x80004005

Private symbols (symbols.pri) are required for locals.

Type ".hh dbgerr005" for details.

_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

01 0532fd34 776f8dc0 ntdll!RtlpWaitOnCriticalSection+0x13e

Unable to enumerate locals, HRESULT 0x80004005

Private symbols (symbols.pri) are required for locals.

Type ".hh dbgerr005" for details.

_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

02 0532fd5c 00414ee7 ntdll!RtlEnterCriticalSection+0x150

Unable to enumerate locals, HRESULT 0x80004005

Private symbols (symbols.pri) are required for locals.

Type ".hh dbgerr005" for details.

_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

03 0532fdc8 00414834 mtgdi!CBallThread::SingleStep+0x147 [c:\downloads\mtgdi\threads.cpp @ 180]

prv local 0532fdc4 @ebp-0x04 class CBallThread * this = 0x043349f0

_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

04 0532fe20 00414d8c mtgdi!CGDIThread::InitInstance+0x44 [c:\downloads\mtgdi\threads.cpp @ 65]

prv local 0532fe1c @ebp-0x04 class CGDIThread * this = 0x043349f0

_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

05 0532fe78 5a67d3e3 mtgdi!CBallThread::InitInstance+0x2c [c:\downloads\mtgdi\threads.cpp @ 156]

prv local 0532fe74 @ebp-0x04 class CBallThread * this = 0x043349f0

_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

06 0532ff40 6d97dfd3 mfc90d!_AfxThreadEntry+0x303

Unable to enumerate locals, HRESULT 0x80004005

Private symbols (symbols.pri) are required for locals.

Type ".hh dbgerr005" for details.

_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

07 0532ff7c 6d97df69 MSVCR90D!_callthreadstartex+0x53

Unable to enumerate locals, HRESULT 0x80004005

Private symbols (symbols.pri) are required for locals.

Type ".hh dbgerr005" for details.

_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

08 0532ff88 75ec3f39 MSVCR90D!_threadstartex+0x89

Unable to enumerate locals, HRESULT 0x80004005

Private symbols (symbols.pri) are required for locals.

Type ".hh dbgerr005" for details.

_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

09 0532ff94 77710409 kernel32!BaseThreadInitThunk+0xe

Unable to enumerate locals, HRESULT 0x80004005

Private symbols (symbols.pri) are required for locals.

Type ".hh dbgerr005" for details.

_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

0a 0532ffd4 777103dc ntdll!__RtlUserThreadStart+0x70

Unable to enumerate locals, HRESULT 0x80004005

Private symbols (symbols.pri) are required for locals.

Type ".hh dbgerr005" for details.

_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

0b 0532ffec 00000000 ntdll!_RtlUserThreadStart+0x1b

Unable to enumerate locals, HRESULT 0x80004005

Private symbols (symbols.pri) are required for locals.

Type ".hh dbgerr005" for details.

_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

00 0532fcd0 776f8edc ntdll!NtWaitForSingleObject+0x15

Comments

  • Anonymous
    September 10, 2009
    I have been trying your example here and I do have private symbols but windbg seems to think otherwise. What could I have done wrong

  • Anonymous
    September 14, 2009
    Have you tried .reload /o /f ? Try to do that, it's going to overwrite your cache and force symbols to be downloaded. If that doesn't work use !chksym to make sure the symbols match to the modules. If possible paste the results here. Thanks, Roberto