いとうといいます。

長文になります、すいません。

 FreeBSD/amd64 7.0-RELEASE において、mpfr-2.3.1 の挙動に悩んでおります。
具体的には make check でいくつかのテストが SIGSEGV になってしまう、と
いうものです。

例として tzeta.core ファイルを読み込ませてバックトレースを見てみると、
 0 番地ジャンプしているように見えます。

(gdb) bt
#0  0x0000000000000000 in ?? ()
#1  0x0000000800781954 in mpfr_cache (dest=0x7fffffffe160,
cache=0x80052da68,
    rnd=GMP_RNDU) at cache.c:62
#2  0x000000080075fb88 in mpfr_exp2 (y=0x7fffffffe680,
    x=<value optimized out>, rnd_mode=GMP_RNDN) at exp2.c:119
#3  0x000000080076621c in mpfr_pow (z=0x7fffffffe680, x=<value
optimized out>,
    y=0x7fffffffe6a0, rnd_mode=GMP_RNDN) at pow.c:402
#4  0x000000080077706f in mpfr_ui_pow (y=0x7fffffffe680, n=8,
    x=0x7fffffffe6a0, rnd_mode=GMP_RNDN) at ui_pow.c:36
#5  0x000000080077c4ee in mpfr_zeta_pos (z=0x7fffffffe9a0,
s=0x7fffffffe980,
    rnd_mode=GMP_RNDN) at zeta.c:123
#6  0x000000080077ceda in mpfr_zeta (z=0x7fffffffe9a0,
s=0x7fffffffe980,
    rnd_mode=GMP_RNDN) at zeta.c:385
#7  0x0000000000402779 in main (argc=1, argv=0x7fffffffea98) at
tzeta.c:37

該当するコードは

int
mpfr_cache (mpfr_ptr dest, mpfr_cache_t cache, mp_rnd_t rnd)
{
  mp_prec_t prec = MPFR_PREC (dest);
    :
      /* Update the cache. */
      pold = prec;
      mpfr_prec_round (cache->x, pold, GMP_RNDN);
      cache->inexact = (*cache->func) (cache->x, GMP_RNDN);
    }

この部分で、*cache->func が NULL になっているようです。

Breakpoint 1, mpfr_cache (dest=0x7fffffffe1e0, cache=0x80052da68,
rnd=GMP_RNDU)
    at cache.c:43
43      {
(gdb) display *cache
1: *cache = {x = {{_mpfr_prec = 0, _mpfr_sign = 1, _mpfr_exp = 0,
      _mpfr_d = 0x0}}, inexact = 0, func = 0}

しかし同じことを FreeBSD/i386 6.2-RELEASE-p4 でやると SIGSEGV にはなり
ません。

Breakpoint 2, mpfr_cache (dest=0xbfbfe16c, cache=0x280d5720,
rnd=GMP_RNDU)
    at cache.c:44
44        mp_prec_t prec = MPFR_PREC (dest);
(gdb) display *cache
1: *cache = {x = {{_mpfr_prec = 0, _mpfr_sign = 1, _mpfr_exp = 0,
      _mpfr_d = 0x0}}, inexact = 0,
  func = 0x280aa89c <mpfr_const_log2_internal>}

 *cache->func は NULL になっておらず、しかもこちらの結果から

/* Declare the cache */
MPFR_DECL_INIT_CACHE(__gmpfr_cache_const_log2,
mpfr_const_log2_internal);

とあらかじめ .data 領域にある値が入っているのかなと思われます。しかし
 FreeBSD/amd64 では NULL になっている、と。ちなみに双方とも
 /usr/bin/gcc を使って mpfr をコンパイルしています。

 shared library がメモリに配置され .data 内の関数ポインタが確定するタ
イミングとか、そういうあたりの知識は持ち合わせておりませんのでこれ以上
は追えず困っております(そもそも的外れ?)。

アドバイスいただけるでしょうか。

 ports にある math/mpfr の動作確認は行っておりません。あしからずご了承
ください。

----
よっちい


メールによる返信