- 论坛徽章:
- 11
|
本帖最后由 zylthinking 于 2014-08-29 15:11 编辑
Visual studio 下发现一个函数一旦优化, 就出现 crash, 最终证明发生在 myref_get 中:- static inline void* handle_get_with(my_handle* handle, int detach)
- {
- printf("handle->statck = %p\n", &handle->stack);
- int n = myref_get(&handle->stack);
- int b = __sync_bool_compare_and_swap((void **) &handle->detached, (void *) 0, (void *) detach);
- if (!b) {
- handle_put(handle);
- return NULL;
- }
- void* ptr = handle->ptr;
- assert(n > 1 && ptr != NULL);
- return ptr;
- }
复制代码 其中:
- static inline int myref_get(myref_t* refp)
- {
- return (int) __sync_add_and_fetch(&refp->val, 1);
- }
复制代码 而后 __sync_add_and_fetch 实现如下, 就是 gcc 产生的代码的移植,
- static int __sync_add_and_fetch(void* lkp, int val)
- {
- __asm {
- mov ecx, val
- mov edx, dword ptr [lkp]
- mov eax, ecx
- lock xadd dword ptr [edx], eax
- add eax, ecx
- leave
- ret
- };
- return 0;
- }
复制代码 百思不得其解, 最终没办法直接反汇编调试, 发现 VC 给我把 myref_get 给 inline 了, 可是。。。。可是。。。。。, 白痴的是, 它把那段内嵌汇编原样拷贝了进去, 天知道我那个是为了从 __sync_add_and_fetch 返回用的。。。。。。。。, 这一搞直接是程序跑飞, 我真服劲了。。。。。。。
static inline void* handle_get_with(my_handle* handle, int detach)
{
10004380 push ecx
10004381 push esi
10004382 push edi
10004383 mov esi,eax
printf("handle->statck = %p\n", &handle->stack);
10004385 lea edi,[esi+4]
10004388 push edi
10004389 push offset string "handle->statck = %p\n" (1004FC14h)
1000438E call printf (1003960Ah)
10004393 add esp,8
int n = myref_get(&handle->stack);
10004396 mov dword ptr [esp+8],edi
1000439A mov ecx,1
1000439F mov edx,dword ptr [esp+8]
100043A3 mov eax,ecx
100043A5 lock xadd dword ptr [edx],eax
100043A9 add eax,ecx
100043AB leave
100043AC ret
int b = __sync_bool_compare_and_swap((void **) &handle->detached, (void *) 0, (void *) detach);
100043AD mov eax,dword ptr [esp+10h]
100043B1 push 0
100043B3 push eax
100043B4 lea ecx,[esi+8]
100043B7 push ecx
100043B8 call dword ptr [__imp__InterlockedCompareExchange@12 (1004E054h)]
100043BE test eax,eax
if (!b) {
100043C0 je handle_get_with+7Ch (100043FCh)
handle_put(handle);
100043C2 mov dword ptr [esp+8],edi
100043C6 mov ecx,0FFFFFFFFh
100043CB mov edx,dword ptr [esp+8]
100043CF mov eax,ecx
100043D1 lock xadd dword ptr [edx],eax
100043D5 add eax,ecx
100043D7 leave
100043D8 ret
100043D9 push 0
100043DB lea edx,[esi+0Ch]
100043DE push edx
100043DF call dword ptr [__imp__InterlockedExchange@8 (1004E020h)]
100043E5 mov esi,dword ptr [esi+10h]
100043E8 test esi,esi
100043EA je handle_get_with+76h (100043F6h)
100043EC test eax,eax
100043EE je handle_get_with+76h (100043F6h)
100043F0 push eax
100043F1 call esi
100043F3 add esp,4
100043F6 pop edi
return NULL;
100043F7 xor eax,eax
100043F9 pop esi
} |
|