ATL
데이터베이스 액세스를 사용하는 간단한 클래스가 있습니다. 모든 기능은 헤더 파일에 정의되어 있습니다.디버그 빌드에서 간단한 함수에 대한 Exzessive 스택 사용
문제가있는 기능은 모두 동일합니다. 일부 매크로가 사용 중입니다. 이
void InitBindings()
{
if (sName) // Static global char*
m_sTableName = sName; // Save into member
{ AddCol("Name", some_constant_data... _GetOleDBType(...), ...); };
{ AddCol("Name1", some_other_constant_data_GetOleDBType(...), ...); };
...
}
AddCol
이 구조에 대한 참조를 반환 같이 생성 된 코드는 보이지만, 당신이 보는대로는 무시됩니다.
6 개의 AddCol 호출을 사용하는 함수가있는 어셈블러 코드를 살펴보면 함수에 2176 바이트의 스택 공간이 필요하다는 것을 알 수 있습니다. 나는 20kb와 더 많은 것을 요구하는 기능이있다. 그리고 디버거에서 스택이 전혀 사용되지 않음을 알 수 있습니다. (모두 0xCC로 초기화되고 절대 건드리지 않음)
끝 부분에 어셈블러 코드가 표시됩니다.
문제는 VS-2015 및 VS-2017에서 볼 수 있습니다.
디버그 모드에서만.
릴리스 모드에서 함수는 여분의 스택 공간을 전혀 예약하지 않습니다.
내가 보는 유일한 규칙은 다음과 같습니다. 더 많은 AddCol 호출은 더 많은 스택을 예약하게합니다. AddCol 호출 당 약 500 바이트가 예약되어 있음을 알 수 있습니다.
다시 : 함수는 개체를 반환하지 않고 바인딩 정보에 대한 참조를 반환합니다.
__pragma(runtime_checks("", off)) __pragma(optimize("ts", on)) __pragma(strict_gs_check(push, off))
하지만 아무 소용이 :
은 이미 기능 (그러나 헤더의 클래스 정의 내부)의 앞에 다음 pragma를 사용했다. 이 pragma는 최적화를 실행하고 런타임 검사 및 스택 검사를 중단합니다. 어떻게 할당 된이 불필요한 스택 공간을 줄일 수 있습니다. 어떤 경우에는이 함수가 사용될 때 디버그 버전에서 스택 오버 플로우를 볼 수 있습니다. 릴리스 버전에는 문제가 없습니다.
; 325 : BIND_BEGIN(CMasterData, _T("tblMasterData"))
push ebp
mov ebp, esp
sub esp, 2176 ; 00000880H
push ebx
push esi
push edi
mov DWORD PTR _this$[ebp], ecx
mov eax, OFFSET [email protected][email protected]@?$AAt?$AAb[email protected]
test eax, eax
je SHORT [email protected]
push OFFSET [email protected][email protected]@?$AAt?$AAb[email protected]
mov ecx, DWORD PTR _this$[ebp]
add ecx, 136 ; 00000088H
call DWORD PTR [email protected][email protected][email protected][email protected]@@@@@[email protected]@[email protected][email protected]
[email protected]:
; 326 : // Columns:
; 327 : B$C_IDENT (_T("Id"), m_lId);
push 0
push 0
push 1
push 4
push 0
call [email protected]@@[email protected] ; ATL::_GetOleDBType
add esp, 4
movzx eax, ax
push eax
push 0
push OFFSET [email protected][email protected][email protected]
mov ecx, DWORD PTR _this$[ebp]
call [email protected]@[email protected]@[email protected]@[email protected]@[email protected] ; DB::CDBAccess::AddCol
; 328 : B$C (_T("Name"), m_szName);
push 0
push 0
push 0
push 122 ; 0000007aH
mov eax, 4
push eax
call [email protected]@@[email protected] ; ATL::_GetOleDBType
add esp, 4
movzx ecx, ax
push ecx
push 4
push OFFSET [email protected][email protected][email protected]
mov ecx, DWORD PTR _this$[ebp]
call [email protected]@[email protected]@[email protected]@[email protected]@[email protected] ; DB::CDBAccess::AddCol
; 329 : B$C (_T("Data"), m_data);
push 0
push 0
push 0
push 4
push 128 ; 00000080H
call [email protected]@@[email protected]@@Z ; ATL::_GetOleDBType
add esp, 4
movzx eax, ax
push eax
push 128 ; 00000080H
push OFFSET [email protected][email protected][email protected]
mov ecx, DWORD PTR _this$[ebp]
call [email protected]@[email protected]@[email protected]@[email protected]@[email protected] ; DB::CDBAccess::AddCol