Project

General

Profile

Actions

Bug #18928

closed

Crash in WeakMap when inspecting T_FREE objects

Added by peterzhu2118 (Peter Zhu) almost 2 years ago. Updated almost 2 years ago.

Status:
Closed
Assignee:
-
Target version:
-
[ruby-core:109251]

Description

Pull request: https://github.com/ruby/ruby/pull/6152

WeakMap tests occasionally crash on CI due to trying to inspect T_FREE objects. There's a bug in wmap_live_p that returns true for dead objects that are in the tomb heap or on pages that are already freed.

Here's a crash log:

/tmp/ruby/v3/src/trunk/test/ruby/test_weakmap.rb:79: [BUG] Segmentation fault at 0x000000000000003c
ruby 3.2.0dev (2022-07-18T19:46:16Z master 3ac9956dee) [x86_64-linux]

-- Control frame information -----------------------------------------------
c:0017 p:---- s:0107 e:000106 CFUNC  :inspect
  me:
    called_id: inspect, type: cfunc
    owner class: 0x00007fb1fb7fcb28 [3LM    ] T_CLASS ObjectSpace::WeakMap
  self: 0x00007fb1fadb1358 [0LM  U ] weakmap (ObjectSpace::WeakMap)weakmap
c:0016 p:0024 s:0103 e:000102 BLOCK  /tmp/ruby/v3/src/trunk/test/ruby/test_weakmap.rb:79 [FINISH]
  me:
    called_id: test_inspect_garbage, type: iseq
    owner class: 0x00007fb1fae87458 [3LM    ] T_CLASS TestWeakMap
  self: 0x00007fb1fadb16f0 [3LM    ] T_OBJECT (TestWeakMap)len:10 ptr:0x0000562e91e72a70
  lvars:
    i: T_FIXNUM 283
c:0015 p:---- s:0099 e:000098 CFUNC  :times
  me:
    called_id: times, type: cfunc
    owner class: 0x00007fb1fb80bd80 [3LM    ] T_CLASS Integer
  self: T_FIXNUM 1000
c:0014 p:0005 s:0095 e:000094 METHOD /tmp/ruby/v3/src/trunk/test/ruby/test_weakmap.rb:77
  me:
    called_id: test_inspect_garbage, type: iseq
    owner class: 0x00007fb1fae87458 [3LM    ] T_CLASS TestWeakMap
  self: 0x00007fb1fadb16f0 [3LM    ] T_OBJECT (TestWeakMap)len:10 ptr:0x0000562e91e72a70
c:0013 p:0041 s:0091 e:000090 METHOD /tmp/ruby/v3/src/trunk/tool/lib/test/unit/testcase.rb:200
  me:
    called_id: run_test, type: iseq
    owner class: 0x00007fb1f9720148 [3LM    ] T_CLASS Test::Unit::TestCase
  self: 0x00007fb1fadb16f0 [3LM    ] T_OBJECT (TestWeakMap)len:10 ptr:0x0000562e91e72a70
  lvars:
    name: T_SYMBOL test_inspect_garbage
    progname: 0x00007fb1fae72080 [3LM    ] T_STRING (String) len: 53, capa: 55 "/tmp/ruby/v3/src/trunk/tool/lib/test/unit/parallel.rb"
c:0012 p:0059 s:0085 e:000084 METHOD /tmp/ruby/v3/src/trunk/tool/lib/test/unit/testcase.rb:168
  me:
    called_id: run, type: iseq
    owner class: 0x00007fb1f9720148 [3LM    ] T_CLASS Test::Unit::TestCase
  self: 0x00007fb1fadb16f0 [3LM    ] T_OBJECT (TestWeakMap)len:10 ptr:0x0000562e91e72a70
  lvars:
    runner: 0x00007fb1fae3b6c0 [3LM    ] T_OBJECT (Test::Unit::Worker)len:28 ptr:0x0000562e9081a460
    start_time: 0x00007fb1fadb1538 [0 M  U ] time (Time)time
    result: 0x00007fb1fd8ce1d0 [3LM    ] T_STRING (String) len: 0, capa: 15 ""
    time: T_NIL
    e: T_NIL
