중요한 것은, 스레드는 계속 생성된다는 거... :: 2009/03/16 14:10


얼마 전에 버그를 수정하다 신기한 현상을 하나 발견했습니다. 물론 지금까지 저만 멍청하게 생각하고 있었던 건지도 모르겠습니다. ㅋㅋ~ NtQuerySystemInformation이란 함수와 관련된 건데요. 아마 다른 함수들에도 적용이 될 것 같습니다. NtQuerySystemInformation 함수는 시스템 정보를 구해오는 함수입니다. 보통 프로세스 목록이라든지, 스레드 목록, 드라이버 목록 등과 같은 정보를 얻을 때 사용하는 함수죠. 이러한 종류의 윈도우 API를 사용할 때에는 한 가지 원칙이 있습니다. 바로 버퍼 크기를 먼저 구하고 할당한 다음 사용하라는 것이죠. 프로세스나 스레드가 몇 개가 떠 있는지 알 수 없기 때문입니다. 통상적으로 아래와 같은 패턴으로 만들게 되죠.


물론 NtQuerySystemInformation 함수의 인자가 저렇게 단순하진 않습니다. 예시는 핵심만 보여주기 위해서 버퍼, 버퍼 크기, 필요한 크기로 인자를 가정하고 표현해 본 것이죠. 거의 대부분의 경우에 위 코드는 정상적으로 동작합니다. 하지만 특정 경우에 두 번째 호출이 실패하는 경우가 생깁니다. 물론 다른 이유도 아니 버퍼 크기가 부족하다는 이유로 말이죠.

왜 그럴까요? 이유는 간단합니다. 처음 NTQSI를 호출한 시점과 그 다음 NTQSI를 호출한 시점의 시스템 정보가 변경되었기 때문입니다. 예를들어 스레드 목록을 구한다고 한다면, 그 사이에 스레드가 추가적으로 생성된 경우입니다. 어쨌든 저런 식의 코드는 아주 정상적인 환경에서도 실패할 가능성을 가지고 있는 셈이죠.

이런 결함을 없애기 위해서는 결국은 루프를 돌아야 합니다. 정상적일 때까지 말이죠. 물론 가져온 버퍼 크기보다 조금 더 할당하는 꼼수를 사용한다면 루프 회수를 줄일 수는 있겠죠. 같은 원리로 미리 할당된 버퍼를 사용한다면 함수 호출 회수를 더 많이 줄일 수 있습니다.

스폰서
글타래

  • 2주간 인기 글
  • 2주간 인기글이 없습니다.
Trackback Address :: http://jiniya.net/tt/trackback/794
  • Gravatar Image.
    rodream | 2009/03/16 14:26 | PERMALINK | EDIT/DEL | REPLY

    완전 찔리는 포스팅이네요...

    지금까지 눈뜬 장님으로 만든 코드가 많이 있네요...ㅋㅋ

  • Gravatar Image.
    정성태 | 2009/03/16 22:50 | PERMALINK | EDIT/DEL | REPLY

    저 같은 경우에는 snapshot처럼 동작하지 않을까 막연히 상상만하고 ... 그저 신뢰했던 코드였는데. ^^
    그런 "현실적인" 문제가 있었군요. ... 이럴 때 마다 느끼는 건데. "컴퓨터 세상에는 마법은 없다는 거!" ^^

    좋은 거 배우고 갑니다. ^^

  • Gravatar Image.
    HS | 2009/03/21 23:09 | PERMALINK | EDIT/DEL | REPLY

    아;;.. 이런 문제가 충분히 발생할 수 있다는걸...;;
    포스팅을 보고 알았습니다;; 쿨럭;;..

Name
Password
Homepage
Secret
< PREV | 1| ... 3|4|5|6|7|8|9|10|11| ... 604| NEXT >