Debugging 'Last Error' problems

On a few occasions I have run into problems where some Windows API was returning a 'strange' error code. Here is a technique that works with some APIs:

  1. Go get public symbols for your operating system – add to your symbol path and define a symbol cache directory
  2. Set a breakpoint on SetLastError: to be on the safe side, set the breakpoint on both {,,kernel32}_SetLastError@4 and {,,ntdll}_RtlSetLastWin32Error@4
  3. Assuming that you get a million calls, figure out where the last error is being passed to the set last error functions. For me, this is *(unsigned*)(@esp+4), but your mileage may vary. Once you know where the error code is passed, you can either set a tracepoint, or turn the breakpoint into a conditional breakpoint (see more information bellow).
  4. Run your scenario and find your bug

To set a tracepoint:

  1. Right click on the breakpoint, and click 'When Hit...'
  2. Check 'print a message'
  3. Set the message to '{*(unsigned*)(@esp+4)} -- $CALLSTACK', or whatever information you want
  4. Click 'okay'

To set a conditional breakpoint:

  1. Right click on the breakpoint, and click 'Condition...'
  2. Set your condition to be '*(unsigned*)(@esp+4)==1234' where 1234 is the strange error code that you are seeing