c:0011 p:0089 s:0076 e:000075 BLOCK  /tmp/ruby/v3/src/trunk/tool/lib/test/unit.rb:1563 [FINISH]
  me:
    called_id: _run_suite, type: iseq
    owner class: 0x00007fb1f99185e0 [3LM    ] T_CLASS Test::Unit::Runner
  self: 0x00007fb1fae3b6c0 [3LM    ] T_OBJECT (Test::Unit::Worker)len:28 ptr:0x0000562e9081a460
  lvars:
    method: T_SYMBOL test_inspect_garbage
    inst: 0x00007fb1fadb16f0 [3LM    ] T_OBJECT (TestWeakMap)len:10 ptr:0x0000562e91e72a70
    start_time: T_NIL
    result: T_NIL
c:0010 p:---- s:0069 e:000068 CFUNC  :map
  me:
    called_id: map, type: cfunc
    owner class: 0x00007fb1fb801560 [3LM    ] T_CLASS Array
  self: 0x00007fb1f9908488 [2      ] T_ARRAY (Array)[E ] len: 13 (embed)
c:0009 p:0117 s:0065 e:000064 METHOD /tmp/ruby/v3/src/trunk/tool/lib/test/unit.rb:1550
  me:
    called_id: _run_suite, type: iseq
    owner class: 0x00007fb1f99185e0 [3LM    ] T_CLASS Test::Unit::Runner
  self: 0x00007fb1fae3b6c0 [3LM    ] T_OBJECT (Test::Unit::Worker)len:28 ptr:0x0000562e9081a460
  lvars:
    suite: 0x00007fb1fae87458 [3LM    ] T_CLASS TestWeakMap
    type: T_SYMBOL test
    header: 0x00007fb1fadb2eb0 [2 M    ] T_STRING (String) len: 17, capa: 31 "test_suite_header"
    filter: 0x00007fb1fae41e30 [3LM    ] T_REGEXP (Regexp)
    all_test_methods: 0x00007fb1f9908488 [2      ] T_ARRAY (Array)[E ] len: 13 (embed)
    leakchecker: 0x00007fb1fae5d950 [2      ] T_OBJECT (LeakChecker)(embed) len:7
    trace: T_NIL
    assertions: T_NIL
c:0008 p:0042 s:0053 e:000052 METHOD /tmp/ruby/v3/src/trunk/tool/lib/test/unit.rb:1343
  me:
    called_id: orig_run_suite, type: iseq
    owner class: 0x00007fb1f9914a80 [3LM    ] T_MODULE (Module)Test::Unit::ExcludesOption
    defined_class: 0x00007fb1f98f0298 [3LM    ] T_ICLASS src:Test::Unit::ExcludesOption
  self: 0x00007fb1fae3b6c0 [3LM    ] T_OBJECT (Test::Unit::Worker)len:28 ptr:0x0000562e9081a460
  lvars:
    suite: 0x00007fb1fae87458 [3LM    ] T_CLASS TestWeakMap
    type: T_SYMBOL test
    ex: T_NIL
c:0007 p:0110 s:0046 E:001a70 METHOD /tmp/ruby/v3/src/trunk/tool/lib/test/unit/parallel.rb:58
  me:
    called_id: _run_suite, type: iseq
    owner class: 0x00007fb1f992bff0 [3LM    ] T_CLASS Test::Unit::Worker
  self: 0x00007fb1fae3b6c0 [3LM    ] T_OBJECT (Test::Unit::Worker)len:28 ptr:0x0000562e9081a460
  lvars:
    suite: 0x00007fb1fae87458 [3LM    ] T_CLASS TestWeakMap
    type: T_SYMBOL test
    orig_testout: 0x00007fb1fd8a93f8 [0LM  U ] T_FILE (IO)
    i: 0x00007fb1fadb31a8 [0 M  U ] T_FILE (IO)
    o: 0x00007fb1fadb3180 [0LM  U ] T_FILE (IO)
    orig_stdin: 0x00007fb1fd8a9448 [0LM  U ] T_FILE (IO)
    orig_stdout: 0x00007fb1fd8a93f8 [0LM  U ] T_FILE (IO)
    th: 0x00007fb1fadb3130 [0 M  U ] VM/thread (Thread)VM/thread
    e: T_FIXNUM 0
    f: T_FIXNUM 0
    s: T_FIXNUM 5
    result: T_NIL
