에러 처리

본 장에서는 에러처리 방법과 디버그 방법에 대해서 설명한다.

1. 개요

Tmax의 API는 에러가 발생하는 경우 상황에 따른 적절한 에러 번호를 설정한다. 에러 메시지를 참고하면 에러에 대한 원인 규명에 많은 도움이 된다. 이외에 API 내부 시스템 콜 레벨의 에러 정보가 알고 싶다면 tuxinc/Uunix.h에 정의되어 있는 에러 메시지와 API들을 참고한다.

Tmax에서는 애플리케이션 레벨이 아닌 Tmax 시스템 운영 상에 발생하는 문제를 도출하는 데 도움을 주기 위해 운영 상의 여러 가지 정보를 콘솔에 보여주는 디버깅용 CLH를 제공하므로 참고한다.

Tmax 운영 중에 발생하는 에러 메시지는 Tmax Message Reference Guide를 참고한다.

2. API 레벨 에러 처리

Tmax API가 실패하는 경우의 반환값은 API마다 다르며 전역변수 tperrno에는 에러 상황에 대한 에러 번호가 설정된다.

2.1. tpstrerror

서버와 클라이언트에서 사용되는 함수로 에러 번호에 해당하는 메시지를 출력한다. Tmax 함수 이용 중 에러가 발생할 경우 해당 에러 코드는 tperrno라는 전역변수에 설정된다. tpstrerror() 함수는 tperrno에 설정된 에러에 대한 메시지를 출력하는 함수이다.

  • 프로토타입

    # include <atmi.h>
    char *tpstrerror (int tperrno)
  • 파라미터

    파라미터 설명

    tperrno

    에러 메시지를 출력하려는 에러 코드이다.

  • 반환값

    반환값 설명

    에러 메시지

    에러 코드에 대한 메시지가 있는 경우이다.

    NULL

    에러 코드에 대한 메시지가 없는 경우이다.

  • 예제

    #include <stdio.h>
    #include <usrinc/atmi.h>
    
    void main(int argc, char *argv[])
    {
        int ret;
        char buf;
        TPSTART_T *tpinfo;
    
        tpinfo = (TPSTART_T *)tpalloc(“TPSTART”, NULL, sizeof(TPSTART_T));
    
        if (tpinfo==NULL) { error processing }
        strcpy(tpinfo->dompwd, “tuxedo”);
    
        if (tpstart(tpinfo) == -1){
            printf(“tpstart fail , err = %s\n”, tpstrerror(tperrno));
            exit(1);
        }
    
        buf = (char *)tpalloc(“CARRAY”, NULL, 20);
        if (buf==NULL) {error processing };
        data process....
    
        tpfree((char *) buf);
        tpend();
    }

3. 시스템 레벨 에러 처리

Tmax API는 많은 시스템 호출을 사용한다. 운영체제나 플랫폼 상에 문제가 있어서 특정 시스템 호출에서 에러가 발생하는 경우 이를 확인하고 싶을 경우나 에러 메시지가 다른 이종 플랫폼으로 포팅할 경우 에러 메시지를 통합하여 관리할 경우 아래에 소개하는 API를 사용하면 도움이 된다.

헤더 파일의 위치는 다음과 같다.

TMAXDIR/tuxinc/Uunix.h

3.1. Uunixerr

시스템 호출 도중 에러가 발생할 경우 통합된 에러 번호가 설정되는 변수이다.

int Uunixerr

3.2. Uunix_err

ATMI API 호출이 실패하고 tperrno가 TPEOS로 설정된 경우 시스템 에러의 종류를 stderr로 출력하는 함수이다.

  • 프로토타입

    # include <Uunix.h>
    void Uunix_err (char *msg)
  • 파라미터

    파라미터 설명

    msg

    에러가 발생한 시스템 호출에 앞서 추가하고 싶은 메시지이다. 일반적으로 프로그램명을 기록한다.

    다음 중에 하나가 출력된다.

    UCLOSE, UCREAT, UEXEC, UFCTNL, UFORK, ULSEEK, UMSGCTL,
    UMSGGET, UMSGSND, UMSGRCV, UOPEN, UPLOCK, UREAD, USEMCTL,
    USEMGET, USEMOP, USHMCTL, USHMGET, USHMAT, USHMDT, USTAT,
    UWRITE, USBRK, USYSMUL, UWAIT, UKILL, UTIME, UMKDIR, ULINK,
    UUNLINK, UUNAME, UNLIST
  • 예제

    ret=tmaxreadenv("NO THAT FILE", "TMAX");
    if (ret<0) {
       Uunix_err("myprog");
       exit(1);
    }

    다음은 앞의 예제를 수행한 결과이다.

    mypog: UOPEN

3.3. Ustrerror

