Skip to content

Mark backtrace referenced by exception#2917

Closed
kou wants to merge 1 commit into
mruby:masterfrom
kou:gc-exception-mark
Closed

Mark backtrace referenced by exception#2917
kou wants to merge 1 commit into
mruby:masterfrom
kou:gc-exception-mark

Conversation

@kou
Copy link
Copy Markdown
Contributor

@kou kou commented Aug 17, 2015

The following code crashes without this change:

def a
  [1].each do
    [2].each do
      [3].each do
        raise "XXX"
      end
    end
  end
end

begin
  a
rescue => exception
  GC.start
  exception.backtrace
end

GDB backtrace:

Program received signal SIGSEGV, Segmentation fault.
strlen () at ../sysdeps/x86_64/strlen.S:106
106 ../sysdeps/x86_64/strlen.S: No such file or directory.
(gdb) bt
#0  strlen () at ../sysdeps/x86_64/strlen.S:106
#1  0x00000000004252cd in mrb_str_new_cstr (mrb=0x69f010,
    p=0x101 <error: Cannot access memory at address 0x101>)
    at mruby/src/string.c:290
#2  0x00000000004183fe in get_backtrace_i (mrb=0x69f010, loc=0x7fffffffd940,
    data=0x6a7410) at mruby/src/backtrace.c:72
#3  0x0000000000418793 in output_backtrace (mrb=0x69f010, ciidx=8,
    pc0=0x71940c, func=0x4183af <get_backtrace_i>, data=0x6a7410)
    at mruby/src/backtrace.c:140
#4  0x0000000000418862 in exc_output_backtrace (mrb=0x69f010, exc=0x6a5be0,
    func=0x4183af <get_backtrace_i>, stream=0x6a7410)
    at mruby/src/backtrace.c:157
#5  0x000000000041894c in mrb_exc_backtrace (mrb=0x69f010, self=...)
    at mruby/src/backtrace.c:199
#6  0x000000000040dbaf in mrb_context_run (mrb=0x69f010, proc=0x6a61b0,
    self=..., stack_keep=0) at mruby/src/vm.c:1126
#7  0x00000000004131d8 in mrb_toplevel_run_keep (mrb=0x69f010, proc=0x6a61b0,
    stack_keep=0) at mruby/src/vm.c:2422
#8  0x000000000043a46c in load_exec (mrb=0x69f010, p=0x6f6450, c=0x6c9320)
    at mruby/mrbgems/mruby-compiler/core/parse.y:5619
#9  0x000000000043a4e2 in mrb_load_file_cxt (mrb=0x69f010, f=0x6f61f0,
    c=0x6c9320)
    at mruby/mrbgems/mruby-compiler/core/parse.y:5628
#10 0x0000000000402466 in main (argc=2, argv=0x7fffffffe438)
    at mruby/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c:222

The following code crashes without this change:

    def a
      [1].each do
        [2].each do
          [3].each do
            raise "XXX"
          end
        end
      end
    end

    begin
      a
    rescue => exception
      GC.start
      exception.backtrace
    end

GDB backtrace:

    Program received signal SIGSEGV, Segmentation fault.
    strlen () at ../sysdeps/x86_64/strlen.S:106
    106	../sysdeps/x86_64/strlen.S: No such file or directory.
    (gdb) bt
    #0  strlen () at ../sysdeps/x86_64/strlen.S:106
    #1  0x00000000004252cd in mrb_str_new_cstr (mrb=0x69f010,
        p=0x101 <error: Cannot access memory at address 0x101>)
        at mruby/src/string.c:290
    #2  0x00000000004183fe in get_backtrace_i (mrb=0x69f010, loc=0x7fffffffd940,
        data=0x6a7410) at mruby/src/backtrace.c:72
    #3  0x0000000000418793 in output_backtrace (mrb=0x69f010, ciidx=8,
        pc0=0x71940c, func=0x4183af <get_backtrace_i>, data=0x6a7410)
        at mruby/src/backtrace.c:140
    #4  0x0000000000418862 in exc_output_backtrace (mrb=0x69f010, exc=0x6a5be0,
        func=0x4183af <get_backtrace_i>, stream=0x6a7410)
        at mruby/src/backtrace.c:157
    #5  0x000000000041894c in mrb_exc_backtrace (mrb=0x69f010, self=...)
        at mruby/src/backtrace.c:199
    #6  0x000000000040dbaf in mrb_context_run (mrb=0x69f010, proc=0x6a61b0,
        self=..., stack_keep=0) at mruby/src/vm.c:1126
    #7  0x00000000004131d8 in mrb_toplevel_run_keep (mrb=0x69f010, proc=0x6a61b0,
        stack_keep=0) at mruby/src/vm.c:2422
    #8  0x000000000043a46c in load_exec (mrb=0x69f010, p=0x6f6450, c=0x6c9320)
        at mruby/mrbgems/mruby-compiler/core/parse.y:5619
    #9  0x000000000043a4e2 in mrb_load_file_cxt (mrb=0x69f010, f=0x6f61f0,
        c=0x6c9320)
        at mruby/mrbgems/mruby-compiler/core/parse.y:5628
    #10 0x0000000000402466 in main (argc=2, argv=0x7fffffffe438)
        at mruby/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c:222
@tsahara
Copy link
Copy Markdown
Member

tsahara commented Aug 17, 2015

Exception#backtrace itself is broken (see #2902). We should repair or rework it first. Or, GC marks random objects on the stack with your patch.

kou added a commit to groonga/groonga that referenced this pull request Aug 17, 2015
Because Exception#backtrace may be crashed after GC. Backtrace isn't
marked.

See also: mruby/mruby#2917
kou added a commit to kou/mruby that referenced this pull request Dec 29, 2015
GitHub: fix mruby#2902, mruby#2917

The current implementation traverses stack to retrieve backtrace. But
stack will be changed when some operations are occurred. It means that
backtrace may be broken after some operations.

This change (1) saves the minimum information to retrieve backtrace when
exception is raised and (2) restores backtrace from the minimum
information when backtrace is needed. It reduces overhead for creating
backtrace Ruby objects.

The space for the minimum information is reused by multiple
exceptions. So memory allocation isn't occurred for each exception.
@matz
Copy link
Copy Markdown
Member

matz commented Dec 30, 2015

fixed by #3065

@matz matz closed this Dec 30, 2015
@kou kou deleted the gc-exception-mark branch December 30, 2015 02:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants