Skip to content

TypeError/ArgumentError can't be coerced into BigDecimal or Segmentation fault after gc compaction #340

Open
@tompng

Description

@tompng

Found while debugging #339, Related to #337

((Real*)x)->obj, a reference from T_DATA to VALUE, will be garbled after gc compaction.

typedef struct {
    VALUE  obj;     /* Back pointer(VALUE) for Ruby object.     */
    size_t MaxPrec;
    size_t Prec;
    SIGNED_VALUE exponent;
    short  sign;
    short  flag;
    DECDIG frac[FLEXIBLE_ARRAY_SIZE];
} Real;

After compaction, obj can be a reference to any kind of object.
The usage of obj field is limited. We should remove it from struct.

Reproduction code

p BigDecimal::VERSION
#=> "3.1.9", "3.2.1"

x = BigDecimal('1.5')
nan = BigDecimal("NaN")
inf = BigDecimal("Infinity")

GC.verify_compaction_references(expand_heap: true, toward: :empty)

x.divmod(inf) # Segfault
x.remainder(inf) # Segfault
nan + nan # Segfault
nan - nan # Segfault
BigMath.log(x, 10) # ??? can't be coerced into BigDecimal (TypeError)
BigMath.exp(x, 10) # Segfault
x**x # ??? can't be coerced into BigDecimal (ArgumentError)
x.power(x, 10) # ??? can't be coerced into BigDecimal (ArgumentError)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions