natalie-lang / natalie

a work-in-progress Ruby compiler, written in Ruby and C++

Home Page:https://natalie-lang.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Failures in asan test

herwinw opened this issue · comments

Extracted from #1891, since it does happen in the master branch as well.

Running test/natalie/argument_test.rb (and possibly other tests as well) with an asan build currently fails at this part of the code:

Method *Object::find_method(Env *env, SymbolObject *method_name, MethodVisibility visibility_at_least, Value sent_from) const {
    ModuleObject *klass = singleton_class();
    if (!klass)
        klass = m_klass;
    assert(klass);

This error originates in the implementation of Tempfile:

  (File.public_instance_methods - public_instance_methods).each do |method|
    define_method(method) do |*args, **kwargs, &block|
      @tmpfile.public_send(method, *args, **kwargs, &block)
    end
  end

And is easy to reconstruct:

$ bin/natalie -rtempfile -e ''
natalie20240315-252571-nodkaz: src/object.cpp:953: Natalie::Method* Natalie::Object::find_method(Natalie::Env*, Natalie::SymbolObject*, Natalie::MethodVisibility, Natalie::Value) const: Assertion `klass' failed.

Rewriting this piece of code to implement method_missing instead does resolve this specific issue, but then the next call to each breaks:

def reset
  @stubs.values.each do |stubs|
    stub = stubs.first
    stub.subject.singleton_class.remove_method(stub.message)
  end

This can be rewritten to @stubs.each_value, but then something else breaks, so this is obviously no solution.

I've managed to get the following output it gdb:

(gdb) p (Natalie::Object)(*this)
$10 = {<Natalie::Cell> = {_vptr.Cell = 0x5310003b7720, m_marked = 224}, m_klass = 0x0,
  m_type = Natalie::ObjectType::Nil, m_singleton_class = 0x0, m_owner = 0x0, m_flags = 0, m_ivars = 0x0}
(gdb) p (Natalie::Object)(*NilObject::the())
$11 = {<Natalie::Cell> = {_vptr.Cell = 0x555556352ae8 <vtable for Natalie::NilObject+16>, m_marked = false},
  m_klass = 0x531000042a20, m_type = Natalie::ObjectType::Nil, m_singleton_class = 0x531000042a20, m_owner = 0x0,
  m_flags = 1, m_ivars = 0x0}

This looks like there is a second instance of an object with m_type == ObjectType::Nil, which is not supposed to happen.

#1894 is a blind attempt to run the asan tests in Debian Bullseye instead of Bookworm (so using oldstable instead of stable), which looks to be passing the specs. This is an indication that the issue is caused by some update in Debian, which does explain the sudden change in behaviour.