絖綛 N@i.jp  昨日:00038570
 今日:00014028
 総計:00753980
keywords
管理者専用
  Post   Add link   Control Panel 































新しいトピック
最新:10/01 12:07


新しいコメント
最新:07/28 16:47






管理人へMAIL

プライバシーポリシー

OpenSSL 1.0.2はcrashして良いのです

悪いのはcrashログを吐きまくるMacOS Xではないかな


 その後、更に調べたら EXC_BAD_INSTRUCTION例外(SIGILL)はPowerPCの種類を調べるための意図的なものだと分かりました。当該ソースは "crypto/ppccap.c" です。この中の OPENSSL_cpuid_setup() 関数が問題の OPENSSL_ppc64_probe() の呼びだし元ですね。その一部を抜粋すると、


    memset(&ill_act, 0, sizeof(ill_act));
    ill_act.sa_handler = ill_handler;
    ill_act.sa_mask = all_masked;

    sigprocmask(SIG_SETMASK, &ill_act.sa_mask, &oset);
    sigaction(SIGILL, &ill_act, &ill_oact);

    if (sizeof(size_t) == 4) {
#ifdef __linux
        struct utsname uts;
        if (uname(&uts) == 0 && strcmp(uts.machine, "ppc64") == 0)
#endif
            if (sigsetjmp(ill_jmp, 1) == 0) {
                OPENSSL_ppc64_probe();
                OPENSSL_ppccap_P |= PPC_FPU64;
            }
    } else {
        /*
         * Wanted code detecting POWER6 CPU and setting PPC_FPU64
         */
    }

 この部分のロジックは以下のとおり。

  1. SIGILL例外にシグナルハンドラ ill_handler() を設定しておく。
  2. sigsetjmp() のif文を実行、sigsetjmp()の復帰値は 0 なので OPENSSL_ppc64_probe() が呼び出される。
  3. OPENSSL_ppc64_probe() で SIGILL例外が発生するとシグナルハンドラ ill_handler() が呼び出される。
  4. ill_handler() から siglongjmp() で sigsetjmp() のif文に復帰する。
  5. すると今度は sigsetjmp() の復帰値が 1にになるため、==0 判定が成立せずに if文を抜ける。
  6. OPENSSL_ppc64_probe() で SIGILL例外が発生しなかった場合は、シグナルハンドラ ill_handler() が呼び出されずにOPENSSL_ppc64_probe()から復帰して来るため、OPENSSL_ppccap_P |= PPC_FPU64; が実行される。

 このようにして PowerPCの 64bit命令が実行可能か調べているのですね。この後、同じように Altivec(ベクトル)命令が使用できるか等を調べています。SIGILL例外は意図的に起されていたわけで、バグではなかったのです。

 そうなると、明示的にシグナルハンドラを指定しているにも関わらず crashログを吐きまくり、それを繰り返すと動作がおかしくなる MacOS X 10.4.11 Tiger の方に問題があるように思えますね。OpenSSLは様々なプログラムで使用されていますから、それらのプログラムについても crashログが吐き出されており、crashログだけで結構な容量を食っています。
 とは言え MacOS X を修正するのは無理ですから、OpenSSL の方で例外を起さないように修正するしかないですね。PowerPC G4前程にするなら、64bit命令なし、Altivec命令ありに決め打ちしてしまって、検査のための命令を実行しないようにソースを修正してしまえば良いのではないかな。


    memset(&ill_act, 0, sizeof(ill_act));
    ill_act.sa_handler = ill_handler;
    ill_act.sa_mask = all_masked;

    sigprocmask(SIG_SETMASK, &ill_act.sa_mask, &oset);
    sigaction(SIGILL, &ill_act, &ill_oact);

    if (sizeof(size_t) == 4) {
#ifdef __linux
        struct utsname uts;
        if (uname(&uts) == 0 && strcmp(uts.machine, "ppc64") == 0)
#endif
/*
            if (sigsetjmp(ill_jmp, 1) == 0) {
                OPENSSL_ppc64_probe();
                OPENSSL_ppccap_P |= PPC_FPU64;
            }
*/
    } else {
        /*
         * Wanted code detecting POWER6 CPU and setting PPC_FPU64
         */
    }

    if (sigsetjmp(ill_jmp, 1) == 0) {
        /*OPENSSL_altivec_probe();*/
        OPENSSL_ppccap_P |= PPC_ALTIVEC;
/*
        if (sigsetjmp(ill_jmp, 1) == 0) {
            OPENSSL_crypto207_probe();
            OPENSSL_ppccap_P |= PPC_CRYPTO207;
        }
*/
    }

でどうだろう?

 PowerPC G5前程なら64bit命令あり、Altivec命令ありに決め打ちで、


    memset(&ill_act, 0, sizeof(ill_act));
    ill_act.sa_handler = ill_handler;
    ill_act.sa_mask = all_masked;

    sigprocmask(SIG_SETMASK, &ill_act.sa_mask, &oset);
    sigaction(SIGILL, &ill_act, &ill_oact);

    if (sizeof(size_t) == 4) {
#ifdef __linux
        struct utsname uts;
        if (uname(&uts) == 0 && strcmp(uts.machine, "ppc64") == 0)
#endif
            if (sigsetjmp(ill_jmp, 1) == 0) {
                /*OPENSSL_ppc64_probe();*/
                OPENSSL_ppccap_P |= PPC_FPU64;
            }
    } else {
        /*
         * Wanted code detecting POWER6 CPU and setting PPC_FPU64
         */
    }

    if (sigsetjmp(ill_jmp, 1) == 0) {
        /*OPENSSL_altivec_probe();*/
        OPENSSL_ppccap_P |= PPC_ALTIVEC;
/*
        if (sigsetjmp(ill_jmp, 1) == 0) {
            OPENSSL_crypto207_probe();
            OPENSSL_ppccap_P |= PPC_CRYPTO207;
        }
*/
    }

で良いのではないかな?


< 過去の記事 [ 6月の 自宅サーバ リスト ] 新しい記事 >

2015 calendar
6月
123456
78910111213
14151617181920
21222324252627
282930


掲示板
最新:08/15 17:19


GsBlog was developed by GUSTAV, Copyright(C) 2003, Web Application Factory All Rights Reserved.