views:

78

answers:

2

I would like to have a break on the SetTimer function in order to see which components register what timers with what values. Is this possible?

+8  A: 

Yes, you can do this. First make sure you have public symbols setup for your debugger.

SetTimer lives in user32 but that is just what it is exported as. The easiest way to do this is with the command line debugger, NTSD. We need its real name, so look for symbols in user32 that match:

0:000> x user32!*timer*
759992b9 USER32!NtUserValidateTimerCallback = <no type information>
759977d5 USER32!NtUserSetTimer = <no type information>
759e4f13 USER32!NtUserSetSystemTimer = <no type information>
759993bf USER32!NtUserKillTimer = <no type information>

Ah-ha! Its debug symbol is NtUserSetTimer:

0:000> bp user32!NtUserSetTimer

In Visual Studio, you can figure out where SetTimer lives by writting a simple scratch program and then setting a breakpoint and right clicking and selecting "Go to Disassembly":

int _tmain(int argc, _TCHAR* argv[]) {
  SetTimer(NULL, 0, 0, NULL);
004113BE  mov         esi,esp 
004113C0  push        0    
004113C2  push        0    
004113C4  push        0    
004113C6  push        0    
004113C8  call        dword ptr [__imp__SetTimer@16 (418338h)] 

If we step into that call, then we land here:

_NtUserSetTimer@16:
759977D5  mov         eax,123Dh 
759977DA  mov         edx,7FFE0300h 
759977DF  call        dword ptr [edx] 
759977E1  ret         10h  

So the to set a breakpoint there in Visual Studio, you have to use the context operator in the breakpoint. Select from the menus: Debug -> New Breakpoint -> Break at Function, then enter:

{,,user32.dll}_NtUserSetTimer@16
jeffamaphone
I was unaware that it is possible to set breakpoints using commands. I have never used this feature. Where do I enter the string you provided?
ronag
The first one is for the command line debugger: http://www.microsoft.com/whdc/devtools/debugging/default.mspx
jeffamaphone
Great answer. Thx.
ronag
,,user32.dll}_NtUserSetTimer@16 doesnt break for me. Ive tried following you instructions:006CD0BD FF 15 4C BA 80 00 call dword ptr [__imp__SetTimer@16 (80BA4Ch)] (8088F8h)],eax step into [__imp__SetTimer@16 (80BA4Ch)] //7E418C2D 90 nop 7E418C2E B8 1E 12 00 00 mov eax,121Eh 7E418C33 BA 00 03 FE 7F mov edx,7FFE0300h 7E418C38 FF 12 call dword ptr [edx] 7E418C3A C2 10 00 ret 10h //7E418C3D 90 nop Dont get any label for the function.
ronag
It seems i have no debug symbols in my dissambly
ronag
Yeah, go to the first link about public symbols. Add `http://msdl.microsoft.com/download/symbols` to the list at Tools -> Options -> Debugging -> Symbols. You may want to check the "only load manually" box to prevent VS from running really slow all the time. Then, just right click on user32.dll (or whatever) in the modules window and pick "Load Symbols".
jeffamaphone
success... thank you!
ronag
my next question then becomes how I can see the threads memory stack? In order too see what parameters the function was called with.
ronag
That's a much more involved answer. Best to ask a new question.
jeffamaphone
+2  A: 

Here's a walkthrough, with screenshots, for VS2005. Note that for VS2008+ you don't need to input decorated function names (perhaps that's the reason the previous description didn't work out directly? What's your platform/IDE ?).

[Edit:] You definitely need public MS symbols to be able to locate Win32 API in binaries. The shortest route there is go to Tools/Options/Debugging/Symbols, then paste 'http://msdl.microsoft.com/download/symbols' into 'pdb locations'. It is highly recommended - but not necessary - to set a local cache for downloaded pdb's (first pdb loads can be a few minutes), and for your needs you should probably uncheck 'Search the above locations only when symbols are loaded manually'. There'd be some startup delay as all symbols are loaded, but you won't have to chase down user32.dll (or whatever dll holds the function you wish to break at) and load its pdb manually.

Ofek Shilon
Windows XP, VS2010 Pro
ronag
Then you can try either {,,user32.dll}NtUserSetTimer or {,,user32.dll}SetTimer .
Ofek Shilon
still no success
ronag
is "Use the Microsoft Symbol Server to obtain debug symbol files" required to accomplish this?
ronag
Yeah, I was using VS2005. I just installed 2010 and it is much nicer all around.
jeffamaphone