summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-03-20 14:18:34 +0000
committernagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-03-20 14:18:34 +0000
commitab2e7357bd27b5139415bf823c2780bc8273eb83 (patch)
treec80cf0761541822ee3eef83f407b27044d854fbd
parentc0848eeda4bd60d9f8915993e31f6fa027f28c88 (diff)
merge revision(s) 61564,61565,61571: [Backport #14270]
fix SEGV touching uninitialized memory This function can be called from Init_VM(). No assumption can be made about object internals. (lldb) run Process 15734 launched: './miniruby' (x86_64) Process 15734 stopped * thread #1: tid = 0x1441d4, 0x00000001000bdfcb miniruby`rb_raw_iseq_info(buff="0x0000000100f61f48 [0 ] T_IMEMO iseq", buff_size=256, iseq=0x0000000100f61f48) + 27 at gc.c:9273, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x50) frame #0: 0x00000001000bdfcb miniruby`rb_raw_iseq_info(buff="0x0000000100f61f48 [0 ] T_IMEMO iseq", buff_size=256, iseq=0x0000000100f61f48) + 27 at gc.c:9273 9270 static void 9271 rb_raw_iseq_info(char *buff, const int buff_size, const rb_iseq_t *iseq) 9272 { -> 9273 if (iseq->body->location.label) { 9274 VALUE path = rb_iseq_path(iseq); 9275 snprintf(buff, buff_size, "%s %s@%s:%d", buff, 9276 RSTRING_PTR(iseq->body->location.label), (lldb) p *iseq (rb_iseq_t) $0 = { flags = 28698 reserved1 = 0 body = 0x0000000000000000 aux = { compile_data = 0x0000000000000000 loader = (obj = 0, index = 0) trace_events = 0 } } (lldb) bt * thread #1: tid = 0x1441d4, 0x00000001000bdfcb miniruby`rb_raw_iseq_info(buff="0x0000000100f61f48 [0 ] T_IMEMO iseq", buff_size=256, iseq=0x0000000100f61f48) + 27 at gc.c:9273, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x50) * frame #0: 0x00000001000bdfcb miniruby`rb_raw_iseq_info(buff="0x0000000100f61f48 [0 ] T_IMEMO iseq", buff_size=256, iseq=0x0000000100f61f48) + 27 at gc.c:9273 frame #1: 0x00000001000bde72 miniruby`rb_raw_obj_info(buff="0x0000000100f61f48 [0 ] T_IMEMO iseq", buff_size=256, obj=4311097160) + 2786 at gc.c:9396 frame #2: 0x00000001000b7c5f miniruby`obj_info(obj=4311097160) + 95 at gc.c:9428 frame #3: 0x00000001000c16a8 miniruby`newobj_init(klass=0, flags=28698, v1=0, v2=0, v3=0, wb_protected=1, objspace=0x00000001007ee280, obj=4311097160) + 424 at gc.c:1887 frame #4: 0x00000001000b44c9 miniruby`newobj_of(klass=0, flags=28698, v1=0, v2=0, v3=0, wb_protected=1) + 217 at gc.c:1970 frame #5: 0x00000001000b464b miniruby`rb_imemo_new(type=imemo_iseq, v1=0, v2=0, v3=0, v0=0) + 75 at gc.c:2017 frame #6: 0x00000001000fd914 miniruby`iseq_imemo_alloc + 36 at iseq.h:156 frame #7: 0x00000001000f6e1d miniruby`iseq_alloc + 13 at iseq.c:211 frame #8: 0x00000001000f6bf8 miniruby`rb_iseq_new_with_opt(node=0x0000000000000000, name=4311097200, path=4311097200, realpath=8, first_lineno=1, parent=0x0000000000000000, type=ISEQ_TYPE_TOP, option=0x0000000100335c30) + 56 at iseq.c:519 frame #9: 0x00000001000f6bb6 miniruby`rb_iseq_new(node=0x0000000000000000, name=4311097200, path=4311097200, realpath=8, parent=0x0000000000000000, type=ISEQ_TYPE_TOP) + 86 at iseq.c:480 frame #10: 0x0000000100284bb0 miniruby`Init_VM + 1040 at vm.c:3022 frame #11: 0x00000001000d4f7d miniruby`rb_call_inits + 189 at inits.c:55 frame #12: 0x000000010009fe06 miniruby`ruby_setup + 198 at eval.c:61 frame #13: 0x000000010009fe5d miniruby`ruby_init + 13 at eval.c:78 frame #14: 0x00000001000009ed miniruby`main(argc=2, argv=0x00007fff5fbfdbf0) + 93 at main.c:41 frame #15: 0x00007fff88eda5ad libdyld.dylib`start + 1 (lldb) fix SEGV touching uninitialized memory This function can be called from rb_data_typed_object_zalloc(). No assumption can be made about object internals. (lldb) run Process 22135 launched: './miniruby' (x86_64) Process 22135 stopped * thread #1: tid = 0x14a3af, 0x000000010008ac8a miniruby`vm_block_type(block=0x0000000000000000) + 12 at vm_core.h:1364, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x18) frame #0: 0x000000010008ac8a miniruby`vm_block_type(block=0x0000000000000000) + 12 at vm_core.h:1364 1361 break; 1362 } 1363 #endif -> 1364 return block->type; 1365 } 1366 1367 static inline void (lldb) bt * thread #1: tid = 0x14a3af, 0x000000010008ac8a miniruby`vm_block_type(block=0x0000000000000000) + 12 at vm_core.h:1364, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x18) * frame #0: 0x000000010008ac8a miniruby`vm_block_type(block=0x0000000000000000) + 12 at vm_core.h:1364 frame #1: 0x000000010008acdb miniruby`vm_block_iseq(block=0x0000000000000000) + 24 at vm_core.h:1399 frame #2: 0x000000010008acc1 miniruby`vm_proc_iseq(procval=4310866360) + 32 at vm_core.h:1387 frame #3: 0x000000010009cbed miniruby`rb_raw_obj_info(buff="0x0000000100f299b8 [0 ] proc (Proc)", buff_size=256, obj=4310866360) + 1513 at gc.c:9349 frame #4: 0x000000010009cf01 miniruby`obj_info(obj=4310866360) + 98 at gc.c:9428 frame #5: 0x000000010008ca1b miniruby`newobj_init(klass=4311027960, flags=12, v1=4298186080, v2=1, v3=0, wb_protected=32, objspace=0x00000001007cf280, obj=4310866360) + 338 at gc.c:1887 frame #6: 0x000000010008cce5 miniruby`newobj_of(klass=4311027960, flags=12, v1=4298186080, v2=1, v3=0, wb_protected=32) + 171 at gc.c:1970 frame #7: 0x000000010008d01d miniruby`rb_data_typed_object_wrap(klass=4311027960, datap=0x0000000000000000, type=0x0000000100311d60) + 133 at gc.c:2062 frame #8: 0x000000010008d04e miniruby`rb_data_typed_object_zalloc(klass=4311027960, size=40, type=0x0000000100311d60) + 42 at gc.c:2073 frame #9: 0x000000010011b459 miniruby`rb_proc_alloc(klass=4311027960) + 36 at proc.c:113 frame #10: 0x0000000100204d8e miniruby`vm_proc_create_from_captured(klass=4311027960, captured=0x00000001025003f8, block_type=block_type_iseq, is_from_method='\0', is_lambda='\x01') + 44 at vm.c:814 frame #11: 0x00000001002050d8 miniruby`rb_vm_make_proc_lambda(ec=0x00000001007cf548, captured=0x00000001025003f8, klass=4311027960, is_lambda='\x01') + 134 at vm.c:892 frame #12: 0x000000010011c0d2 miniruby`proc_new(klass=4311027960, is_lambda='\x01') + 445 at proc.c:752 frame #13: 0x000000010011c154 miniruby`rb_block_lambda + 27 at proc.c:808 frame #14: 0x00000001001ee7e3 miniruby`call_cfunc_0(func=(miniruby`rb_block_lambda at proc.c:807), recv=4310991600, argc=0, argv=0x0000000102400480) + 41 at vm_insnhelper.c:1729 frame #15: 0x00000001001ef2c3 miniruby`vm_call_cfunc_with_frame(ec=0x00000001007cf548, reg_cfp=0x00000001025003e0, calling=0x00007fff5fbfd4d0, ci=0x0000000102537be0, cc=0x000000010253e0f0) + 386 at vm_insnhelper.c:1918 frame #16: 0x00000001001ef412 miniruby`vm_call_cfunc(ec=0x00000001007cf548, reg_cfp=0x00000001025003e0, calling=0x00007fff5fbfd4d0, ci=0x0000000102537be0, cc=0x000000010253e0f0) + 149 at vm_insnhelper.c:1934 frame #17: 0x00000001001f0655 miniruby`vm_call_method_each_type(ec=0x00000001007cf548, cfp=0x00000001025003e0, calling=0x00007fff5fbfd4d0, ci=0x0000000102537be0, cc=0x000000010253e0f0) + 239 at vm_insnhelper.c:2232 frame #18: 0x00000001001f0ce0 miniruby`vm_call_method(ec=0x00000001007cf548, cfp=0x00000001025003e0, calling=0x00007fff5fbfd4d0, ci=0x0000000102537be0, cc=0x000000010253e0f0) + 117 at vm_insnhelper.c:2355 frame #19: 0x00000001001f0eb6 miniruby`vm_call_general(ec=0x00000001007cf548, reg_cfp=0x00000001025003e0, calling=0x00007fff5fbfd4d0, ci=0x0000000102537be0, cc=0x000000010253e0f0) + 59 at vm_insnhelper.c:2398 frame #20: 0x00000001001f6e61 miniruby`vm_exec_core(ec=0x00000001007cf548, initial=0) + 7480 at insns.def:850 frame #21: 0x0000000100207995 miniruby`vm_exec(ec=0x00000001007cf548) + 230 at vm.c:1771 frame #22: 0x0000000100208647 miniruby`rb_iseq_eval_main(iseq=0x0000000100f29fd0) + 52 at vm.c:2019 frame #23: 0x000000010007b750 miniruby`ruby_exec_internal(n=0x0000000100f29fd0) + 297 at eval.c:246 frame #24: 0x000000010007b876 miniruby`ruby_exec_node(n=0x0000000100f29fd0) + 36 at eval.c:310 frame #25: 0x000000010007b849 miniruby`ruby_run_node(n=0x0000000100f29fd0) + 62 at eval.c:302 frame #26: 0x0000000100000c05 miniruby`main(argc=2, argv=0x00007fff5fbfdbf0) + 113 at main.c:42 frame #27: 0x00007fff88eda5ad libdyld.dylib`start + 1 (lldb) check an existence of block. * gc.c (rb_raw_obj_info): check block before using it. * vm_core.h (vm_block_iseq): r61565 introduced NULL check but this check is only needed by `rb_raw_obj_info()` and it is called at GC debug mode. Above fix for `rb_raw_obj_info()` solves this problem and NULL check should not be needed any more. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_4@62864 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--gc.c11
-rw-r--r--version.h2
2 files changed, 9 insertions, 4 deletions
diff --git a/gc.c b/gc.c
index 987bea907f..21ad919575 100644
--- a/gc.c
+++ b/gc.c
@@ -9207,11 +9207,12 @@ method_type_name(rb_method_type_t type)
static void
rb_raw_iseq_info(char *buff, const int buff_size, const rb_iseq_t *iseq)
{
- if (iseq->body->location.label) {
+ if (iseq->body && iseq->body->location.label) {
+ VALUE n = iseq->body->location.first_lineno;
snprintf(buff, buff_size, "%s %s@%s:%d", buff,
RSTRING_PTR(iseq->body->location.label),
RSTRING_PTR(iseq->body->location.path),
- FIX2INT(iseq->body->location.first_lineno));
+ n ? FIX2INT(n) : 0 );
}
}
@@ -9282,8 +9283,12 @@ rb_raw_obj_info(char *buff, const int buff_size, VALUE obj)
break;
}
case T_DATA: {
+ const struct rb_block *block;
const rb_iseq_t *iseq;
- if (rb_obj_is_proc(obj) && (iseq = vm_proc_iseq(obj)) != NULL) {
+ if (rb_obj_is_proc(obj) &&
+ (block = vm_proc_block(obj)) != NULL &&
+ (vm_block_type(block) == block_type_iseq) &&
+ (iseq = vm_block_iseq(block)) != NULL) {
rb_raw_iseq_info(buff, buff_size, iseq);
}
else {
diff --git a/version.h b/version.h
index 4a96d5f229..83f6e0e555 100644
--- a/version.h
+++ b/version.h
@@ -1,6 +1,6 @@
#define RUBY_VERSION "2.4.4"
#define RUBY_RELEASE_DATE "2018-03-20"
-#define RUBY_PATCHLEVEL 272
+#define RUBY_PATCHLEVEL 273
#define RUBY_RELEASE_YEAR 2018
#define RUBY_RELEASE_MONTH 3