Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:24
erlang
6661-erts-Fix-init-crash-slogan.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 6661-erts-Fix-init-crash-slogan.patch of Package erlang
From ede8830346fd553707ccb2d0290d3a4029b9497b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20H=C3=B6gberg?= <john@erlang.org> Date: Fri, 2 Jun 2023 11:36:43 +0200 Subject: [PATCH 1/2] erts: Fix 'init' crash slogan Use the internal routine powering erlang:display/1 instead of trying to wing it, which left references, maps, and funs invisible since we apparently hadn't updated this part of the code since those were added. --- erts/emulator/beam/bif.c | 40 +++++++++++++++----- erts/emulator/beam/bif.tab | 2 +- erts/emulator/test/map_SUITE.erl | 2 +- erts/preloaded/src/erts_internal.erl | 14 +++++++ erts/preloaded/src/init.erl | 55 +--------------------------- erts/test/erl_print_SUITE.erl | 4 +- lib/kernel/src/erts_debug.erl | 8 +--- 7 files changed, 52 insertions(+), 73 deletions(-) diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c index 80eb260153..d0f9976a32 100644 --- a/erts/emulator/beam/bif.c +++ b/erts/emulator/beam/bif.c @@ -4193,22 +4193,44 @@ BIF_RETTYPE display_1(BIF_ALIST_1) } /* - * erts_debug:display/1 is for debugging erlang:display/1 + * erts_internal:term_to_string/2 is an internal and undocumented function for + * formatting terms during init or other times when io_lib is unavailable. + * It can also be used to debug functions that rely on the internal term + * printing such as erlang:display/1 */ -BIF_RETTYPE erts_debug_display_1(BIF_ALIST_1) +BIF_RETTYPE erts_internal_term_to_string_2(BIF_ALIST_2) { + erts_dsprintf_buf_t *dsbufp; + int limit; int pres; Eterm res; Eterm *hp; - erts_dsprintf_buf_t *dsbufp = erts_create_tmp_dsbuf(64); - pres = erts_dsprintf(dsbufp, "%.*T\n", INT_MAX, BIF_ARG_1); - if (pres < 0) - erts_exit(ERTS_ERROR_EXIT, "Failed to convert term to string: %d (%s)\n", - -pres, erl_errno_id(-pres)); - hp = HAlloc(BIF_P, 2*dsbufp->str_len); /* we need length * 2 heap words */ + + if (is_small(BIF_ARG_2) && + (signed_val(BIF_ARG_2) > 1 && + signed_val(BIF_ARG_2) < INT_MAX)) { + limit = signed_val(BIF_ARG_2); + } else if (BIF_ARG_2 == am_undefined) { + limit = INT_MAX; + } else { + BIF_ERROR(BIF_P, BADARG); + } + + dsbufp = erts_create_tmp_dsbuf(64); + pres = erts_dsprintf(dsbufp, "%.*T", limit, BIF_ARG_1); + + if (pres < 0) { + erts_exit(ERTS_ERROR_EXIT, + "Failed to convert term to string: %d (%s)\n", + -pres, + erl_errno_id(-pres)); + } + + hp = HAlloc(BIF_P, 2 * dsbufp->str_len); res = buf_to_intlist(&hp, dsbufp->str, dsbufp->str_len, NIL); - erts_printf("%s", dsbufp->str); + erts_destroy_tmp_dsbuf(dsbufp); + BIF_RET(res); } diff --git a/erts/emulator/beam/bif.tab b/erts/emulator/beam/bif.tab index e1ca5a961b..74ab523a9b 100644 --- a/erts/emulator/beam/bif.tab +++ b/erts/emulator/beam/bif.tab @@ -446,7 +446,6 @@ bif erts_debug:same/2 bif erts_debug:flat_size/1 bif erts_debug:get_internal_state/1 bif erts_debug:set_internal_state/2 -bif erts_debug:display/1 bif erts_debug:dist_ext_to_term/2 bif erts_debug:instructions/0 bif erts_debug:interpreter_size/0 @@ -784,3 +783,4 @@ bif maps:from_keys/2 # ubif erlang:min/2 ubif erlang:max/2 +bif erts_internal:term_to_string/2 diff --git a/erts/emulator/test/map_SUITE.erl b/erts/emulator/test/map_SUITE.erl index 5d7546c1a4..ffb10b9285 100644 --- a/erts/emulator/test/map_SUITE.erl +++ b/erts/emulator/test/map_SUITE.erl @@ -3786,7 +3786,7 @@ make_nontrivial_map(N, Effort) -> maps:from_list(L). verify_map_term(Term) -> - Printed = string:chomp(erts_debug:display(Term)), + Printed = string:chomp(erts_internal:term_to_string(Term)), {ok,Tokens,1} = erl_scan:string(Printed ++ "."), {ok,ParsedTerm} = erl_parse:parse_term(Tokens), diff --git a/erts/preloaded/src/erts_internal.erl b/erts/preloaded/src/erts_internal.erl index 6688bbfe67..ef1bf2f472 100644 --- a/erts/preloaded/src/erts_internal.erl +++ b/erts/preloaded/src/erts_internal.erl @@ -119,6 +119,8 @@ -export([dynamic_node_name/0, dynamic_node_name/1]). +-export([term_to_string/1, term_to_string/2]). + %% %% Await result of send to port %% @@ -1060,3 +1062,15 @@ dynamic_node_name(false) -> false -> ok; _ -> _ = persistent_term:erase({?MODULE, dynamic_node_name}), ok end. + +-spec term_to_string(T :: term()) -> string(). + +term_to_string(T) -> + term_to_string(T, undefined). + +-spec term_to_string(T, Limit) -> string() when + T :: term(), + Limit :: undefined | pos_integer(). + +term_to_string(_T, _Limit) -> + erlang:nif_error(undefined). diff --git a/erts/preloaded/src/init.erl b/erts/preloaded/src/init.erl index 7933cfaa34..1f7ef28085 100644 --- a/erts/preloaded/src/init.erl +++ b/erts/preloaded/src/init.erl @@ -315,60 +315,9 @@ boot(Start,Flags,Args) -> bootpid = BootPid}, boot_loop(BootPid,State). -%%% Convert a term to a printable string, if possible. -to_string(X, D) when is_list(X), D < 4 -> % assume string - F = flatten(X, []), - case printable_list(F) of - true when length(F) > 0 -> F; - _false -> - List = [to_string(E, D+1) || E <- X], - flatten(["[",join(List),"]"], []) - end; -to_string(X, _D) when is_list(X) -> - "[_]"; -to_string(X, _D) when is_atom(X) -> - atom_to_list(X); -to_string(X, _D) when is_pid(X) -> - pid_to_list(X); -to_string(X, _D) when is_float(X) -> - float_to_list(X); -to_string(X, _D) when is_integer(X) -> - integer_to_list(X); -to_string(X, D) when is_tuple(X), D < 4 -> - List = [to_string(E, D+1) || E <- tuple_to_list(X)], - flatten(["{",join(List),"}"], []); -to_string(X, _D) when is_tuple(X) -> - "{_}"; -to_string(_X, _D) -> - "". % can't do anything with it - -%% This is an incorrect and narrow definition of printable characters. -%% The correct one is in io_lib:printable_list/1 -%% -printable_list([H|T]) when is_integer(H), H >= 32, H =< 126 -> - printable_list(T); -printable_list([$\n|T]) -> printable_list(T); -printable_list([$\r|T]) -> printable_list(T); -printable_list([$\t|T]) -> printable_list(T); -printable_list([]) -> true; -printable_list(_) -> false. - -join([] = T) -> - T; -join([_Elem] = T) -> - T; -join([Elem|T]) -> - [Elem,","|join(T)]. - -flatten([H|T], Tail) when is_list(H) -> - flatten(H, flatten(T, Tail)); -flatten([H|T], Tail) -> - [H|flatten(T, Tail)]; -flatten([], Tail) -> - Tail. - things_to_string([X|Rest]) -> - " (" ++ to_string(X, 0) ++ ")" ++ things_to_string(Rest); + " (" ++ erts_internal:term_to_string(X, 32768) ++ ")" ++ + things_to_string(Rest); things_to_string([]) -> "". diff --git a/erts/test/erl_print_SUITE.erl b/erts/test/erl_print_SUITE.erl index 2c3cae64c1..49f9f03945 100644 --- a/erts/test/erl_print_SUITE.erl +++ b/erts/test/erl_print_SUITE.erl @@ -174,8 +174,8 @@ get_chnl_no(NodeName) when is_atom(NodeName) -> erts_debug:get_internal_state({channel_number, NodeName}). chk_display(Term, Expect) when is_list(Expect) -> - Dstr = erts_debug:display(Term), - case Expect ++ io_lib:nl() of + Dstr = erts_internal:term_to_string(Term), + case Expect of Dstr -> io:format("Test of \"~p\" succeeded.~n" " Expected and got: ~s~n", diff --git a/lib/kernel/src/erts_debug.erl b/lib/kernel/src/erts_debug.erl index 6cf3e211e8..9b939e39d1 100644 --- a/lib/kernel/src/erts_debug.erl +++ b/lib/kernel/src/erts_debug.erl @@ -31,7 +31,7 @@ %%% BIFs --export([breakpoint/2, disassemble/1, display/1, dist_ext_to_term/2, +-export([breakpoint/2, disassemble/1, dist_ext_to_term/2, flat_size/1, get_internal_state/1, instructions/0, interpreter_size/0, map_info/1, same/2, set_internal_state/2, @@ -69,12 +69,6 @@ breakpoint(_, _) -> disassemble(_) -> erlang:nif_error(undef). --spec display(Term) -> string() when - Term :: term(). - -display(_) -> - erlang:nif_error(undef). - -spec dist_ext_to_term(Tuple, Binary) -> term() when Tuple :: tuple(), Binary :: binary(). -- 2.35.3
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor