空循环,g++ -O2优化
早上有开发反应demo 程序编译加-O2 或-O3 会一直卡在那里。
使用gdb 调试,定位到下面的代码片段上
但还是在没法继续执行。
源代码如下
int HttpClientHandle::getResponsCode(){ while(!m_isPerform); long retcode = 0; CURLcode code = curl_easy_getinfo(m_curl, CURLINFO_RESPONSE_CODE , &retcode); if(code == CURLE_OK){ m_responseCode = retcode; }else{ m_responseCode=-1; } return m_responseCode; }
m_isPerform 已经为true 了,m_isPerform 是多线程共享的变量没有加volatile修饰符。
以下是三种情况的的 int HttpClientHandle::getResponsCode()函数汇编代码。
没做优化 0x00002afc73cc0402 <_ZN16HttpClientHandle14getResponsCodeEv+0>: push %rbp 0x00002afc73cc0403 <_ZN16HttpClientHandle14getResponsCodeEv+1>: mov %rsp,%rbp 0x00002afc73cc0406 <_ZN16HttpClientHandle14getResponsCodeEv+4>: sub $0x20,%rsp 0x00002afc73cc040a <_ZN16HttpClientHandle14getResponsCodeEv+8>: mov %rdi,-0x18(%rbp) 0x00002afc73cc040e <_ZN16HttpClientHandle14getResponsCodeEv+12>: mov -0x18(%rbp),%rax 0x00002afc73cc0412 <_ZN16HttpClientHandle14getResponsCodeEv+16>: movzbl 0x48(%rax),%eax 0x00002afc73cc0416 <_ZN16HttpClientHandle14getResponsCodeEv+20>: test %al,%al 0x00002afc73cc0418 <_ZN16HttpClientHandle14getResponsCodeEv+22>: je 0x2afc73cc040e <_ZN16HttpClientHandle14getResponsCodeEv+12> 0x00002afc73cc041a <_ZN16HttpClientHandle14getResponsCodeEv+24>: movq $0x0,-0x10(%rbp) 0x00002afc73cc0422 <_ZN16HttpClientHandle14getResponsCodeEv+32>: mov -0x18(%rbp),%rax 0x00002afc73cc0426 <_ZN16HttpClientHandle14getResponsCodeEv+36>: mov 0x18(%rax),%rdi 0x00002afc73cc042a <_ZN16HttpClientHandle14getResponsCodeEv+40>: lea -0x10(%rbp),%rdx 0x00002afc73cc042e <_ZN16HttpClientHandle14getResponsCodeEv+44>: mov $0x200002,%esi 0x00002afc73cc0433 <_ZN16HttpClientHandle14getResponsCodeEv+49>: mov $0x0,%eax 0x00002afc73cc0438 <_ZN16HttpClientHandle14getResponsCodeEv+54>: callq 0x2afc73cbcf50 <curl_easy_getinfo@plt> 0x00002afc73cc043d <_ZN16HttpClientHandle14getResponsCodeEv+59>: mov %eax,-0x4(%rbp) 0x00002afc73cc0440 <_ZN16HttpClientHandle14getResponsCodeEv+62>: cmpl $0x0,-0x4(%rbp) 0x00002afc73cc0444 <_ZN16HttpClientHandle14getResponsCodeEv+66>: jne 0x2afc73cc0454 <_ZN16HttpClientHandle14getResponsCodeEv+82> 0x00002afc73cc0446 <_ZN16HttpClientHandle14getResponsCodeEv+68>: mov -0x10(%rbp),%rdx 0x00002afc73cc044a <_ZN16HttpClientHandle14getResponsCodeEv+72>: mov -0x18(%rbp),%rax 0x00002afc73cc044e <_ZN16HttpClientHandle14getResponsCodeEv+76>: mov %rdx,0x40(%rax) 0x00002afc73cc0452 <_ZN16HttpClientHandle14getResponsCodeEv+80>: jmp 0x2afc73cc0460 <_ZN16HttpClientHandle14getResponsCodeEv+94> 0x00002afc73cc0454 <_ZN16HttpClientHandle14getResponsCodeEv+82>: mov -0x18(%rbp),%rax 0x00002afc73cc0458 <_ZN16HttpClientHandle14getResponsCodeEv+86>: movq $0xffffffffffffffff,0x40(%rax) 0x00002afc73cc0460 <_ZN16HttpClientHandle14getResponsCodeEv+94>: mov -0x18(%rbp),%rax 0x00002afc73cc0464 <_ZN16HttpClientHandle14getResponsCodeEv+98>: mov 0x40(%rax),%rax 0x00002afc73cc0468 <_ZN16HttpClientHandle14getResponsCodeEv+102>: leaveq 0x00002afc73cc0469 <_ZN16HttpClientHandle14getResponsCodeEv+103>: retq 加了-O2 (gdb) disass Dump of assembler code for function _ZN16HttpClientHandle14getResponsCodeEv: 0x00002ad0873360e0 <_ZN16HttpClientHandle14getResponsCodeEv+0>: push %rbx 0x00002ad0873360e1 <_ZN16HttpClientHandle14getResponsCodeEv+1>: mov %rdi,%rbx 0x00002ad0873360e4 <_ZN16HttpClientHandle14getResponsCodeEv+4>: sub $0x10,%rsp 0x00002ad0873360e8 <_ZN16HttpClientHandle14getResponsCodeEv+8>: cmpb $0x0,0x48(%rdi) 0x00002ad0873360ec <_ZN16HttpClientHandle14getResponsCodeEv+12>: nopl 0x0(%rax) 0x00002ad0873360f0 <_ZN16HttpClientHandle14getResponsCodeEv+16>: je 0x2ad0873360f0 <_ZN16HttpClientHandle14getResponsCodeEv+16> 0x00002ad0873360f2 <_ZN16HttpClientHandle14getResponsCodeEv+18>: mov 0x18(%rbx),%rdi 0x00002ad0873360f6 <_ZN16HttpClientHandle14getResponsCodeEv+22>: lea 0x8(%rsp),%rdx 0x00002ad0873360fb <_ZN16HttpClientHandle14getResponsCodeEv+27>: xor %eax,%eax 0x00002ad0873360fd <_ZN16HttpClientHandle14getResponsCodeEv+29>: mov $0x200002,%esi 0x00002ad087336102 <_ZN16HttpClientHandle14getResponsCodeEv+34>: movq $0x0,0x8(%rsp) 0x00002ad08733610b <_ZN16HttpClientHandle14getResponsCodeEv+43>: callq 0x2ad0873348a8 <curl_easy_getinfo@plt> 0x00002ad087336110 <_ZN16HttpClientHandle14getResponsCodeEv+48>: test %eax,%eax 0x00002ad087336112 <_ZN16HttpClientHandle14getResponsCodeEv+50>: jne 0x2ad087336127 <_ZN16HttpClientHandle14getResponsCodeEv+71> 0x00002ad087336114 <_ZN16HttpClientHandle14getResponsCodeEv+52>: mov 0x8(%rsp),%rax 0x00002ad087336119 <_ZN16HttpClientHandle14getResponsCodeEv+57>: mov %rax,0x40(%rbx) 0x00002ad08733611d <_ZN16HttpClientHandle14getResponsCodeEv+61>: mov 0x40(%rbx),%rax 0x00002ad087336121 <_ZN16HttpClientHandle14getResponsCodeEv+65>: add $0x10,%rsp 0x00002ad087336125 <_ZN16HttpClientHandle14getResponsCodeEv+69>: pop %rbx 0x00002ad087336126 <_ZN16HttpClientHandle14getResponsCodeEv+70>: retq 0x00002ad087336127 <_ZN16HttpClientHandle14getResponsCodeEv+71>: movq $0xffffffffffffffff,0x40(%rbx) 0x00002ad08733612f <_ZN16HttpClientHandle14getResponsCodeEv+79>: mov 0x40(%rbx),%rax 0x00002ad087336133 <_ZN16HttpClientHandle14getResponsCodeEv+83>: add $0x10,%rsp 0x00002ad087336137 <_ZN16HttpClientHandle14getResponsCodeEv+87>: pop %rbx 0x00002ad087336138 <_ZN16HttpClientHandle14getResponsCodeEv+88>: retq -O3 (gdb) disas Dump of assembler code for function _ZN16HttpClientHandle14getResponsCodeEv: 0x00002b28741bd100 <_ZN16HttpClientHandle14getResponsCodeEv+0>: push %rbx 0x00002b28741bd101 <_ZN16HttpClientHandle14getResponsCodeEv+1>: mov %rdi,%rbx 0x00002b28741bd104 <_ZN16HttpClientHandle14getResponsCodeEv+4>: sub $0x10,%rsp 0x00002b28741bd108 <_ZN16HttpClientHandle14getResponsCodeEv+8>: cmpb $0x0,0x48(%rdi) 0x00002b28741bd10c <_ZN16HttpClientHandle14getResponsCodeEv+12>: je 0x2b28741bd152 <_ZN16HttpClientHandle14getResponsCodeEv+82> 0x00002b28741bd10e <_ZN16HttpClientHandle14getResponsCodeEv+14>: mov 0x18(%rdi),%rdi 0x00002b28741bd112 <_ZN16HttpClientHandle14getResponsCodeEv+18>: lea 0x8(%rsp),%rdx 0x00002b28741bd117 <_ZN16HttpClientHandle14getResponsCodeEv+23>: xor %eax,%eax 0x00002b28741bd119 <_ZN16HttpClientHandle14getResponsCodeEv+25>: mov $0x200002,%esi 0x00002b28741bd11e <_ZN16HttpClientHandle14getResponsCodeEv+30>: movq $0x0,0x8(%rsp) 0x00002b28741bd127 <_ZN16HttpClientHandle14getResponsCodeEv+39>: callq 0x2b28741bb8a8 <curl_easy_getinfo@plt> 0x00002b28741bd12c <_ZN16HttpClientHandle14getResponsCodeEv+44>: test %eax,%eax 0x00002b28741bd12e <_ZN16HttpClientHandle14getResponsCodeEv+46>: jne 0x2b28741bd140 <_ZN16HttpClientHandle14getResponsCodeEv+64> 0x00002b28741bd130 <_ZN16HttpClientHandle14getResponsCodeEv+48>: mov 0x8(%rsp),%rax 0x00002b28741bd135 <_ZN16HttpClientHandle14getResponsCodeEv+53>: mov %rax,0x40(%rbx) 0x00002b28741bd139 <_ZN16HttpClientHandle14getResponsCodeEv+57>: add $0x10,%rsp 0x00002b28741bd13d <_ZN16HttpClientHandle14getResponsCodeEv+61>: pop %rbx 0x00002b28741bd13e <_ZN16HttpClientHandle14getResponsCodeEv+62>: retq 0x00002b28741bd13f <_ZN16HttpClientHandle14getResponsCodeEv+63>: nop 0x00002b28741bd140 <_ZN16HttpClientHandle14getResponsCodeEv+64>: movq $0xffffffffffffffff,0x40(%rbx) 0x00002b28741bd148 <_ZN16HttpClientHandle14getResponsCodeEv+72>: mov 0x40(%rbx),%rax 0x00002b28741bd14c <_ZN16HttpClientHandle14getResponsCodeEv+76>: add $0x10,%rsp 0x00002b28741bd150 <_ZN16HttpClientHandle14getResponsCodeEv+80>: pop %rbx 0x00002b28741bd151 <_ZN16HttpClientHandle14getResponsCodeEv+81>: retq 0x00002b28741bd152 <_ZN16HttpClientHandle14getResponsCodeEv+82>: jmp 0x2b28741bd152 <_ZN16HttpClientHandle14getResponsCodeEv+82> End of assembler dump.
有关volatile 变量参考 http://zh.wikipedia.org/wiki/Volatile%E5%8F%98%E9%87%8F