From: merch-redmine@... Date: 2017-02-03T05:48:30+00:00 Subject: [ruby-core:79404] [Ruby trunk Bug#13176] Segfault during exception raising because rb_thread_t.errinfo is set to IMEMO object Issue #13176 has been updated by Jeremy Evans. `Timeout.timeout` doesn't appear to be called directly, though I didn't audit all code involved. The problematic code uses `rb_ensure` and inside the ensure function it uses `rb_exc_raise`: https://github.com/jeremyevans/sequel_pg/blob/1.6.17/ext/sequel_pg/sequel_pg.c#L1004 I tried to build an example with a simple C extension that didn't use Sequel, but unfortunately I was not able to get it to crash. ---------------------------------------- Bug #13176: Segfault during exception raising because rb_thread_t.errinfo is set to IMEMO object https://bugs.ruby-lang.org/issues/13176#change-62836 * Author: Jeremy Evans * Status: Feedback * Priority: Normal * Assignee: * Target version: * ruby -v: ruby 2.4.0p0 (2016-12-24 revision 57164) [x86_64-openbsd] * Backport: 2.2: DONTNEED, 2.3: DONTNEED, 2.4: REQUIRED ---------------------------------------- There appears to be a problem in ruby 2.4.0 and ruby 2.5.0dev (ruby 2.5.0dev (2017-01-31 trunk 57485) [x86_64-openbsd]) where rb_thread_t.errinfo gets set to an IMEMO object, and later used as the cause of an exception, which blows up when the exception is raised. First, the gdb backtrace: ~~~ Program received signal SIGSEGV, Segmentation fault at 0x00000000000018 0x000016413f931995 in iv_index_tbl_make (obj=24471839573840) at variable.c:1324 #1 0x000016413f931a8c in generic_ivar_set (obj=24471839573840, id=7585, val=8) at variable.c:1353 #2 0x000016413f931e48 in rb_ivar_set (obj=24471839573840, id=7585, val=8) at variable.c:1414 #3 0x000016413f7dd5b0 in exc_setup_cause (exc=24471839573760, cause=24471839573840) at eval.c:461 #4 0x000016413f7dd6e0 in setup_exception (th=0x1642049f9000, tag=6, mesg=24471839573760, cause=52) at eval.c:497 #5 0x000016413f7dddf6 in rb_longjmp (tag=6, mesg=24471839573760, cause=52) at eval.c:601 #6 0x000016413f7dde4d in rb_exc_raise (mesg=Could not find the frame base for "rb_exc_raise".) at eval.c:614 #7 0x00001641186c619d in spg__flush_results (rconn=24469332626760) at sequel_pg.c:1004 #8 0x000016413f7deb1e in rb_ensure (b_proc=0x1641186c5d3d , data1=24471839574280, e_proc=0x1641186c60d1 , data2=24469332626760) at eval.c:931 #9 0x00001641186c61e9 in spg_yield_each_row (self=24471839576040, rconn=24469332626760) at sequel_pg.c:1013 #10 0x000016413f93add6 in call_cfunc_1 (func=0x1641186c61a3 , recv=24471839576040, argc=1, argv=0x16416eb3e890) at vm_insnhelper.c:1585 #11 0x000016413f93b8cd in vm_call_cfunc_with_frame (th=0x1642049f9000, reg_cfp=0x16416ec3d670, calling=0x7f7ffffd8190, ci=0x1641e10f1aa0, cc=0x16411eb2d980) at vm_insnhelper.c:1752 #12 0x000016413f93bb14 in vm_call_cfunc (th=0x1642049f9000, reg_cfp=0x16416ec3d670, calling=0x7f7ffffd8190, ci=0x1641e10f1aa0, cc=0x16411eb2d980) at vm_insnhelper.c:1847 #13 0x000016413f9416b1 in vm_exec_core (th=0x1642049f9000, initial=0) at insns.def:967 #14 0x000016413f9549f4 in vm_exec (th=0x1642049f9000) at vm.c:1712 #15 0x000016413f9528ef in invoke_bmethod (th=0x1642049f9000, iseq=0x1641bbe3cde0, self=24472494004560, captured=0x164123905c80, me=0x16413ee55bd8, type=2576941057, opt_pc=0) at vm.c:988 #16 0x000016413f952cbb in invoke_iseq_block_from_c (th=0x1642049f9000, captured=0x164123905c80, self=24472494004560, argc=0, argv=0x7f7ffffd9080, passed_block_handler=0, cref=0x0, splattable=0, is_lambda=1) at vm.c:1017 #17 0x000016413f953042 in invoke_block_from_c_unsplattable (th=0x1642049f9000, block=0x164123905c80, self=24472494004560, argc=0, argv=0x7f7ffffd9080, passed_block_handler=0, is_lambda=1) at vm.c:1086 #18 0x000016413f953120 in vm_invoke_bmethod (th=0x1642049f9000, proc=0x164123905c80, self=24472494004560, argc=0, argv=0x7f7ffffd9080, block_handler=0) at vm.c:1127 #19 0x000016413f93c3da in vm_call_bmethod_body (th=0x1642049f9000, calling=0x7f7ffffd95f0, ci=0x7f7ffffd9280, cc=0x7f7ffffd9250, argv=0x7f7ffffd9080) at vm_insnhelper.c:1875 #20 0x000016413f93c345 in vm_call_bmethod (th=0x1642049f9000, cfp=0x16416ec3da90, calling=0x7f7ffffd95f0, ci=0x7f7ffffd9280, cc=0x7f7ffffd9250) at vm_insnhelper.c:1892 #21 0x000016413f93d238 in vm_call_method_each_type (th=0x1642049f9000, cfp=0x16416ec3da90, calling=0x7f7ffffd95f0, ci=0x7f7ffffd9280, cc=0x7f7ffffd9250) at vm_insnhelper.c:2168 #22 0x000016413f93d6d4 in vm_call_method (th=0x1642049f9000, cfp=0x16416ec3da90, calling=0x7f7ffffd95f0, ci=0x7f7ffffd9280, cc=0x7f7ffffd9250) at vm_insnhelper.c:2265 #23 0x000016413f93c7de in vm_call_opt_send (th=0x1642049f9000, reg_cfp=0x16416ec3da90, calling=0x7f7ffffd95f0, orig_ci=0x16411f36cf40, orig_cc=0x164203e784a0) at vm_insnhelper.c:1961 #24 0x000016413f93d2c9 in vm_call_method_each_type (th=0x1642049f9000, cfp=0x16416ec3da90, calling=0x7f7ffffd95f0, ci=0x16411f36cf40, cc=0x164203e784a0) at vm_insnhelper.c:2179 #25 0x000016413f93d6d4 in vm_call_method (th=0x1642049f9000, cfp=0x16416ec3da90, calling=0x7f7ffffd95f0, ci=0x16411f36cf40, cc=0x164203e784a0) at vm_insnhelper.c:2265 #26 0x000016413f93d8c8 in vm_call_general (th=0x1642049f9000, reg_cfp=0x16416ec3da90, calling=0x7f7ffffd95f0, ci=0x16411f36cf40, cc=0x164203e784a0) at vm_insnhelper.c:2308 #27 0x000016413f942195 in vm_exec_core (th=0x1642049f9000, initial=0) at insns.def:1066 #28 0x000016413f9549f4 in vm_exec (th=0x1642049f9000) at vm.c:1712 #29 0x000016413f952da1 in invoke_block (th=0x1642049f9000, iseq=0x16412dd7bae8, self=24469332631680, captured=0x16416ec3dda8, cref=0x0, type=572653569, opt_pc=0) at vm.c:969 #30 0x000016413f952c80 in invoke_iseq_block_from_c (th=0x1642049f9000, captured=0x16416ec3dda8, self=24469332631680, argc=1, argv=0x7f7ffffda498, passed_block_handler=0, cref=0x0, splattable=1, is_lambda=0) at vm.c:1014 #31 0x000016413f952a94 in invoke_block_from_c_splattable (th=0x1642049f9000, block_handler=24470287015337, argc=1, argv=0x7f7ffffda498, passed_block_handler=0, cref=0x0) at vm.c:1032 #32 0x000016413f952de3 in vm_yield (th=0x1642049f9000, argc=1, argv=0x7f7ffffda498) at vm.c:1069 #33 0x000016413f94e877 in rb_yield_0 (argc=1, argv=0x7f7ffffda498) at vm_eval.c:1009 #34 0x000016413f94e850 in rb_yield_1 (val=24472494007280) at vm_eval.c:1015 #35 0x000016413f94e8aa in rb_yield (val=24472494007280) at vm_eval.c:1025 #36 0x000016413f77689a in rb_ary_each (ary=24472494006960) at array.c:1824 #37 0x000016413f93ada7 in call_cfunc_0 (func=0x16413f77682b , recv=24472494006960, argc=0, argv=0x16416eb3e258) at vm_insnhelper.c:1579 #38 0x000016413f93b8cd in vm_call_cfunc_with_frame (th=0x1642049f9000, reg_cfp=0x16416ec3dd90, calling=0x7f7ffffda950, ci=0x16413e9fa160, cc=0x16418ddfd200) at vm_insnhelper.c:1752 #39 0x000016413f93bb14 in vm_call_cfunc (th=0x1642049f9000, reg_cfp=0x16416ec3dd90, calling=0x7f7ffffda950, ci=0x16413e9fa160, cc=0x16418ddfd200) at vm_insnhelper.c:1847 #40 0x000016413f93d043 in vm_call_method_each_type (th=0x1642049f9000, cfp=0x16416ec3dd90, calling=0x7f7ffffda950, ci=0x16413e9fa160, cc=0x16418ddfd200) at vm_insnhelper.c:2145 #41 0x000016413f93d6d4 in vm_call_method (th=0x1642049f9000, cfp=0x16416ec3dd90, calling=0x7f7ffffda950, ci=0x16413e9fa160, cc=0x16418ddfd200) at vm_insnhelper.c:2265 #42 0x000016413f93d8c8 in vm_call_general (th=0x1642049f9000, reg_cfp=0x16416ec3dd90, calling=0x7f7ffffda950, ci=0x16413e9fa160, cc=0x16418ddfd200) at vm_insnhelper.c:2308 #43 0x000016413f9416b1 in vm_exec_core (th=0x1642049f9000, initial=0) at insns.def:967 #44 0x000016413f9549f4 in vm_exec (th=0x1642049f9000) at vm.c:1712 #45 0x000016413f952da1 in invoke_block (th=0x1642049f9000, iseq=0x1641267ba7f0, self=24469584412240, captured=0x16416ec3df58, cref=0x0, type=572653569, opt_pc=0) at vm.c:969 #46 0x000016413f952c80 in invoke_iseq_block_from_c (th=0x1642049f9000, captured=0x16416ec3df58, self=24469584412240, argc=1, argv=0x7f7ffffdb7f8, passed_block_handler=0, cref=0x0, splattable=1, is_lambda=0) at vm.c:1014 #47 0x000016413f952a94 in invoke_block_from_c_splattable (th=0x1642049f9000, block_handler=24470287015769, argc=1, argv=0x7f7ffffdb7f8, passed_block_handler=0, cref=0x0) at vm.c:1032 #48 0x000016413f952de3 in vm_yield (th=0x1642049f9000, argc=1, argv=0x7f7ffffdb7f8) at vm.c:1069 #49 0x000016413f94e877 in rb_yield_0 (argc=1, argv=0x7f7ffffdb7f8) at vm_eval.c:1009 #50 0x000016413f94e850 in rb_yield_1 (val=24469332631680) at vm_eval.c:1015 #51 0x000016413f94e8aa in rb_yield (val=24469332631680) at vm_eval.c:1025 #52 0x000016413f778a56 in rb_ary_collect (ary=24472494010520) at array.c:2733 #53 0x000016413f93ada7 in call_cfunc_0 (func=0x16413f7789d2 , recv=24472494010520, argc=0, argv=0x16416eb3e0c0) at vm_insnhelper.c:1579 #54 0x000016413f93b8cd in vm_call_cfunc_with_frame (th=0x1642049f9000, reg_cfp=0x16416ec3df40, calling=0x7f7ffffdbcc0, ci=0x1641894147c0, cc=0x164144950aa0) at vm_insnhelper.c:1752 #55 0x000016413f93bb14 in vm_call_cfunc (th=0x1642049f9000, reg_cfp=0x16416ec3df40, calling=0x7f7ffffdbcc0, ci=0x1641894147c0, cc=0x164144950aa0) at vm_insnhelper.c:1847 #56 0x000016413f93d043 in vm_call_method_each_type (th=0x1642049f9000, cfp=0x16416ec3df40, calling=0x7f7ffffdbcc0, ci=0x1641894147c0, cc=0x164144950aa0) at vm_insnhelper.c:2145 #57 0x000016413f93d6d4 in vm_call_method (th=0x1642049f9000, cfp=0x16416ec3df40, calling=0x7f7ffffdbcc0, ci=0x1641894147c0, cc=0x164144950aa0) at vm_insnhelper.c:2265 #58 0x000016413f93d8c8 in vm_call_general (th=0x1642049f9000, reg_cfp=0x16416ec3df40, calling=0x7f7ffffdbcc0, ci=0x1641894147c0, cc=0x164144950aa0) at vm_insnhelper.c:2308 #59 0x000016413f9416b1 in vm_exec_core (th=0x1642049f9000, initial=0) at insns.def:967 #60 0x000016413f9549f4 in vm_exec (th=0x1642049f9000) at vm.c:1712 #61 0x000016413f952da1 in invoke_block (th=0x1642049f9000, iseq=0x1641701a0910, self=24469584412240, captured=0x1641c68b4100, cref=0x0, type=572653569, opt_pc=0) at vm.c:969 #62 0x000016413f952c80 in invoke_iseq_block_from_c (th=0x1642049f9000, captured=0x1641c68b4100, self=24469584412240, argc=0, argv=0x16413ee545b8, passed_block_handler=0, cref=0x0, splattable=0, is_lambda=0) at vm.c:1014 #63 0x000016413f953042 in invoke_block_from_c_unsplattable (th=0x1642049f9000, block=0x1641c68b4100, self=24469584412240, argc=0, argv=0x16413ee545b8, passed_block_handler=0, is_lambda=0) at vm.c:1086 #64 0x000016413f952f5a in vm_invoke_proc (th=0x1642049f9000, proc=0x1641c68b4100, self=24469584412240, argc=0, argv=0x16413ee545b8, passed_block_handler=0) at vm.c:1111 #65 0x000016413f9531b2 in rb_vm_invoke_proc (th=0x1642049f9000, proc=0x1641c68b4100, argc=0, argv=0x16413ee545b8, passed_block_handler=0) at vm.c:1141 #66 0x000016413f86f371 in rb_proc_call (self=24469463297920, args=24469483898280) at proc.c:847 #67 0x000016413f7dc592 in rb_call_end_proc (data=24469463297920) at eval_jump.c:13 #68 0x000016413f7dc744 in exec_end_procs_chain (procs=0x16413fc75d50, errp=0x1642049f90d8) at eval_jump.c:108 #69 0x000016413f7dc840 in rb_exec_end_proc () at eval_jump.c:125 #70 0x000016413f7dcc26 in ruby_finalize_0 () at eval.c:122 #71 0x000016413f7dcdb2 in ruby_cleanup (ex=0) at eval.c:179 #72 0x000016413f7dd1e4 in ruby_run_node (n=0x16410f990280) at eval.c:300 #73 0x0000163f0e700680 in main (argc=4, argv=0x7f7ffffdcff8) at main.c:36 ~~~ Some debugging in the core dump, showing that errinfo is getting set to an IMEMO object, which is later used as the cause of an exception: ~~~ #0 0x000016413f931995 in iv_index_tbl_make (obj=24471839573840) at variable.c:1324 1324 st_table *iv_index_tbl = RCLASS_IV_INDEX_TBL(klass); (gdb) info args obj = 24471839573840 (gdb) print rb_type(obj) $16 = 26 # RUBY_T_IMEMO ! (gdb) info locals klass = 0 iv_index_tbl = (st_table *) 0x34 (gdb) up #1 0x000016413f931a8c in generic_ivar_set (obj=24471839573840, id=7585, val=8) at variable.c:1353 1353 ivup.u.iv_index_tbl = iv_index_tbl_make(obj); (gdb) up #2 0x000016413f931e48 in rb_ivar_set (obj=24471839573840, id=7585, val=8) at variable.c:1414 1414 generic_ivar_set(obj, id, val); (gdb) up #3 0x000016413f7dd5b0 in exc_setup_cause (exc=24471839573760, cause=24471839573840) at eval.c:461 461 rb_ivar_set(cause, id_cause, Qnil); (gdb) up #4 0x000016413f7dd6e0 in setup_exception (th=0x1642049f9000, tag=6, mesg=24471839573760, cause=52) at eval.c:497 497 exc_setup_cause(mesg, get_thread_errinfo(th)); (gdb) print get_thread_errinfo(th) $17 = 24471839573840 (gdb) print th->errinfo $18 = 24471839573840 ~~~ The segfault ultimately happens because rb_obj_class on IMEMO objects is 0, and iv_index_tbl_make doesn't expect rb_obj_class to return 0. Unfortunately, I was not able to create a minimal example showing the problem. This is the simplest reproducible example I could create, which requires PostgreSQL and the sequel, sequel_pg, and pg gems: ~~~ require 'sequel' DB = Sequel.connect('postgres://sequel_test@localhost/sequel_test') # or similar PostgreSQL database connection string DB.extension(:pg_streaming) DB.stream_all_queries = true DB.drop_table?(:items, :items2) DB.create_table!(:items2){Integer :id, :primary_key=>true} DB.create_table!(:items){foreign_key :id, :items2, :deferrable=>true} DB[:items].insert(1) ~~~ This same code works (raises an exception, no segfault) from ruby 1.8.7 to 2.3. Only in ruby 2.4.0 and ruby 2.5.0dev does it segfault. -- https://bugs.ruby-lang.org/ Unsubscribe: