책정리/Windows VIA C,C++

1장 에러 핸들링

GONII 2019. 2. 23. 22:13
윈도우 함수를 호출하면 호출된 함수는 먼저 전달된 인자의 유효성을 확인하고 함수의 기능을 수행하려 한다. 만일 전달된 인자가 유효하지 않거나 다른 이유로 인해 해당 기능을 수행할 없으면 함수는 실패로 반환한다.
윈도우 함수의 대표적인 반환 자료형
자료형
실패했을 때의
VOID
함수는 절대 실패하지 않는다. 아주 적은 수의 윈도우 함수만이 VOID형의 반환 자료형을 가진다.
BOOL
함수가 실패하면 0 반환한다. 성공 시에는 0 아닌 값을 반환한다. 반환 값을 TRUE 비교해서는 안된다. 함수의 성공 여부를 확인하기 위해 FALSE인지 아닌지를 비교하는 것이 가장 좋은 방법이다.
HANDLE
함수가 실패하면 반환 값은 대개 NULL이다. 성공 시에는 유효한 오브젝트 핸들을 반환한다. 몇몇 함수들은 -1 정의된 INVALID_HANDLE_VALUE 반환하는 경우가 있기 때문에 주의가 필요하다.
PVOID
함수가 실패하면 NULL 반환한다. 성공 시에는 PVOID 데이터를 저장하고 있는 메모리 주소를 가리킨다.
LONG/DWORD
상당히 까다로운 형태다. 이러한 종류의 함수는 대개 LONG이나 DWORD형으로 개수를 반환한다. 어떤 이유로 인해 개수를 반환하지 못하게 되면 0이나 -1 반환한다.
윈도우 함수가 실패하면 함수가 실패했는지의 여부를 알아내는 과정이 반드시 필요하다. 마이크로소프트는 발생할 가능성이 있는 모든 에러코드를 32비트 숫자로 정의해 두었다.
윈도우 함수가 실패하게 되면 내부적으로 함수를 호출한 스레드의 스레드 지역 저장소(thread-local storage) 적절한 에러 코드를 저장해 둔다. 이러한 메커니즘을 통해 여러 개의 스레드가 동시에 수행될 경우라도 상호간에 영향을 미치지 않고 스레드별로 에러 코드를 유지할 있게 된다. 호출한 함수가 실패한 것으로 판단되면 어떤 에러가 발생했는지 확인하기 위해 GetLastError 함수를 사용할 있다.
함수는 단순히 가장 최근에 호출된 함수의 에러 코드를 스레드 지역 저장소로부터 가져온다. 이러한 32비트 에러 코드를 유용한 정보로 변환할 필요가 있다. WinError.h 헤더 파일은 마이크로소프트가 정의한 모든 에러 코드의 리스트를 가지고 있다.
각각의 에러는 메시지 ID(GetLastError 함수의 반환 값과 비교할 있도록 정의된 매크로), 메시지 텍스트(영어로 설명), 에러 코드(메시지 ID 대신 값을 직접 사용해서는 안된다) 3가지 요소로 구성되어 있다.
만일 GetLastError 함수를 호출하기 전에 다른 함수를 호출하게 되면 다른 함수의 수행 결과가 겹쳐 써지게 된다. 함수 호출이 성공하면 ERROR_SUCCESS 에러 코드로 기록한다.
몇몇 윈도우 함수들은 가지 서로 다른 성공 이유가 존재한다. 예를 들어 명명된 이벤트 커널 오브젝트를 생성하는 함수를 호출하면 실제로 새로운 커널 오브젝트가 생성되는 경우 외에도 이미 동일 이름의 커널 오브젝트가 존재하는 경우에도 성공을 반환하게 된다. 경우 애플리케이션은 어떠한 이유로 함수가 성공했는지 정확히 구분해야 필요가 있다. 따라서 함수 호출이 성공했다하더라도 부가적인 성공의 이유를 확인하기 위해 GetLastError 호출해야 수도 있다.
Watch창을 통해 현재 수행 중인 스레드의 마지막 에러 코드와 메시지 텍스트를 확인 있다.($err,hr)
에러 코드를 메시지 텍스트로 변환해 주는 FormatMessage 함수도 제공하고 있다.
  1. 자신만의 에러 코드를 정의하는 방법
개발하는 함수는 하나 혹은 여러 가지 이유에 의해 실패할 있을 것이며, 실패의 원인을 호출자에게 반환하도록 작성되어야 것이다.
함수가 실패했음을 나타내기 위해서는 실패의 이유를 스레드의 마지막 에러 코드를 설정하고 FALSE, INVALID_HANDLE_VALUE, NULL 같은 값이나 적절한 값을 반환하도록 함수를 작성하면 된다.
스레드의 마지막 에러 코드를 설정하기 위해서는 SetLastError 함수를 호출하면 된다.
함수의 인자로 전달되는 값은 어떠한 32비트 값이라도 상관없다. 만약 WinError.h 정의된 에러의 원인이 정확하게 에러의 원인을 나타내지 못한다면 자신만의 에러 코드를 작성할 있다.
에러 코드 필드
비트
31-30
29
28
27-16
15-0
내용
심각도
마이크로소프트/고객
예약됨
식별 코드
예외 코드
의미

0 = 성공
1 = 정보
2 = 주의
3 = 에러
0 = 마이크로소프트가 정의한 코드
1 = 고객이 정의한 코드
항상 0
256까지는 마이크로소프트에 의해 예약됨
마이크로소프트나 고객이 정의한 코드
  1. ErrorShow 예제 애플리케이션
FormatMessage 어떻게 사용되었는지를 확인할 있다.
반응형

'책정리 > Windows VIA C,C++' 카테고리의 다른 글

3장 커널 오브젝트  (0) 2021.07.01
목차  (0) 2019.02.23