Question

I'm using a Visual Studio trace point in a function I don't own (part of Windows' user32.dll), and I want to print out the function's parameters.

If I had the source code for the function I could use the following syntax.

In Function( {arg1}, {arg2} ) called from $CALLER

However, I don't have debug information for user32.dll therefore I can't reference arg1. In the watch window I'm able to see the variables by offsetting from a register (*(int*)(ESP+4)), but I can't figure out how to do this in the print option of the trace point.

When I try the following:

In Function( {*(int*)($ESP+4)}, {*(bool*)($ESP+8)} ) called from $CALLER

I get: In Function( , ) called from OtherFunction

Any ideas if this is possible?

Was it helpful?

Solution

Not certain if this is possible in Visual Studio. At least the documented possibilities for tracepoints seem not to cover what you need.

One alternative solution would be to use WinDbg (includded in Debugging Tools for Windows. With WinDbg you could for instance:

bp kernel32!CreateFileW "du poi(@esp+4); gc"

This command:

  1. Sets a breakpoint on the function you are interested in (bp).
  2. On breakpoint hit executes the part in " ". This prints out the parameter you are interested in and continues debugging. I.e. for the CreateFile example:

du - prints out the unicode string at the address pointed to (poi) by (@esp+4)

gc - command resumes execution from a conditional breakpoint in the same fashion that was used to hit the breakpoint (stepping, tracing, or freely executing).

I hope this helps.

EDIT: Following Assaf Levy's now deleted reply (I wanted to vote it up because it helped with learning something/gave me the push to try it again in VS :-). Unfortunately he was faster with deleting than I was with voting up.

I managed to get tracing working for CreateFile (filename) in a similar way I did in WinDbg in Visual Studio (For reference I use 2010). What I did:

  1. I chose "Go to disassembly" while in the debugger and went down up to the CreateFileW call. I took the name of the function from there (i.e. _CreateFileW@28).
  2. I went in the breakpoints window, selected New -> Break at function... (Ctrl + B). Entered the name (_CreateFileW@28). I tried the WinDbg way also (kernel32!CreateFileW) but it does not work (not supported?)
  3. Selected "When hit..." on the breakpoint and entered: "CreateFileW FileName: {*((const wchar_t**)(@esp+4))}", Continue Execution was selected.

With my test code now, something in the lines of:

CreateFileW FileName: 0x7efddc00 "c:\Temp\test.out"

is printed out for a CreateFile call.

So in principle it works/should work in VS also. It takes some fiddling but it works.

EDIT2: Also It might help/make things easier if you set up the usage of "Microsoft Symbol Servers". Please see: Use a Symbol Server. It can be made to work also without symbol servers, but you have to adapt step 1 and use an address instead of the symbolic name when you create the breakpoint.

OTHER TIPS

Unless I'm missing something, this works for me:
In foo: ({*(int*)($ESP+4)},{*(int*)($ESP+8)}) called from $CALLER
Gives me exactly the two int's that I passed.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top