시스템 에러 코드(errno)에 대한 통합 에러 메시지를 반환하는 함수이다.

  • 프로토타입

    # include <Uunix.h>
    char * Ustrerror(int err);
  • 파라미터

    파라미터 설명

    err

    알고 싶은 에러 메시지의 통합 에러 번호이다.

  • 반환값

    함수 호출에 성공하는 경우 errno에 대한 통합 에러 메시지의 포인터 주소가 반환된다.

    다음 목록 중 하나가 chr * 타입 포인터로 반환된다.

    UCLOSE, UCREAT, UEXEC, UFCTNL, UFORK, ULSEEK, UMSGCTL, UMSGGET, UMSGSND,
    UMSGRCV, UOPEN, UPLOCK, UREAD, USEMCTL, USEMGET, USEMOP, USHMCTL, USHMGET,
    USHMAT, USHMDT, USTAT, UWRITE, USBRK, USYSMUL, UWAIT, UKILL, UTIME, UMKDIR,
    ULINK, UUNLINK, UUNAME, UNLIST
  • 예제

    ret=tmaxreadenv("NO THAT FILE", "TMAX");
    if (ret<0)
    {
        printf("%d->%s\n", Uunixerr, Ustrerror(Uunixerr));
        exit(1);
    }

    다음은 앞의 예제를 수행한 결과이다.

    11->UOPEN

3.4. tmaxoserrno

시스템 호출 도중 에러가 발생할 경우 통합된 에러 번호가 설정되는 변수이다. 에러 발생 이후 여러 시스템 콜 호출시 에러 번호가 최초 에러 발생 이후에 변경되어 원인 파악이 어려워 질 수 있다. 이 때 tmaxoserrno 변수를 확인하면 tperrno 가 TPEOS, TPESYSTEM 발생 시점의 시스템 에러 번호를 알 수 있다. Windows 는 GetLastError() 값을 , Unix에서는 errno 의 값을 저장하고 있다.

# include <atmi.h>
int tmaxoserrno;

4. 디버그

4.1. 디버그 CLH

TMAXDIR/bin 디렉터리에 위치한 clh.dbg라는 파일을 CLH로 이름을 변경하여 사용하면 CLH에서 이루어지는 모든 메시지 전달의 내용을 확인할 수 있다. 반드시 원본 CLH를 백업해둔다.

/home/navis/tmax/bin> tmboot

TMBOOT for node(aix5l) is starting:
Welcome to Tmax demo system: it will expire 2002/9/15
Today: 2002/7/16
        TMBOOT: TMM is starting: Tue Jul 16 22:39:13 2002
        TMBOOT: CLL is starting: Tue Jul 16 22:39:13 2002
        TMBOOT: CLH is starting: Tue Jul 16 22:39:13 2002
COM: waiting for TMM reply
LIB: read 96 bytes
(I) CLH Current Tmax Configuration:
                Number of client handler(MINCLH) = 1
                Supported maximum user per node = 3944
                Supported maximum user per handler = 3944
LIB: read 96 bytes
CLH: bootpid = 31202
        TMBOOT: SVR(sub) is starting: Tue Jul 16 22:39:13 2002
        TMBOOT: SVR(svr2) is starting: Tue Jul 16 22:39:13 2002
CLH: request_from_server: clh = 0, ind = 0, fd = 8
CLH: msg from server: msgtype = 101, svcname = , len = 0
CLH: register_from_server, spri = 32, svri = 0, maxtms = 32
CLH: reply_to_server: clh = 0, ind = 32, fd =8
CLH: msg to server: msgtype = 1101, svcname = , len = 0
CLH: request_from_server: clh = 0, ind = 0, fd = 9
CLH: msg from server: msgtype = 135, svcname = , len = 0
.....

4.2. 디버그 라이브러리

TMAXDIR/lib 디렉터리에 libsvrd.a, libsvrd.so라는 라이브러리가 존재한다. libsvr.a, libsvr.so 대신에 이들 라이브러리를 사용하면 콘솔 화면을 통해 여러 가지 데이터 값이 출력되므로 서버 라이브러리에서 발생하는 흐름을 파악할 수 있고 에러가 발생하는 시점을 찾는 데도 편리하다. libsvrd.a의 경우는 재컴파일을 필요로 하고, libsvrd.so의 경우에는 이름만 변경하면 된다.

/oracle/navis/tmax385/lib> tmboot

TMBOOT for node(tmaxc1) is starting:
Welcome to Tmax demo system: it will expire 2002/9/30
........
GETOPT1: -b 255859
GETOPT1: -s svr2
GETOPT1: -d -1
SVR: delay = -1, _use_lock = 1
COM: waiting for TMM reply
LIB: read 96 bytes
register_to_tmm success
init_shm(78990, 139364) success
init_svctab success
SVR: my info--1 32 0 0 -3
init_clh success
LIB: read 96 bytes
register_to_clh success
init_txinfo success
check_node success
_tmax_init = 1
GETOPT1: -b 255859
GETOPT1: -s fdltest
GETOPT1: -d -1
SVR: delay = -1, _use_lock = 1
COM: waiting for TMM reply
LIB: read 96 bytes
register_to_tmm success
......