c:0006 p:0007 s:0030 e:000029 BLOCK  /tmp/ruby/v3/src/trunk/tool/lib/test/unit/parallel.rb:30 [FINISH]
  me:
    called_id: _run_suites, type: iseq
    owner class: 0x00007fb1f992bff0 [3LM    ] T_CLASS Test::Unit::Worker
  self: 0x00007fb1fae3b6c0 [3LM    ] T_OBJECT (Test::Unit::Worker)len:28 ptr:0x0000562e9081a460
  lvars:
    suite: 0x00007fb1fae87458 [3LM    ] T_CLASS TestWeakMap
c:0005 p:---- s:0026 e:000025 CFUNC  :map
  me:
    called_id: map, type: cfunc
    owner class: 0x00007fb1fb801560 [3LM    ] T_CLASS Array
  self: 0x00007fb1fadb3270 [2 M    ] T_ARRAY (Array)[E ] len: 1 (embed)
c:0004 p:0005 s:0022 e:000021 METHOD /tmp/ruby/v3/src/trunk/tool/lib/test/unit/parallel.rb:29
  me:
    called_id: _run_suites, type: iseq
    owner class: 0x00007fb1f992bff0 [3LM    ] T_CLASS Test::Unit::Worker
  self: 0x00007fb1fae3b6c0 [3LM    ] T_OBJECT (Test::Unit::Worker)len:28 ptr:0x0000562e9081a460
  lvars:
    suites: 0x00007fb1fadb3270 [2 M    ] T_ARRAY (Array)[E ] len: 1 (embed)
    type: T_SYMBOL test
c:0003 p:0260 s:0016 e:000015 METHOD /tmp/ruby/v3/src/trunk/tool/lib/test/unit/parallel.rb:128
  me:
    called_id: run, type: iseq
    owner class: 0x00007fb1f992bff0 [3LM    ] T_CLASS Test::Unit::Worker
  self: 0x00007fb1fae3b6c0 [3LM    ] T_OBJECT (Test::Unit::Worker)len:28 ptr:0x0000562e9081a460
  lvars:
    args: 0x00007fb1fd8a8908 [3LM    ] T_ARRAY [E ] len: 0 (embed)
    buf: 0x00007fb1fae885d8 [3LM    ] T_STRING (String) len: 58, capa: 135 "run /tmp/ruby/v3/src/trunk/test/ruby/test_weakmap.rb test
"
    suites: 0x00007fb1fadb6060 [2 M    ] T_ARRAY (Array)[   ] len: 79, capa:79 ptr:0x0000562e91e5b7f0
    e: T_NIL
    trace: T_NIL
    err: T_NIL
c:0002 p:0127 s:0006 e:000005 EVAL   /tmp/ruby/v3/src/trunk/tool/lib/test/unit/parallel.rb:211 [FINISH]
  self: 0x00007fb1fd89cdb0 [3LM    ] T_OBJECT (embed) len:2
c:0001 p:0000 s:0003 E:000f50 (none) [FINISH]
  self: 0x00007fb1fd89cdb0 [3LM    ] T_OBJECT (embed) len:2

-- Ruby level backtrace information ----------------------------------------
/tmp/ruby/v3/src/trunk/tool/lib/test/unit/parallel.rb:211:in `<main>'
/tmp/ruby/v3/src/trunk/tool/lib/test/unit/parallel.rb:128:in `run'
/tmp/ruby/v3/src/trunk/tool/lib/test/unit/parallel.rb:29:in `_run_suites'
/tmp/ruby/v3/src/trunk/tool/lib/test/unit/parallel.rb:29:in `map'
/tmp/ruby/v3/src/trunk/tool/lib/test/unit/parallel.rb:30:in `block in _run_suites'
/tmp/ruby/v3/src/trunk/tool/lib/test/unit/parallel.rb:58:in `_run_suite'
/tmp/ruby/v3/src/trunk/tool/lib/test/unit.rb:1343:in `_run_suite'
/tmp/ruby/v3/src/trunk/tool/lib/test/unit.rb:1550:in `_run_suite'
/tmp/ruby/v3/src/trunk/tool/lib/test/unit.rb:1550:in `map'
/tmp/ruby/v3/src/trunk/tool/lib/test/unit.rb:1563:in `block in _run_suite'
/tmp/ruby/v3/src/trunk/tool/lib/test/unit/testcase.rb:168:in `run'
/tmp/ruby/v3/src/trunk/tool/lib/test/unit/testcase.rb:200:in `run_test'
/tmp/ruby/v3/src/trunk/test/ruby/test_weakmap.rb:77:in `test_inspect_garbage'
/tmp/ruby/v3/src/trunk/test/ruby/test_weakmap.rb:77:in `times'
/tmp/ruby/v3/src/trunk/test/ruby/test_weakmap.rb:79:in `block in test_inspect_garbage'
/tmp/ruby/v3/src/trunk/test/ruby/test_weakmap.rb:79:in `inspect'

