Skip to content

Commit

Permalink
merge revision(s) b8a3f1b:
Browse files Browse the repository at this point in the history
	Fix crash in tracing object allocations

	ObjectSpace.trace_object_allocations_start could crash since it adds a
	TracePoint for when objects are freed. However, TracePoint could crash
	since it modifies st tables while inside the GC that is trying to free
	the object. This could cause a memory allocation to happen which would
	crash if it triggers another GC.

	See a crash log: http://ci.rvm.jp/results/trunk@ruby-sp1/4373707
	---
	 ext/objspace/depend           | 1 +
	 ext/objspace/object_tracing.c | 7 +++++++
	 gc.h                          | 4 ++--
	 3 files changed, 10 insertions(+), 2 deletions(-)
  • Loading branch information
nagachika committed Jan 18, 2024
1 parent 3302e25 commit 99c9aee
Show file tree
Hide file tree
Showing 4 changed files with 11 additions and 3 deletions.
1 change: 1 addition & 0 deletions ext/objspace/depend
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ object_tracing.o: $(hdrdir)/ruby/missing.h
object_tracing.o: $(hdrdir)/ruby/ruby.h
object_tracing.o: $(hdrdir)/ruby/st.h
object_tracing.o: $(hdrdir)/ruby/subst.h
object_tracing.o: $(top_srcdir)/gc.h
object_tracing.o: $(top_srcdir)/internal.h
object_tracing.o: object_tracing.c
object_tracing.o: objspace.h
Expand Down
7 changes: 7 additions & 0 deletions ext/objspace/object_tracing.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
**********************************************************************/

#include "gc.h"
#include "internal.h"
#include "ruby/debug.h"
#include "objspace.h"
Expand Down Expand Up @@ -121,6 +122,10 @@ freeobj_i(VALUE tpval, void *data)
st_data_t v;
struct allocation_info *info;

/* Modifying the st table can cause allocations, which can trigger GC.
* Since freeobj_i is called during GC, it must not trigger another GC. */
VALUE gc_disabled = rb_gc_disable_no_rest();

if (arg->keep_remains) {
if (st_lookup(arg->object_table, obj, &v)) {
info = (struct allocation_info *)v;
Expand All @@ -135,6 +140,8 @@ freeobj_i(VALUE tpval, void *data)
ruby_xfree(info);
}
}

if (gc_disabled == Qfalse) rb_gc_enable();
}

static int
Expand Down
4 changes: 2 additions & 2 deletions gc.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,6 @@ int ruby_get_stack_grow_direction(volatile VALUE *addr);
const char *rb_obj_info(VALUE obj);
const char *rb_raw_obj_info(char *const buff, const size_t buff_size, VALUE obj);

VALUE rb_gc_disable_no_rest(void);

struct rb_thread_struct;

size_t rb_size_pool_slot_size(unsigned char pool_id);
Expand All @@ -142,6 +140,8 @@ void rb_objspace_each_objects_without_setup(

size_t rb_gc_obj_slot_size(VALUE obj);

VALUE rb_gc_disable_no_rest(void);

RUBY_SYMBOL_EXPORT_END

#endif /* RUBY_GC_H */
2 changes: 1 addition & 1 deletion version.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
#define RUBY_VERSION_TEENY 2
#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
#define RUBY_PATCHLEVEL 155
#define RUBY_PATCHLEVEL 156

#include "ruby/version.h"
#include "ruby/internal/abi.h"
Expand Down

0 comments on commit 99c9aee

Please sign in to comment.