Skip to content

Commit 34e36a7

Browse files
committed
Ensure global variable traces are freed at exit
ASAN_OPTIONS="detect_leaks=1" RUBY_FREE_AT_EXIT=1 ./miniruby -e 'trace_var(:$x){}'
1 parent a8ebc59 commit 34e36a7

File tree

1 file changed

+18
-12
lines changed

1 file changed

+18
-12
lines changed

variable.c

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -453,15 +453,27 @@ struct rb_global_entry {
453453
bool ractor_local;
454454
};
455455

456+
static void
457+
free_global_variable(struct rb_global_variable *var)
458+
{
459+
RUBY_ASSERT(var->counter == 0);
460+
461+
struct trace_var *trace = var->trace;
462+
while (trace) {
463+
struct trace_var *next = trace->next;
464+
xfree(trace);
465+
trace = next;
466+
}
467+
xfree(var);
468+
}
469+
456470
static enum rb_id_table_iterator_result
457471
free_global_entry_i(VALUE val, void *arg)
458472
{
459473
struct rb_global_entry *entry = (struct rb_global_entry *)val;
460-
if (entry->var->counter == 1) {
461-
ruby_xfree(entry->var);
462-
}
463-
else {
464-
entry->var->counter--;
474+
entry->var->counter--;
475+
if (entry->var->counter == 0) {
476+
free_global_variable(entry->var);
465477
}
466478
ruby_xfree(entry);
467479
return ID_TABLE_DELETE;
@@ -1007,13 +1019,7 @@ rb_alias_variable(ID name1, ID name2)
10071019
}
10081020
var->counter--;
10091021
if (var->counter == 0) {
1010-
struct trace_var *trace = var->trace;
1011-
while (trace) {
1012-
struct trace_var *next = trace->next;
1013-
xfree(trace);
1014-
trace = next;
1015-
}
1016-
xfree(var);
1022+
free_global_variable(var);
10171023
}
10181024
}
10191025
else {

0 commit comments

Comments
 (0)