非常奇怪的段错误调用WinUsb_GetOverlappedResult [英] Very strange segfault calling WinUsb_GetOverlappedResult
问题描述
void GetResult(WINUSB_INTERFACE_HANDLE InterfaceHandle,LPOVERLAPPED lpOverlapped)
{
DWORD numBytes = 0;
WinUsb_GetOverlappedResult(
InterfaceHandle,
lpOverlapped,
& numBytes,
TRUE
);
return;
uint8_t堆栈[64];
}
WinUsb_GetOverlappedResult
是一个 __ stdcall
函数声明如下:
WINBOOL WINAPI WinUsb_GetOverlappedResult(WINUSB_INTERFACE_HANDLE InterfaceHandle, LPOVERLAPPED lpOverlapped,LPDWORD lpNumberOfBytesTransferred,WINBOOL bWait);
使用GCC 5.3.0(MinGW)在调试模式下编译它一切正常。 (我无法用VC ++进行编译,因为我使用GCC扩展。)
然而如果我将它更改为 stack [80]
然后它segfaults !!
这里是每种情况下的反汇编。 64(不会崩溃): 和80(崩溃):
pre $ 函数GetResult的汇编代码转储(void *,_OVERLAPPED *):
88 {
0x00408523< + 0> ;: push%ebp
0x00408524< + 1> ;: mov%esp,%ebp
0x00408526< + 3>:sub $ 0x68, esp
89 DWORD numBytes = 0;
0x00408529< + 6> ;: movl $ 0x0,-0xc(%ebp)
90 WinUsb_GetOverlappedResult(
91 InterfaceHandle,
92 lpOverlapped,
93字节,
94真实
95);
=> 0x00408530< + 13> ;: movl $ 0x1,0xc(%esp)
0x00408538< + 21> ;: lea -0xc(%ebp),%eax
0x0040853b< + 24> ;: mov% eax,0x8(%esp)
0x0040853f< + 28> ;: mov 0xc(%ebp),%eax
0x00408542< + 31> ;: mov%eax,0x4(%esp)
0x00408546< + 35>:mov 0x8(%ebp),%eax
0x00408549< + 38> ;: mov%eax,(%esp)
0x0040854c< + 41> ;: call 0x409d58< ; WinUsb_GetOverlappedResult @ 16取代;
0x00408551< + 46>:sub $ 0x10,%esp
96 return;
0x00408554< + 49> ;: nop
97
98 uint8_t堆栈[64]; b
$ b $
$ b
函数GetResult的汇编代码转储(void * ,_OVERLAPPED *):
的作用是添加行
88 {
0x00408523< + 0> ;: push%ebp
0x00408524< + 1> ;: mov%esp,%ebp
0x00408526< + 3>:sub $ 0x78,%esp
89 DWORD numBytes = 0;
0x00408529< + 6> ;: movl $ 0x0,-0xc(%ebp)
90 WinUsb_GetOverlappedResult(
91 InterfaceHandle,
92 lpOverlapped,
93字节,
94真实
95);
=> 0x00408530< + 13> ;: movl $ 0x1,0xc(%esp)
0x00408538< + 21> ;: lea -0xc(%ebp),%eax
0x0040853b< + 24> ;: mov% eax,0x8(%esp)
0x0040853f< + 28> ;: mov 0xc(%ebp),%eax
0x00408542< + 31> ;: mov%eax,0x4(%esp)
0x00408546< + 35>:mov 0x8(%ebp),%eax
0x00408549< + 38> ;: mov%eax,(%esp)
0x0040854c< + 41> ;: call 0x409d58< ; WinUsb_GetOverlappedResult @ 16取代;
0x00408551< + 46>:sub $ 0x10,%esp
96 return;
0x00408554< + 49> ;: nop
97
98 uint8_t stack [80]; b
$ b $
$ b sub $ 0x10,%esp
我想这是取消 ret $ 0x10
在函数中。
在任何情况下,这些看起来都非常相似我不知道它为什么会崩溃。我甚至没有100%确定在哪里它崩溃了(GDB是无用的),但它在WinUsb函数调用的某个地方。
很难调试,因为如果我运行带有任何断点的调试器,它不会崩溃。我怀疑它可能与时间有关 -
我也可以通过一些额外的 Sleep(100)
s来防止崩溃。一旦它看起来在 PerfIncrementULongLongCounterValue()
中崩溃,但是谁知道...
有谁知道为什么会这样可能会发生?
编辑
WinUsb_GetOverlappedResult()
只是根据它的程序集直接调用到 GetOverlappedResult()
,所以我用这个替换了调用。现在你需要 stack [96]
来引发崩溃,但是当它至少告诉我真正的崩溃在哪里(我认为)!
以下是对 GetOverlappedResult()
的反汇编。它在指定位置崩溃,因为 ebp
为0。
0x76feaba0 8b ff mov %edi,%edi
0x76feaba2< + 0x0002> 55推%ebp
0x76feaba3< + 0x0003> 8b ec mov%esp,%ebp
0x76feaba5< + 0x0005> 83 ec 0c sub $ 0xc,%esp
0x76feaba8< + 0x0008> a1 94 4b 09 77 mov 0x77094b94,%eax
0x76feabad< + 0x000d> 33 c5 xor%ebp,%eax
0x76feabaf< + 0x000f> 89 45 fc mov%eax,-0x4(%ebp)
0x76feabb2< + 0x0012> 83 7d 14 00 cmpl $ 0x0,0x14(%ebp)
0x76feabb6< + 0x0016> 53 push%ebx
0x76feabb7< + 0x0017> 56%%esi
0x76feabb8< + 0x0018> 57%%edi
0x76feabb9< + 0x0019> 0f 84 b3 00 00 00 je 0x76feac72< KERNELBASE!GetOverlappedResult + 210>
0x76feabbf< + 0x001f> 83 cf ff或$ 0xffffffff,%edi
0x76feabc2< + 0x0022> 8b 5d 08 mov 0x8(%ebp),%ebx
0x76feabc5< + 0x0025> 83 cb 01或$ 0x1,%ebx
0x76feabc8< + 0x0028> 85 ff test%edi,%edi
0x76feabca< + 0x002a> 0f 84 a9 00 00 00 je 0x76feac79< KERNELBASE!GetOverlappedResult + 217>
0x76feabd0< + 0x0030> b8 01 00 00 00 mov $ 0x1,%eax
0x76feabd5< + 0x0035> c7 45 f4 01 00 00 00 movl $ 0x1,-0xc(%ebp)
0x76feabdc< + 0x003c> 89 45 f8 mov%eax,-0x8(%ebp)
0x76feabdf< + 0x003f> 84 d8测试%bl,%al
0x76feabe1< + 0x0041> 0f 84 5e f3 03 00 je 0x77029f45< KERNELBASE!GetCurrentProcess + 43221>
0x76feabe7< + 0x0047> 6a 00推$ 0x0
0x76feabe9< + 0x0049> 68 dc 10 f2 76推$ 0x76f210dc
0x76feabee< + 0x004e> 50推%eax
0x76feabef< + 0x004f> 68 ab ab ab ab push $ 0xabababab
0x76feabf4< + 0x0054> ff 15 68 80 09 77 call * 0x77098068
0x76feabfa< + 0x005a> 8b f0 mov%eax,%esi
0x76feabfc< + 0x005c> 85 f6 test%esi,%esi
0x76feabfe< + 0x005e> 74 0e je 0x76feac0e< KERNELBASE!GetOverlappedResult + 110>
0x76feac00< + 0x0060> 8d 45 f4 lea -0xc(%ebp),%eax
0x76feac03< + 0x0063> 8b ce mov%esi,%ecx
0x76feac05< + 0x0065> 50%%eax
0x76feac06< + 0x0066> ff 15 5c 8a 09 77 call * 0x77098a5c
0x76feac0c< + 0x006c> ff d6 call *%esi
0x76feac0e< + 0x006e> 33 c0 xor%eax,%eax
0x76feac10< + 0x0070> 83 e3 fe和$ 0xfffffffe,%ebx
0x76feac13< + 0x0073> 89 45 f8 mov%eax,-0x8(%ebp)
0x76feac16< + 0x0076> 39 45 f4 cmp%eax,-0xc(%ebp)
0x76feac19< + 0x0079> 0f 85 26 f3 03 00 jne 0x77029f45< KERNELBASE!GetCurrentProcess + 43221>
0x76feac1f< + 0x007f> 8b 75 0c mov 0xc(%ebp),%esi
0x76feac22< + 0x0082> 81 3e 03 01 00 00 cmpl $ 0x103,(%esi)
0x76feac28< + 0x0088> 74 26 je 0x76feac50< KERNELBASE!GetOverlappedResult + 176>
崩溃:
0x76feac2a< + 0x008a> 8b 45 10 mov 0x10(%ebp),%eax
0x76feac2d< + 0x008d> 8b 4e 04 mov 0x4(%esi),%ecx
0x76feac30< + 0x0090> 89%mov%ecx,(%eax)
0x76feac32< + 0x0092> 8b 0e mov(%esi),%ecx
0x76feac34< + 0x0094> 85 c9 test%ecx,%ecx
0x76feac36< + 0x0096> 78 31 js 0x76feac69< KERNELBASE!GetOverlappedResult + 201>
0x76feac38< + 0x0098> b8 01 00 00 00 mov $ 0x1,%eax
0x76feac3d< + 0x009d> 8b 4d fc mov -0x4(%ebp),%ecx
0x76feac40< + 0x00a0> 5f pop%edi
0x76feac41< + 0x00a1> 5e pop%esi
0x76feac42< + 0x00a2> 33 cd xor%ebp,%ecx
0x76feac44< + 0x00a4> 5b pop%ebx
0x76feac45< + 0x00a5> e8 0b f0 02 00 call 0x77019c55< PerfIncrementULongLongCounterValue + 197>
0x76feac4a< + 0x00aa> 8b e5 mov%ebp,%esp
0x76feac4c< + 0x00ac> 5d pop%ebp
0x76feac4d< + 0x00ad> c2 10 00 ret $ 0x10
0x76feac50< + 0x00b0> 8b 46 10 mov 0x10(%esi),%eax
0x76feac53< + 0x00b3> 85 c0 test%eax,%eax
0x76feac55< + 0x00b5> 74 46 je 0x76feac9d< KERNELBASE!GetOverlappedResult + 253>
0x76feac57< + 0x00b7> 6a 00推$ 0x0
0x76feac59< + 0x00b9> 57推%edi
0x76feac5a< + 0x00ba> 50%%eax
0x76feac5b< + 0x00bb> e8 50 01 00 00 call 0x76feadb0< WaitForSingleObjectEx>
0x76feac60< + 0x00c0> 85 c0 test%eax,%eax
0x76feac62< + 0x00c2> 74 c6 je 0x76feac2a< KERNELBASE!GetOverlappedResult + 138>
0x76feac64< + 0x00c4> e9 fb f2 03 00 jmp 0x77029f64< KERNELBASE!GetCurrentProcess + 43252>
0x76feac69< + 0x00c9> e8 d2 f1 ff ff call 0x76fe9e40< OpenThreadToken + 64>
0x76feac6e< + 0x00ce> 33 c0 xor%eax,%eax
0x76feac70< + 0x00d0> eb cb jmp 0x76feac3d< KERNELBASE!GetOverlappedResult + 157>
0x76feac72< + 0x00d2> 33 ff xor%edi,%edi
0x76feac74< + 0x00d4> e9 49 ff ff ff jmp 0x76feabc2< KERNELBASE!GetOverlappedResult + 34>
0x76feac79< + 0x00d9> 8b 75 0c mov 0xc(%ebp),%esi
0x76feac7c< + 0x00dc> 81 3e 03 01 00 00 cmpl $ 0x103,(%esi)
0x76feac82< + 0x00e2> 74 0a je 0x76feac8e< KERNELBASE!GetOverlappedResult + 238>
0x76feac84< + 0x00e4> 33 c9 xor%ecx,%ecx
0x76feac86< + 0x00e6> 8d 45 f8 lea -0x8(%ebp),%eax
0x76feac89< + 0x00e9> f0 09 08锁定或%ecx,(%eax)
0x76feac8c< + 0x00ec> eb 9c jmp 0x76feac2a< KERNELBASE!GetOverlappedResult + 138>
0x76feac8e< + 0x00ee> 68 e4 03 00 00推送$ 0x3e4
0x76feac93< + 0x00f3> ff 15 c4 80 09 77 call * 0x770980c4
0x76feac99< + 0x00f9> 33 c0 xor%eax,%eax
0x76feac9b< + 0x00fb> eb a0 jmp 0x76feac3d< KERNELBASE!GetOverlappedResult + 157>
0x76feac9d< + 0x00fd> 8b c3 mov%ebx,%eax
0x76feac9f< + 0x00ff> eb b6 jmp 0x76feac57< KERNELBASE!GetOverlappedResult + 183>
0x76feaca1< + 0x0101> cc int3
0x76feaca2< + 0x0102> cc int3
0x76feaca3< + 0x0103> cc int3
0x76feaca4< + 0x0104> cc int3
0x76feaca5< + 0x0105> cc int3
0x76feaca6< + 0x0106> cc int3
0x76feaca7< + 0x0107> cc int3
0x76feaca8< + 0x0108> cc int3
0x76feaca9< + 0x0109> cc int3
0x76feacaa< + 0x010a> cc int3
0x76feacab< + 0x010b> cc int3
0x76feacac< + 0x010c> cc int3
0x76feacad< + 0x010d> cc int3
0x76feacae< + 0x010e> cc int3
0x76feacaf< + 0x010f> cc int3
>我明白了这一点。也许。我改变的是我不再移动我的 OVERLAPPED
结构。我只能假设WinUsb保留了一个指针,当你开始写入时,它会传递给你的 OVERLAPPED
。
在任何地方我都可以找到 OVERLAPPED
但改变我的代码,以便 OVERLAPPED
动态分配一次,永不移动似乎停止崩溃。
不幸的是我从来没有找到一个好方法来调试它。最好的方法是可逆调试器,但它们似乎不适用于Windows。
I have this code:
void GetResult(WINUSB_INTERFACE_HANDLE InterfaceHandle, LPOVERLAPPED lpOverlapped)
{
DWORD numBytes = 0;
WinUsb_GetOverlappedResult(
InterfaceHandle,
lpOverlapped,
&numBytes,
TRUE
);
return;
uint8_t stack[64];
}
WinUsb_GetOverlappedResult
is a __stdcall
function declared as follows:
WINBOOL WINAPI WinUsb_GetOverlappedResult (WINUSB_INTERFACE_HANDLE InterfaceHandle, LPOVERLAPPED lpOverlapped, LPDWORD lpNumberOfBytesTransferred, WINBOOL bWait);
Compiling in debug mode with GCC 5.3.0 (MinGW) it all works fine. (I can't compile with VC++ because I'm using GCC extensions.)
However if I change it to stack[80]
then it segfaults!!
Here is the disassembly in each case. 64 (doesn't crash):
Dump of assembler code for function GetResult(void*, _OVERLAPPED*):
88 {
0x00408523 <+0>: push %ebp
0x00408524 <+1>: mov %esp,%ebp
0x00408526 <+3>: sub $0x68,%esp
89 DWORD numBytes = 0;
0x00408529 <+6>: movl $0x0,-0xc(%ebp)
90 WinUsb_GetOverlappedResult(
91 InterfaceHandle,
92 lpOverlapped,
93 &numBytes,
94 TRUE
95 );
=> 0x00408530 <+13>: movl $0x1,0xc(%esp)
0x00408538 <+21>: lea -0xc(%ebp),%eax
0x0040853b <+24>: mov %eax,0x8(%esp)
0x0040853f <+28>: mov 0xc(%ebp),%eax
0x00408542 <+31>: mov %eax,0x4(%esp)
0x00408546 <+35>: mov 0x8(%ebp),%eax
0x00408549 <+38>: mov %eax,(%esp)
0x0040854c <+41>: call 0x409d58 <WinUsb_GetOverlappedResult@16>
0x00408551 <+46>: sub $0x10,%esp
96 return;
0x00408554 <+49>: nop
97
98 uint8_t stack[64];
99 }
0x00408555 <+50>: leave
0x00408556 <+51>: ret
And 80 (does crash):
Dump of assembler code for function GetResult(void*, _OVERLAPPED*):
88 {
0x00408523 <+0>: push %ebp
0x00408524 <+1>: mov %esp,%ebp
0x00408526 <+3>: sub $0x78,%esp
89 DWORD numBytes = 0;
0x00408529 <+6>: movl $0x0,-0xc(%ebp)
90 WinUsb_GetOverlappedResult(
91 InterfaceHandle,
92 lpOverlapped,
93 &numBytes,
94 TRUE
95 );
=> 0x00408530 <+13>: movl $0x1,0xc(%esp)
0x00408538 <+21>: lea -0xc(%ebp),%eax
0x0040853b <+24>: mov %eax,0x8(%esp)
0x0040853f <+28>: mov 0xc(%ebp),%eax
0x00408542 <+31>: mov %eax,0x4(%esp)
0x00408546 <+35>: mov 0x8(%ebp),%eax
0x00408549 <+38>: mov %eax,(%esp)
0x0040854c <+41>: call 0x409d58 <WinUsb_GetOverlappedResult@16>
0x00408551 <+46>: sub $0x10,%esp
96 return;
0x00408554 <+49>: nop
97
98 uint8_t stack[80];
99 }
0x00408555 <+50>: leave
0x00408556 <+51>: ret
The effect of the __stdcall
is to add the line sub $0x10,%esp
which I guess is to cancel out ret $0x10
in the function.
In any case these seem very similar and I have no idea why it is crashing. I'm not even 100% sure where it is crashing (GDB is rather unhelpful) but it is somewhere around WinUsb function call.
It's quite hard to debug because if I run the debugger with any breakpoints set, it doesn't crash. I suspect it may be timing related -
I can also prevent the crash with a few extra Sleep(100)
s. Once it seemed to crash in PerfIncrementULongLongCounterValue()
but who knows...
Does anyone have any clue why this might be happening?
Edit
WinUsb_GetOverlappedResult()
just calls straight through to GetOverlappedResult()
according to its assembly, so I replace the call with that. Now you need stack[96]
to cause the crash, but when it does it at least tells me where the real crash is (I think)!
Here is the disassembly of GetOverlappedResult()
. It crashes where indicated because ebp
is 0.
0x76feaba0 8b ff mov %edi,%edi
0x76feaba2 <+0x0002> 55 push %ebp
0x76feaba3 <+0x0003> 8b ec mov %esp,%ebp
0x76feaba5 <+0x0005> 83 ec 0c sub $0xc,%esp
0x76feaba8 <+0x0008> a1 94 4b 09 77 mov 0x77094b94,%eax
0x76feabad <+0x000d> 33 c5 xor %ebp,%eax
0x76feabaf <+0x000f> 89 45 fc mov %eax,-0x4(%ebp)
0x76feabb2 <+0x0012> 83 7d 14 00 cmpl $0x0,0x14(%ebp)
0x76feabb6 <+0x0016> 53 push %ebx
0x76feabb7 <+0x0017> 56 push %esi
0x76feabb8 <+0x0018> 57 push %edi
0x76feabb9 <+0x0019> 0f 84 b3 00 00 00 je 0x76feac72 <KERNELBASE!GetOverlappedResult+210>
0x76feabbf <+0x001f> 83 cf ff or $0xffffffff,%edi
0x76feabc2 <+0x0022> 8b 5d 08 mov 0x8(%ebp),%ebx
0x76feabc5 <+0x0025> 83 cb 01 or $0x1,%ebx
0x76feabc8 <+0x0028> 85 ff test %edi,%edi
0x76feabca <+0x002a> 0f 84 a9 00 00 00 je 0x76feac79 <KERNELBASE!GetOverlappedResult+217>
0x76feabd0 <+0x0030> b8 01 00 00 00 mov $0x1,%eax
0x76feabd5 <+0x0035> c7 45 f4 01 00 00 00 movl $0x1,-0xc(%ebp)
0x76feabdc <+0x003c> 89 45 f8 mov %eax,-0x8(%ebp)
0x76feabdf <+0x003f> 84 d8 test %bl,%al
0x76feabe1 <+0x0041> 0f 84 5e f3 03 00 je 0x77029f45 <KERNELBASE!GetCurrentProcess+43221>
0x76feabe7 <+0x0047> 6a 00 push $0x0
0x76feabe9 <+0x0049> 68 dc 10 f2 76 push $0x76f210dc
0x76feabee <+0x004e> 50 push %eax
0x76feabef <+0x004f> 68 ab ab ab ab push $0xabababab
0x76feabf4 <+0x0054> ff 15 68 80 09 77 call *0x77098068
0x76feabfa <+0x005a> 8b f0 mov %eax,%esi
0x76feabfc <+0x005c> 85 f6 test %esi,%esi
0x76feabfe <+0x005e> 74 0e je 0x76feac0e <KERNELBASE!GetOverlappedResult+110>
0x76feac00 <+0x0060> 8d 45 f4 lea -0xc(%ebp),%eax
0x76feac03 <+0x0063> 8b ce mov %esi,%ecx
0x76feac05 <+0x0065> 50 push %eax
0x76feac06 <+0x0066> ff 15 5c 8a 09 77 call *0x77098a5c
0x76feac0c <+0x006c> ff d6 call *%esi
0x76feac0e <+0x006e> 33 c0 xor %eax,%eax
0x76feac10 <+0x0070> 83 e3 fe and $0xfffffffe,%ebx
0x76feac13 <+0x0073> 89 45 f8 mov %eax,-0x8(%ebp)
0x76feac16 <+0x0076> 39 45 f4 cmp %eax,-0xc(%ebp)
0x76feac19 <+0x0079> 0f 85 26 f3 03 00 jne 0x77029f45 <KERNELBASE!GetCurrentProcess+43221>
0x76feac1f <+0x007f> 8b 75 0c mov 0xc(%ebp),%esi
0x76feac22 <+0x0082> 81 3e 03 01 00 00 cmpl $0x103,(%esi)
0x76feac28 <+0x0088> 74 26 je 0x76feac50 <KERNELBASE!GetOverlappedResult+176>
Crash:
0x76feac2a <+0x008a> 8b 45 10 mov 0x10(%ebp),%eax
0x76feac2d <+0x008d> 8b 4e 04 mov 0x4(%esi),%ecx
0x76feac30 <+0x0090> 89 08 mov %ecx,(%eax)
0x76feac32 <+0x0092> 8b 0e mov (%esi),%ecx
0x76feac34 <+0x0094> 85 c9 test %ecx,%ecx
0x76feac36 <+0x0096> 78 31 js 0x76feac69 <KERNELBASE!GetOverlappedResult+201>
0x76feac38 <+0x0098> b8 01 00 00 00 mov $0x1,%eax
0x76feac3d <+0x009d> 8b 4d fc mov -0x4(%ebp),%ecx
0x76feac40 <+0x00a0> 5f pop %edi
0x76feac41 <+0x00a1> 5e pop %esi
0x76feac42 <+0x00a2> 33 cd xor %ebp,%ecx
0x76feac44 <+0x00a4> 5b pop %ebx
0x76feac45 <+0x00a5> e8 0b f0 02 00 call 0x77019c55 <PerfIncrementULongLongCounterValue+197>
0x76feac4a <+0x00aa> 8b e5 mov %ebp,%esp
0x76feac4c <+0x00ac> 5d pop %ebp
0x76feac4d <+0x00ad> c2 10 00 ret $0x10
0x76feac50 <+0x00b0> 8b 46 10 mov 0x10(%esi),%eax
0x76feac53 <+0x00b3> 85 c0 test %eax,%eax
0x76feac55 <+0x00b5> 74 46 je 0x76feac9d <KERNELBASE!GetOverlappedResult+253>
0x76feac57 <+0x00b7> 6a 00 push $0x0
0x76feac59 <+0x00b9> 57 push %edi
0x76feac5a <+0x00ba> 50 push %eax
0x76feac5b <+0x00bb> e8 50 01 00 00 call 0x76feadb0 <WaitForSingleObjectEx>
0x76feac60 <+0x00c0> 85 c0 test %eax,%eax
0x76feac62 <+0x00c2> 74 c6 je 0x76feac2a <KERNELBASE!GetOverlappedResult+138>
0x76feac64 <+0x00c4> e9 fb f2 03 00 jmp 0x77029f64 <KERNELBASE!GetCurrentProcess+43252>
0x76feac69 <+0x00c9> e8 d2 f1 ff ff call 0x76fe9e40 <OpenThreadToken+64>
0x76feac6e <+0x00ce> 33 c0 xor %eax,%eax
0x76feac70 <+0x00d0> eb cb jmp 0x76feac3d <KERNELBASE!GetOverlappedResult+157>
0x76feac72 <+0x00d2> 33 ff xor %edi,%edi
0x76feac74 <+0x00d4> e9 49 ff ff ff jmp 0x76feabc2 <KERNELBASE!GetOverlappedResult+34>
0x76feac79 <+0x00d9> 8b 75 0c mov 0xc(%ebp),%esi
0x76feac7c <+0x00dc> 81 3e 03 01 00 00 cmpl $0x103,(%esi)
0x76feac82 <+0x00e2> 74 0a je 0x76feac8e <KERNELBASE!GetOverlappedResult+238>
0x76feac84 <+0x00e4> 33 c9 xor %ecx,%ecx
0x76feac86 <+0x00e6> 8d 45 f8 lea -0x8(%ebp),%eax
0x76feac89 <+0x00e9> f0 09 08 lock or %ecx,(%eax)
0x76feac8c <+0x00ec> eb 9c jmp 0x76feac2a <KERNELBASE!GetOverlappedResult+138>
0x76feac8e <+0x00ee> 68 e4 03 00 00 push $0x3e4
0x76feac93 <+0x00f3> ff 15 c4 80 09 77 call *0x770980c4
0x76feac99 <+0x00f9> 33 c0 xor %eax,%eax
0x76feac9b <+0x00fb> eb a0 jmp 0x76feac3d <KERNELBASE!GetOverlappedResult+157>
0x76feac9d <+0x00fd> 8b c3 mov %ebx,%eax
0x76feac9f <+0x00ff> eb b6 jmp 0x76feac57 <KERNELBASE!GetOverlappedResult+183>
0x76feaca1 <+0x0101> cc int3
0x76feaca2 <+0x0102> cc int3
0x76feaca3 <+0x0103> cc int3
0x76feaca4 <+0x0104> cc int3
0x76feaca5 <+0x0105> cc int3
0x76feaca6 <+0x0106> cc int3
0x76feaca7 <+0x0107> cc int3
0x76feaca8 <+0x0108> cc int3
0x76feaca9 <+0x0109> cc int3
0x76feacaa <+0x010a> cc int3
0x76feacab <+0x010b> cc int3
0x76feacac <+0x010c> cc int3
0x76feacad <+0x010d> cc int3
0x76feacae <+0x010e> cc int3
0x76feacaf <+0x010f> cc int3
Well I think I figured this out. Maybe. The thing I changed is that I don't move my OVERLAPPED
structure any more. I can only assume that WinUsb retains a pointer to the OVERLAPPED
you pass when you start the write. If it moves then presumably things break.
This isn't mentioned anywhere I can find int the documentation for OVERLAPPED
but changing my code so that the OVERLAPPED
is dynamically allocated once and never moved seems to stop the crashes.
Unfortunately I never found a good way to debug it. The best way would be a reversible debugger but they don't seem to exist for Windows.
这篇关于非常奇怪的段错误调用WinUsb_GetOverlappedResult的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!