Windows OS2013. 4. 27. 22:18
반응형

[문제증상]

GetTempFileName()을 호출하면 시스템이 느려진다???

 

[분석]

시스템이 느려진다는 문의가 있어 Process Monitor로 살펴 봤다.

 

TEMP.EXE 3568 CreateFile C:\Documents ... \Temp\myFFF.tmp
TEMP.EXE 3568 CreateFile C:\Documents ... \Temp\myFFF.tmp
TEMP.EXE 3568 CreateFile C:\Documents ... \Temp\my1000.tmp
TEMP.EXE 3568 CreateFile C:\Documents ... \Temp\my1000.tmp
TEMP.EXE 3568 CreateFile C:\Documents ... \Temp\my1001.tmp
TEMP.EXE 3568 CreateFile C:\Documents ... \Temp\my1001.tmp
TEMP.EXE 3568 CreateFile C:\Documents ... \Temp\my1002.tmp
TEMP.EXE 3568 CreateFile C:\Documents ... \Temp\my1002.tmp

 

이런 임시 파일 열기가 수두룩히 이어지고 있었다.

(ReadFile, CloseFile I/O는 생략했다.)

 

파일 이름 형식으로 보아 TEMP.EXE는 GetTempFileName()을 호출해 이름을 얻는 것으로 보인다.

 

문제는 GetTempFileName()에서 파일을 열어 본다는 것이다.

파일을 열어본 후에 이미 존재하면 이름의 숫자를 하나 올리고 다시 열어본다.

존재하면 또 올리고 또 열어보고... 존재하지 않는 파일이름이 나올 때까지... -_-

 

콜스택은 다음과 같이 확인된다.

 

Args to Child             
0012fcc4 80100080 0012fc64 ntdll!ZwCreateFile
00142ab0 80000000 00000000 kernel32!CreateFileW+0x35f
7ffdfc00 00142a90 00000000 kernel32!GetTempFileNameW+0x1fd
00422050 00422058 00000000 kernel32!GetTempFileNameA+0x75
00000001 00370d10 00370d88 TEMP!main+0x51

 

시스템 사용중에는 마지막 인덱스를 보관하고 사용하는 것 같은데...

부팅후 처음으로 GetTempFileName()을 호출하면 1번부터 마지막 인덱스를 찾기 위한 Open이 반복된다.

 

위 예제에서 이름을 보면 몇 번이나 열어보고 있는 것인지 확인이 가능하다.

myFFF.tmp로 보아 16진수로 올라가고 있음을 알 수 있으므로 my1000.tmp는 4096번째 파일이다.

tmp 파일이 이미 4096개 존재했다는 뜻이고 계속 올라가고 있다.

이 시스템에는 4000개 이상의 엄청나게 많은 tmp파일이 존재하고 있었다.

 

그냥 보면 왜 CreateFile이 2번씩 나오는지, 이게 왜 시스템을 느려지게 하는지 모르시겠지만...

사실 이 시스템에는 Anti-Virus가 설치되어 있기 때문에 다음과 같이 해석해야 한다.

 

TEMP.EXE 3568 CreateFile C:\Documents ... \Temp\myFFF.tmp => GetTempFileName Open
TEMP.EXE 3568 CreateFile C:\Documents ... \Temp\myFFF.tmp => Anti-Virus 실시간감시 Open
TEMP.EXE 3568 CreateFile C:\Documents ... \Temp\my1000.tmp
TEMP.EXE 3568 CreateFile C:\Documents ... \Temp\my1000.tmp
TEMP.EXE 3568 CreateFile C:\Documents ... \Temp\my1001.tmp
TEMP.EXE 3568 CreateFile C:\Documents ... \Temp\my1001.tmp
TEMP.EXE 3568 CreateFile C:\Documents ... \Temp\my1002.tmp => GetTempFileName Open
TEMP.EXE 3568 CreateFile C:\Documents ... \Temp\my1002.tmp => Anti-Virus 실시간감시 Open

 

첫번째는 GetTempFileName()에서 수행하는 Open이고 두번째는 첫번째 Open을 검사하기 위해서 Anti-Virus 실시간감시에서 수행하는 Open이다.

 

실시간감시가 없었다면 GetTempFileName()에서 수행하는 CreateFile/CloseFile 때문에 느려지는 일은 없다.

CreateFile/CloseFile은 순식간에 끝나기 때문이다.

 

하지만 실시간감시가 있다면 tmp파일을 검사하기 위해 Anti-Virus에서 ReadFile이 추가로 발생한다.

ReadFile은 디스크에 있는 파일의 데이터를 실제로 읽는 작업을 하기 때문에 실제 데이터를 읽지 않는 CreateFile/CloseFile에 비해 속도가 느릴 수 밖에 없다.

 

위 예에서 tmp파일 하나 검사하는데 10ms 라고 가정하면 4000개를 검사하는 순간까지는 40초가 나온다.

GetTempFileName()을 호출했는데 리턴될 때까지 40초 이상 걸리는 것이다. -_-

 

 

[결론]

자신의 prefix를 가지는 tmp 파일이 많이 남아 있다면 정리해야 겠다.

부팅후 최초 GetTempFileName() 호출시 특정 prefix를 가지는 tmp 파일이 많이 존재한다면...

Anti-Virus가 모든 tmp 파일을 검사하게 돼 시스템이 느려질 수도 있다.

 

 

[부록]

GetTempFileName.txt

반응형
Posted by GreeMate