summaryrefslogtreecommitdiffhomepage
path: root/src/gc.c
diff options
context:
space:
mode:
authorKouhei Sutou <[email protected]>2016-03-06 11:58:54 +0900
committerKouhei Sutou <[email protected]>2016-03-06 11:58:54 +0900
commitf1eb3aea114cbd1e2622cbe9618571f3e1eec115 (patch)
tree1eb3d36738e3c0fe87366347ab6004d01d22abf7 /src/gc.c
parentd77c72dac5b46dacc8332bca73a8398ae2cf9a78 (diff)
downloadmruby-f1eb3aea114cbd1e2622cbe9618571f3e1eec115.tar.gz
mruby-f1eb3aea114cbd1e2622cbe9618571f3e1eec115.zip
Fix segmentation fault by backtrace and GC
GitHub: fix #3122 It reverts #3126. #3126 fixes the segmentation fault but generates broken backtrace. This change fixes the segmentation fault and generates correct backtrace. The strategy of this change is "generating backtrace while irep is alive". /tmp/test.rb: def gen e0 = nil begin 1.times { raise 'foobar' } rescue => e e0 = e end e0 end e = gen GC.start gen GC.start puts e.backtrace.join("\n") Run: % bin/mruby /tmp/test.rb /tmp/test.rb:5:in Object.gen /home/kou/work/ruby/mruby.kou/mrblib/numeric.rb:77:in Integral#times /tmp/test.rb:4:in Object.gen /tmp/test.rb:13 FYI: % ruby -v /tmp/test.rb ruby 2.3.0p0 (2015-12-25) [x86_64-linux-gnu] /tmp/test.rb:5:in `block in gen' /tmp/test.rb:4:in `times' /tmp/test.rb:4:in `gen' /tmp/test.rb:13:in `<main>'
Diffstat (limited to 'src/gc.c')
-rw-r--r--src/gc.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/src/gc.c b/src/gc.c
index b23e4869e..e7948e4f5 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -695,8 +695,13 @@ obj_free(mrb_state *mrb, struct RBasic *obj)
#endif
case MRB_TT_OBJECT:
+ mrb_gc_free_iv(mrb, (struct RObject*)obj);
+ break;
+
case MRB_TT_EXCEPTION:
mrb_gc_free_iv(mrb, (struct RObject*)obj);
+ if ((struct RObject*)obj == mrb->backtrace.exc)
+ mrb->backtrace.exc = 0;
break;
case MRB_TT_CLASS: