Skip to content

Commit

Permalink
Merge branch 'lukas/erts/fix-persistent-term-literal-tag/OTP-19458' i…
Browse files Browse the repository at this point in the history
…nto maint

* lukas/erts/fix-persistent-term-literal-tag/OTP-19458:
  erts: Mark error in erl.c as noreturn
  erts: Strengthen literal tag assert
  erts: Make sure to tag orig with literal ptr
  • Loading branch information
garazdawi committed Jan 29, 2025
2 parents 20a8fba + c3c2d0b commit e060f28
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 6 deletions.
11 changes: 8 additions & 3 deletions erts/emulator/beam/erl_term.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,14 @@ erts_set_literal_tag(Eterm *term, Eterm *hp_start, Eterm hsz)
*hp |= TAG_LITERAL_PTR;
break;
case TAG_PRIMARY_HEADER:
if (header_is_thing(*hp)) {
hp += thing_arityval(*hp);
}
if (*hp == HEADER_SUB_BITS) {
/* Tag the `orig` field as a literal. It's the last field
* inside the thing structure so we can handle it by pretending
* it's not part of the thing. */
hp += thing_arityval(*hp) - 1;
} else if (header_is_thing(*hp)) {
hp += thing_arityval(*hp);
}
break;
default:
break;
Expand Down
3 changes: 3 additions & 0 deletions erts/emulator/beam/global.h
Original file line number Diff line number Diff line change
Expand Up @@ -1564,6 +1564,9 @@ ERTS_GLB_FORCE_INLINE int erts_is_literal(Eterm tptr, Eterm *ptr)
ASSERT(ptr == ptr_val(tptr));

#if defined(ERTS_HAVE_IS_IN_LITERAL_RANGE)
#ifdef TAG_LITERAL_PTR
ASSERT(!erts_is_in_literal_range(ptr) || is_literal_ptr(tptr));
#endif
return erts_is_in_literal_range(ptr);
#elif defined(TAG_LITERAL_PTR)
return is_literal_ptr(tptr);
Expand Down
31 changes: 29 additions & 2 deletions erts/emulator/test/persistent_term_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@
whole_message/1,
shared_magic_ref/1,
non_message_signal/1,
get_put_colliding_bucket/1]).
get_put_colliding_bucket/1,
gc_binary_orig/1]).

%%
-export([test_init_restart_cmd/1]).
Expand All @@ -55,7 +56,8 @@ all() ->
whole_message,
shared_magic_ref,
non_message_signal,
get_put_colliding_bucket].
get_put_colliding_bucket,
gc_binary_orig].

init_per_suite(Config) ->
erts_debug:set_internal_state(available_internal_state, true),
Expand Down Expand Up @@ -1091,6 +1093,31 @@ gar_setter(Key) ->
persistent_term:put(Key, {complex, term}),
gar_setter(Key).

%% https://github.com/erlang/otp/issues/9222
gc_binary_orig(_Config) ->

Key = ?FUNCTION_NAME,
Data = iolist_to_binary(lists:duplicate(100, $a)),

persistent_term:put(Key,Data),

LiteralData = persistent_term:get(Key),

%% We create a sub binary to a literal persistent term
%% This means that the SUB_BITS now is a non-literal but
%% orig is a literal
<<SubData:70/binary, _/binary>> = LiteralData,

%% This used to GC LiteralData->orig when it should not.
erlang:garbage_collect(),

%% Just a dummy compare in order to access the data. This would
%% segfault on Windows.
false = LiteralData =:= SubData,

persistent_term:erase(Key).


%% Test that literals in non-message signals are copied
%% when removed...
%%
Expand Down
3 changes: 2 additions & 1 deletion erts/etc/win32/erl.c
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,8 @@ static void get_parameters(void)
free(ini_filename);
}

static void error(char* format, ...)
static __declspec(noreturn) void
error(char* format, ...)
{
char sbuf[2048];
va_list ap;
Expand Down

0 comments on commit e060f28

Please sign in to comment.