diff options
Diffstat (limited to 'vm_insnhelper.c')
-rw-r--r-- | vm_insnhelper.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/vm_insnhelper.c b/vm_insnhelper.c index f82b0e075b..702e22291b 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -3900,3 +3900,38 @@ vm_trace(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, const VALUE *p } } } + +#if VM_CHECK_MODE > 0 +static NORETURN( NOINLINE( +#if GCC_VERSION_SINCE(4, 3, 0) +__attribute__((__cold__)) +#endif +void vm_canary_is_found_dead(enum ruby_vminsn_type i, VALUE c))); +static VALUE vm_stack_canary; + +void +Init_vm_stack_canary(void) +{ + /* This has to be called _after_ our PRNG is properly set up. */ + int n = fill_random_bytes(&vm_stack_canary, sizeof vm_stack_canary, false); + + VM_ASSERT(n == 0); +} + +static void +vm_canary_is_found_dead(enum ruby_vminsn_type i, VALUE c) +{ + /* Because a method has already been called, why not call + * another one. */ + const char *insn = rb_insns_name(i); + VALUE inspection = rb_inspect(c); + const char *str = StringValueCStr(inspection); + VALUE message = rb_sprintf("dead canary found at %s: %s", insn, str); + const char *msg = StringValueCStr(message); + + rb_bug(msg); +} + +#elif !defined(MJIT_HEADER) +void Init_vm_stack_canary(void) { /* nothing to do */ } +#endif |