Skip to content

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

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)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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