[Win32 API] 가변인자 처리 방식, 그리고 오류
저장소/VC++
최근 가변인자 처리 과정에서 생각치 못했던 오류가 발생했다.(원인은 내 실수 ㅡㅜ)
그리 어려웠던 것도 아니었는데 시간은 시간대로 소비하고 간신히 원인을 찾았는데 정말 생각하지도 못했던 문제였기에 적어본다.
우선 가변인자 처리에는 _vstprintf_s의 사용보다는 Strsafe.h에 있는 StringCchVPrintf 함수를 주로 사용한다.
익숙해져서이기도 하지만 안전한 문자열 처리를 위해 Strsafe.h에 있는 함수들을 사용하기 때문이다.
내가 보편적으로 쓰는 처리방식은 아래와 같다.
void OuputFunction(LPCTSTR lpszFormat, ...) { TCHAR szContent[1024] = {0,}; va_list vlist; va_start(vlist, lpszFormat); StringCchVPrintf(szContent, 1024, lpszFormat, vlist); va_end(vlist); ... }
로그 기록 처리에 주로 위와 같이 구현해서 사용하는데 쓰다보니 가변인자 처리를 2번에 걸쳐서 쓰게되는 상황이 생겼는데
문제는 여기서 발생했다.
처리 상황을 똑같이 구현해놓기는 뭐하고 다음과 같이 처리해놓으니 문제 증상이 재현된다.
void OuputFunction(LPTSTR _lpszRet, size_t _cchLen, LPCTSTR _lpszFormat, ...) { TCHAR szContent[1024] = {0,}; if(NULL != _lpszFormat) { va_list vl; va_start(vl, _lpszFormat); StringCchVPrintf(szContent, sizeof(szContent) / sizeof(TCHAR), _lpszFormat, vl); va_end(vl); } if(NULL != _lpszRet) StringCchCopy(_lpszRet, _cchLen, szContent); } void SomeFunction() { TCHAR* pszSampleString = _T("C:\\Users\\Administrator\\Desktop\\style-12px%20Helvetica%2C%20Arial%2C%20Sans-serif;606060_FFFFFF_3399CC_99FF33_006600_666666_FFFFFF;0px%20solid;_blank[1].htm"); TCHAR szContent[1024] = {0,}; OuputFunction(szContent, _countof(szContent), _T("[test] %s"), pszSampleString); OuputFunction(NULL, 0, szContent); _tprintf_s(_T("%s\n"), szContent); }
증상 재현을 위해 대충 만들었기 때문에 그냥 이러한 상황이 있다 가정한다.
주목해야 할 부분은 바로 pszSampleString의 파일 경로다.
첫 번째, OuputFunction을 거치고나면 szContent에 "[test] C:\Users..." 요로코롬 값이 들어간다.
두 번째, szContent가 다시 OutputFunction의 Format으로 전달되는데 이 때 문자열에 포함된 %로 인하여 문제 발생.
(디버깅으로 하나하나 찾아보니 %s를 두 번째 처리할 때 Access Violation이 발생했다.)
보통 가변인자 처리를 많이 하는 것도 아니고 2번에 걸쳐 처리되게 만들지도 않는다.
좀 편하게 만들자고 여기저기 만들어뒀는데 그것땜에 이런 문제를 발견했다.
생각치도 못했던 파일명으로 인하여 예상하지 못했던 증상을 발견했네. ㅡㅜ
이번 가변인자 처리과정의 문제로 인해 좀 더 생각하고 만들어야겠단 반성을 하게됐다.
끝!
'저장소 > VC++' 카테고리의 다른 글
[Win32 API] File Version 확인 (0) | 2011.02.22 |
---|---|
[Win32 API] File Information 확인 (1) (0) | 2011.02.22 |
[MFC] Modaless Dailog - Itself destroy (0) | 2011.02.14 |
[MFC] Esc Key 또는 Return Key에 의해 Dialog가 닫힐 때 처리 방법 (0) | 2011.01.26 |
[MFC] OnCancel(), OnClose(), OnDestroy(), OnOK() 그리고 Dialog 소멸자 (0) | 2011.01.04 |