-- Machine register context ------------------------------------------------
 RIP: 0x00007fb1fe379b1b RBP: 0x0000000000000034 RSP: 0x00007ffc2f67a560
 RAX: 0x0000000000000000 RBX: 0x0000562e9207f680 RCX: 0x0000562e903ec010
 RDX: 0x00007ffc2f67a5b0 RDI: 0x0000000000000034 RSI: 0x0000000000000f11
  R8: 0x000000000000000c  R9: 0x0000562e91d1e0f0 R10: 0x00007fb1f8920020
 R11: 0x0000562e90a39ec0 R12: 0x0000000000000034 R13: 0x00007ffc2f67a5b0
 R14: 0x0000562e903ec010 R15: 0x0000000000000f11 EFL: 0x0000000000010206

-- C level backtrace information -------------------------------------------
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(rb_print_backtrace+0x11) [0x7fb1fe418624] /tmp/ruby/v3/src/trunk/vm_dump.c:762
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(rb_vm_bugreport) /tmp/ruby/v3/src/trunk/vm_dump.c:1057
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(rb_bug_for_fatal_signal+0xf4) [0x7fb1fe213694] /tmp/ruby/v3/src/trunk/error.c:822
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(sigsegv+0x4d) [0x7fb1fe36e5fd] /tmp/ruby/v3/src/trunk/signal.c:964
/lib/x86_64-linux-gnu/libpthread.so.0(__restore_rt+0x0) [0x7fb1fdee8420] ../sysdeps/pthread/funlockfile.c:28
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(do_hash+0x0) [0x7fb1fe379b1b] /tmp/ruby/v3/src/trunk/st.c:1010
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(rb_st_lookup) /tmp/ruby/v3/src/trunk/st.c:1012
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(classname+0x28) [0x7fb1fe3dd8ed] /tmp/ruby/v3/src/trunk/variable.c:122
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(rb_tmp_class_path) /tmp/ruby/v3/src/trunk/variable.c:168
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(rb_class_path) /tmp/ruby/v3/src/trunk/variable.c:192
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(rb_any_to_s+0x4d) [0x7fb1fe2d306d] /tmp/ruby/v3/src/trunk/object.c:595
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(wmap_inspect_append+0xa9) [0x7fb1fe230dc9] /tmp/ruby/v3/src/trunk/gc.c:12793
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(wmap_inspect_i+0x97) [0x7fb1fe230f67] /tmp/ruby/v3/src/trunk/gc.c:12817
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(apply_functor+0x13) [0x7fb1fe37b636] /tmp/ruby/v3/src/trunk/st.c:1569
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(st_general_foreach) /tmp/ruby/v3/src/trunk/st.c:1479
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(rb_st_foreach) /tmp/ruby/v3/src/trunk/st.c:1576
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(RB_FL_TEST_RAW+0x0) [0x7fb1fe22d6ff] /tmp/ruby/v3/src/trunk/gc.c:12835
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(rbimpl_rstring_getmem) /tmp/ruby/v3/src/trunk/include/ruby/internal/fl_type.h:552
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(RSTRING_PTR) /tmp/ruby/v3/src/trunk/include/ruby/internal/core/rstring.h:500
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(wmap_inspect) /tmp/ruby/v3/src/trunk/gc.c:12837
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(vm_call_cfunc_with_frame+0x128) [0x7fb1fe3ef4b8] /tmp/ruby/v3/src/trunk/vm_insnhelper.c:3034
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(vm_sendish+0x10) [0x7fb1fe3fdc62] /tmp/ruby/v3/src/trunk/vm_insnhelper.c:4758
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(vm_exec_core) ../../src/trunk/insns.def:778
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(rb_vm_exec+0x1a4) [0x7fb1fe403934] /tmp/ruby/v3/src/trunk/vm.c:2291
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(rb_yield_1+0x2e7) [0x7fb1fe407d67] /tmp/ruby/v3/src/trunk/vm.c:1319
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(int_dotimes+0x9c) [0x7fb1fe2c757c] /tmp/ruby/v3/src/trunk/numeric.c:5697
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(vm_call_cfunc_with_frame+0x128) [0x7fb1fe3ef4b8] /tmp/ruby/v3/src/trunk/vm_insnhelper.c:3034
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(vm_sendish+0xe) [0x7fb1fe3fdd73] /tmp/ruby/v3/src/trunk/vm_insnhelper.c:4758
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(vm_exec_core) ../../src/trunk/insns.def:759
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(rb_vm_exec+0x1a4) [0x7fb1fe403934] /tmp/ruby/v3/src/trunk/vm.c:2291
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(rb_yield+0x266) [0x7fb1fe408d56] /tmp/ruby/v3/src/trunk/vm.c:1319
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(rb_ary_collect+0x5c) [0x7fb1fe17fd8c] /tmp/ruby/v3/src/trunk/array.c:3802
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(vm_call_cfunc_with_frame+0x128) [0x7fb1fe3ef4b8] /tmp/ruby/v3/src/trunk/vm_insnhelper.c:3034
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(vm_sendish+0xe) [0x7fb1fe3fdd73] /tmp/ruby/v3/src/trunk/vm_insnhelper.c:4758
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(vm_exec_core) ../../src/trunk/insns.def:759
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(rb_vm_exec+0x1a4) [0x7fb1fe403934] /tmp/ruby/v3/src/trunk/vm.c:2291
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(rb_yield+0x266) [0x7fb1fe408d56] /tmp/ruby/v3/src/trunk/vm.c:1319
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(rb_ary_collect+0x5c) [0x7fb1fe17fd8c] /tmp/ruby/v3/src/trunk/array.c:3802
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(vm_call_cfunc_with_frame+0x128) [0x7fb1fe3ef4b8] /tmp/ruby/v3/src/trunk/vm_insnhelper.c:3034
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(vm_sendish+0xe) [0x7fb1fe3fdd73] /tmp/ruby/v3/src/trunk/vm_insnhelper.c:4758
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(vm_exec_core) ../../src/trunk/insns.def:759
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(rb_vm_exec+0xa45) [0x7fb1fe4041d5] /tmp/ruby/v3/src/trunk/vm.c:2300
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(rb_ec_exec_node+0xbb) [0x7fb1fe21822b] /tmp/ruby/v3/src/trunk/eval.c:280
/tmp/ruby/v3/build/trunk/libruby.so.3.2.0(ruby_run_node+0x5a) [0x7fb1fe21e87a] /tmp/ruby/v3/src/trunk/eval.c:321
/tmp/ruby/v3/build/trunk/ruby(rb_main+0x21) [0x562e8e9381db] /tmp/ruby/v3/src/trunk/main.c:38
/tmp/ruby/v3/build/trunk/ruby(main) /tmp/ruby/v3/src/trunk/main.c:57
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf3) [0x7fb1fdd06083] ../csu/libc-start.c:308
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main) (null):0
[0x562e8e93822e]
Actions #1

Updated by peterzhu2118 (Peter Zhu) almost 2 years ago

  • Status changed from Open to Closed

Applied in changeset git|86d061294d3cc1656e18d0e1fd4b4f290da16944.


[Bug #18928] Fix crash in WeakMap

In wmap_live_p, if is_pointer_to_heap returns false, then the page is
either in the tomb or has already been freed, so the object is dead. In
this case, wmap_live_p should return false.

Actions #2

Updated by peterzhu2118 (Peter Zhu) almost 2 years ago

  • Backport changed from 2.7: DONTNEED, 3.0: DONTNEED, 3.1: REQUIRED to 2.7: REQUIRED, 3.0: REQUIRED, 3.1: REQUIRED

Updated by nagachika (Tomoyuki Chikanaga) almost 2 years ago

  • Backport changed from 2.7: REQUIRED, 3.0: REQUIRED, 3.1: REQUIRED to 2.7: REQUIRED, 3.0: REQUIRED, 3.1: DONE

ruby_3_1 c356c31f77b2d7c7c7f40f5b19dbb0961ea5f803 merged revision(s) 86d061294d3cc1656e18d0e1fd4b4f290da16944.

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0