From: "mame (Yusuke Endoh)" <mame@...> Date: 2012-11-05T20:33:48+09:00 Subject: [ruby-core:48896] [ruby-trunk - Bug #7044][Assigned] BigDecimal#power randomly raises coercion errors Issue #7044 has been updated by mame (Yusuke Endoh). Status changed from Open to Assigned Assignee set to mrkn (Kenta Murata) Target version set to 2.0.0 Confirmed, good catch! Looks GC issue. An intermediate object seems to be GC'd too early. The following patch will fix. Mrkn, could you review and commit it if it looks good? diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c index f58b640..36ca77d 100644 --- a/ext/bigdecimal/bigdecimal.c +++ b/ext/bigdecimal/bigdecimal.c @@ -2016,6 +2016,7 @@ static VALUE rmpd_power_by_big_decimal(Real const* x, Real const* exp, ssize_t const n) { VALUE log_x, multiplied, y; + volatile VALUE obj = exp->obj; if (VpIsZero(exp)) { return ToValue(VpCreateRbObject(n, "1")); @@ -2024,6 +2025,7 @@ rmpd_power_by_big_decimal(Real const* x, Real const* exp, ssize_t const n) log_x = BigMath_log(x->obj, SSIZET2NUM(n+1)); multiplied = BigDecimal_mult2(exp->obj, log_x, SSIZET2NUM(n+1)); y = BigMath_exp(multiplied, SSIZET2NUM(n)); + RB_GC_GUARD(obj); return y; } -- Yusuke Endoh <mame@tsg.ne.jp> ---------------------------------------- Bug #7044: BigDecimal#power randomly raises coercion errors https://bugs.ruby-lang.org/issues/7044#change-32391 Author: twooster (Tony Wooster) Status: Assigned Priority: Normal Assignee: mrkn (Kenta Murata) Category: Target version: 2.0.0 ruby -v: ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux] When running the following code: require 'bigdecimal' 10000.times { BigDecimal.new('1001.10')**0.75; putc '.' } The call to ** will sometimes (not always) raise the following trace: ..............................................TypeError: #<Class:0x0000001cd78f40> can't be coerced into BigDecimal from (irb):4:in `**' from (irb):4:in `block in irb_binding' from (irb):3:in `times' from (irb):3 from /home/tony/.rbenv/versions/1.9.3-p194/bin/irb:12:in `<main>' (The '.'s being the debug print of the putc.) I understand the documentation says only integer powers are supported for BigDecimal, however there is code support for floats and rationals, and it should fail or work reliably either way. -- http://bugs.ruby-lang.org/