When I calling the
BOOL __stdcall WinUsb_WritePipe( In WINUSB_INTERFACE_HANDLE InterfaceHandle, In UCHAR PipeID, In PUCHAR Buffer, In ULONG BufferLength, Out_opt PULONG LengthTransferred, In_opt LPOVERLAPPED Overlapped
);
from the WinDbg X64 calling conventions:
The first four integer or pointer parameters are passed in the rcx,rdx, r8, and r9 registers.
Because I known the Buffer pointer value is: 00000000`038830b8
and BufferLength is 0x300040.
Why I have to setup the breakpoint for WinUsb_WritePipe.
Because when I prepare a data buffer then transfer by WinUSB by call user mode winusb api.
At device side, I sometimes found, the previous 1KB data is lost.
Which means, device receive the data start from the 2KB offset of the original data.
So I set this breakpoint to check if the caller of WinUsb_WritePipe give a wrong buffer pointer.
Or if this is USB3.0 host hardware issue.
Because I test with Intel, Fresco host.
They all use the Win8.1 USB3 stack.
Intel host have not see this issue, but Fresco host have.
Can any one give more tech tips on debug this issue?
Because every time check the buffer pointer from src to WinUsb_WritePipe, is a lit bit waste time.
On Thu, Jan 8, 2015 at 6:03 AM, wrote: > My target PC is Win8.1 9600 x64 system. > > When I calling the > BOOL __stdcall WinUsb_WritePipe( > In WINUSB_INTERFACE_HANDLE InterfaceHandle, > In UCHAR PipeID, > In PUCHAR Buffer, > In ULONG BufferLength, > Out_opt PULONG LengthTransferred, > In_opt LPOVERLAPPED Overlapped > ); > > from the WinDbg X64 calling conventions: > The first four integer or pointer parameters are passed in the rcx,rdx, r8, and r9 registers. > > Because I known the Buffer pointer value is: 00000000038830b8<br>> and BufferLength is 0x300040.<br>><br>> But from the windbg<br>> 10 000000000377f6b0 0000000000cc45d6 : 0000000000ef0200 000000000377f702 0000000000ef2ec0 00000000038830b8 : WinUsb_7ffb16570000!WinUsb_WritePipe+0x10d<br>> 11 000000000377f730 0000000000cc4c1f : 0000000000000000 0000000303000400 0000c299caf3775a 0000000000ef2ec0 : xxmgr+0x145d6<br>> 12 000000000377f7f0 0000000000cd0e45 : 00000000026bb4d0 0000000000000000 0000000000000001 0000000000000000 : xxmgr+0x14c1f<br>> 13 000000000377f850 0000000000cce23d : 0000000000ef14c0 000000000377f919 0000000000020d00 000000000038a0cc : xxmgr+0x20e45<br>> 14 000000000377f890 0000000000cd28c7 : 0000000000000300 0000000000000020 0000000000000004 00000000026bb398 : xxmgr+0x1e23d<br>> 15 000000000377f980 0000000000ccf42f : 0000000000000000 0000000000ef2dd0 0000000000000000 0000000000ef14c0 : xxmgr+0x228c7<br>> 16 000000000377f9e0 0000000000ccc72b : 00000000026bbc80 0000000000000000 0000000000000000 0000000000000000 : xxmgr+0x1f42f<br>> 17 000000000377fa40 0000000000cc2744 : 0000000000000000 0000000000000000 0000000000000000 0000000000000000 : xxmgr+0x1c72b<br>> 18 000000000377fa80 00007ffb1cef16ad : 0000000000000000 0000000000000000 0000000000000000 0000000000000000 : xxmgr+0x12744<br>> 19 000000000377fac0 00007ffb1ecb4409 : 0000000000000000 0000000000000000 0000000000000000 0000000000000000 : KERNEL32!BaseThreadInitThunk+0xd<br>> 1a 000000000377faf0 0000000000000000 : 0000000000000000 0000000000000000 0000000000000000 0000000000000000 : ntdll!RtlUserThreadStart+0x1d<br>><br>><br>><br>> 3: kd> .frame /r 0x10<br>> 10 000000000377f6b0 0000000000cc45d6 WinUsb_7ffb16570000!WinUsb_WritePipe+0x10d<br>> rax=0000000000000000 rbx=000000000038dc30 rcx=ffffe0019085fe60<br>> rdx=ffffe001908bdf84 rsi=0000000000000000 rdi=0000000000ef3110<br>> rip=00007ffb16572cbd rsp=000000000377f6b0 rbp=000000000377f7b0<br>> r8=00001ffe6ca109a8 r9=ffffd000234c6420 r10=000000000000001c<br>> r11=ffffe001908bd080 r12=0000000000300040 r13=00000000038830b8<br>> r14=000000000377f764 r15=0000000000380580<br>> iopl=0 nv up ei ng nz na po nc<br>> cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00000286<br>> WinUsb_7ffb16570000!WinUsb_WritePipe+0x10d:<br>> 00007ffb16572cbd 8bd8 mov ebx,eax > > r12 and 13 is equal to the parameters(00000000038830b8, 0000000000300040), not what Windbg help said: > rcx, rdx, r8, r9? It’s because registers may be reused for something later on by a given function (and you’re +0x10d in this case). Set a breakpoint at the first instruction in WinUsb_WritePipe and then you should see first 4 arguments in rcx, rdx, r8 and r9.
3: kd> .frame /r 0x10
10 000000000377f6b0 0000000000cc45d6 WinUsb_7ffb16570000!WinUsb_WritePipe+0x10d
rax=0000000000000000 rbx=000000000038dc30 rcx=ffffe0019085fe60
rdx=ffffe001908bdf84 rsi=0000000000000000 rdi=0000000000ef3110
rip=00007ffb16572cbd rsp=000000000377f6b0 rbp=000000000377f7b0
r8=00001ffe6ca109a8 r9=ffffd000234c6420 r10=000000000000001c
r11=ffffe001908bd080 r12=0000000000300040 r13=00000000038830b8
r14=000000000377f764 r15=0000000000380580
iopl=0 nv up ei ng nz na po nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00000286
WinUsb_7ffb16570000!WinUsb_WritePipe+0x10d:
00007ffb`16572cbd 8bd8 mov ebx,eax
r12 and 13 is equal to the parameters(00000000038830b8, 0000000000300040), not what Windbg help said:
rcx, rdx, r8, r9?
Does the x64 calling conventions changed?
No, you have a couple of misunderstandings here.
First, you are 269 bytes into the function at that point. It has
already executed a lot of instructions. The compiler probably moved the
parameters into other registers. Remember, the only time you’re
guaranteed that rcx, rdx, r8 and r9 contain the first four parameters is
at the very first instruction of the function. The compiler is not
obligated to KEEP the parameters there.
Also remember that this is the 16th stack frame. The compiler does not
save the complete register set on every function call. The debugger
tries to make a GUESS at what the registers might have contained, but in
most cases there’s simply no way for it to know what the actual
registers contained. Thus, you’re probably seeing what r12 and r13
contain in the live registers, not as they were in WriteUsb_WritePipe.
–
Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.