Skip to content

Commit fabb86d

Browse files
committed
erts: Fix SEGV when killing process during yielding re:run
Adjust pointer from pcre2_match_data to allocated RestartContext at first yield, don't wait until first trap call.
1 parent d9454db commit fabb86d

2 files changed

Lines changed: 27 additions & 1 deletion

File tree

erts/emulator/beam/erl_bif_re.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1477,6 +1477,7 @@ re_run(Process *p, Eterm arg1, Eterm arg2, Eterm arg3, int first)
14771477
Eterm *hp;
14781478
BUMP_REDS(p, reds_consumed);
14791479
sys_memcpy(restartp,&restart,sizeof(RestartContext));
1480+
pcre2_set_restart_data(restart.match_data, &restartp->restart_data);
14801481
ERTS_VBUMP_ALL_REDS(p);
14811482
hp = HAlloc(p, ERTS_MAGIC_REF_THING_SIZE);
14821483
magic_ref = erts_mk_magic_ref(&hp, &MSO(p), mbp);
@@ -1592,7 +1593,6 @@ static BIF_RETTYPE re_match_trap(BIF_ALIST_3)
15921593
restartp = (RestartContext *) ERTS_MAGIC_BIN_DATA(mbp);
15931594
loop_limit = MIN(reds_initial * LOOP_FACTOR, max_loop_limit);
15941595
pcre2_set_loops_left(restartp->match_data, loop_limit);
1595-
pcre2_set_restart_data(restartp->match_data, &restartp->restart_data);
15961596
pcre2_set_restart_flags(restartp->match_data, 0);
15971597

15981598
rc = pcre2_match(NULL, NULL, 0, 0, 0, restartp->match_data, NULL);

lib/stdlib/test/re_SUITE.erl

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
match_limit/1,sub_binaries/1,copt/1,global_unicode_validation/1,
3636
yield_on_subject_validation/1, bad_utf8_subject/1,
3737
error_info/1, subject_is_sub_binary/1, pattern_is_sub_binary/1,
38+
kill_yielding/1,
3839

3940
last_test/1]).
4041

@@ -58,6 +59,7 @@ all() ->
5859
match_limit, sub_binaries, re_version, global_unicode_validation,
5960
yield_on_subject_validation, bad_utf8_subject,
6061
error_info, subject_is_sub_binary, pattern_is_sub_binary,
62+
kill_yielding,
6163

6264
last_test].
6365

@@ -1163,6 +1165,30 @@ subject_is_sub_binary(Config) when is_list(Config) ->
11631165
ok
11641166
end.
11651167

1168+
%% OTP-19888: Verify that process can handle being killed while yielding
1169+
%% inside re:run without beam crash or memory leak.
1170+
kill_yielding(Config) when is_list(Config) ->
1171+
Subject = binary:copy(~"hejsan", 100_000),
1172+
DoIt = fun(RE) ->
1173+
{Pid, MRef} = spawn_monitor(fun() ->
1174+
re:run(Subject, RE)
1175+
end),
1176+
erlang:yield(),
1177+
exit(Pid, kill),
1178+
{'DOWN',MRef,process,Pid,killed} = receive_any()
1179+
end,
1180+
1181+
RE_string = ~B"\w+\d",
1182+
{ok, RE_compiled} = re:compile(RE_string, []),
1183+
DoIt(RE_string),
1184+
DoIt(RE_compiled),
1185+
ok.
1186+
1187+
receive_any() ->
1188+
receive M -> M
1189+
after 1000 -> timeout
1190+
end.
1191+
11661192
last_test(Config) when is_list(Config) ->
11671193
erts_debug:set_internal_state(available_internal_state, true),
11681194
Res = case erts_debug:get_internal_state(re_yield_coverage) of

0 commit comments

Comments
 (0)