erlang / otp

Erlang/OTP
http://erlang.org
Apache License 2.0
11.33k stars 2.94k forks source link

OTP-27 inetrc behavior change leads to obscure crashes #8899

Open lhoguin opened 3 days ago

lhoguin commented 3 days ago

Describe the bug It's technically not a bug as the inetrc Kernel variable is documented to be a string:

inetrc = Filename - The name (string) of an Inet user configuration file. For details, see section Inet Configuration in the ERTS User's Guide.

However, something has changed in OTP-27 that should be improved at least a bit: the error message.

We have been testing that using an atom works in the RabbitMQ test suite because some users were using atoms (it turns out that the RabbitMQ documentation was telling people to use single quotes, whoops). It breaks for OTP-27. I understand we should have been telling people to use double quotes, and that's fine to require that change.

What isn't expected however is to have so many obscure crashes when you provide an invalid value for the filename. Since using erl -kernel inetrc \"$FILE\" is a documented way of setting this value, and it's so easy to confuse single and double quotes (especially coming from outside the Erlang world), the VM should probably validate and error out early instead of the below.

In OTP-26 we could set inetrc as an atom:

$ cat /tmp/inetrc-ipv6.erl 
{inet6,true}.
$ erl -kernel inetrc \'/tmp/inetrc-ipv6.erl\'
Erlang/OTP 26 [erts-14.2.5.2] [source] [64-bit] [smp:16:16] [ds:16:16:10] [async-threads:1] [jit:ns]

Eshell V14.2.5.2 (press Ctrl+G to abort, type help(). for help)
1> 

In OTP-27 we get horrible crashes:

$ erl -kernel inetrc \'/tmp/inetrc-ipv6.erl\'
2024-10-04 10:14:45.016170 supervisor_report   
    supervisor: {local,kernel_sup}
    errorContext: start_error
    reason: {'EXIT',{function_clause,[{erl_prim_loader,archive_split,['/tmp/inetrc-ipv6.erl',"ze.",[]],[]},{erl_prim_loader,name_split,2,[]},{erl_prim_loader,client_or_request,2,[]},{erl_prim_loader,read_file,1,[]},{inet_config,get_rc,1,[{file,"inet_config.erl"},{line,448}]},{inet_config,try_get_rc,1,[{file,"inet_config.erl"},{line,442}]},{inet_config,read_rc,0,[{file,"inet_config.erl"},{line,391}]},{inet_config,init,0,[{file,"inet_config.erl"},{line,90}]}]}}
    offender: [{pid,undefined},{id,inet_db},{mfargs,{inet_db,start_link,[]}},{restart_type,permanent},{significant,false},{shutdown,2000},{child_type,worker}]
2024-10-04 10:14:45.017343 crash_report        
    initial_call: {application_master,init,['Argument__1','Argument__2','Argument__3']}
    pid: <0.46.0>
    registered_name: []
    process_label: undefined
    error_info: {exit,{{shutdown,{failed_to_start_child,inet_db,{'EXIT',{function_clause,[{erl_prim_loader,archive_split,['/tmp/inetrc-ipv6.erl',"ze.",[]],[]},{erl_prim_loader,name_split,2,[]},{erl_prim_loader,client_or_request,2,[]},{erl_prim_loader,read_file,1,[]},{inet_config,get_rc,1,[{file,"inet_config.erl"},{line,448}]},{inet_config,try_get_rc,1,[{file,"inet_config.erl"},{line,442}]},{inet_config,read_rc,0,[{file,"inet_config.erl"},{line,391}]},{inet_config,init,0,[{file,"inet_config.erl"},{line,90}]}]}}}},{kernel,start,[normal,[]]}},[{application_master,init,3,[{file,"application_master.erl"},{line,143}]},{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,329}]}]}
    ancestors: [application_controller,<0.10.0>]
    message_queue_len: 1
    messages: [{'EXIT',<0.47.0>,normal}]
    links: [<0.45.0>]
    dictionary: []
    trap_exit: true
    status: running
    heap_size: 987
    stack_size: 29
    reductions: 99
2024-10-04 10:14:45.017360 std_info            
    application: kernel
    exited: {{shutdown,{failed_to_start_child,inet_db,{'EXIT',{function_clause,[{erl_prim_loader,archive_split,['/tmp/inetrc-ipv6.erl',"ze.",[]],[]},{erl_prim_loader,name_split,2,[]},{erl_prim_loader,client_or_request,2,[]},{erl_prim_loader,read_file,1,[]},{inet_config,get_rc,1,[{file,"inet_config.erl"},{line,448}]},{inet_config,try_get_rc,1,[{file,"inet_config.erl"},{line,442}]},{inet_config,read_rc,0,[{file,"inet_config.erl"},{line,391}]},{inet_config,init,0,[{file,"inet_config.erl"},{line,90}]}]}}}},{kernel,start,[normal,[]]}}
    type: permanent
2024-10-04 10:14:45.018050 Error in process ~p with exit value:~n~p~n
    <0.57.0>
    {badarg,[{erlang,send,[code_server,{code_call,<0.57.0>,{load_module,#Ref<0.3821139121.2104360968.83270>,logger_formatter,"/home/essen/erlang/OTP-27.0.1/lib/kernel-10.0.1/ebin/logger_formatter.beam",false,#Ref<0.3821139121.2104229896.83265>}}],[{error_info,#{module=>erl_erts_errors}}]},{code_server,call,1,[{file,"code_server.erl"},{line,154}]},{error_handler,undefined_function,3,[{file,"error_handler.erl"},{line,84}]},{logger_simple_h,'-log_internal/2-fun-0-',1,[{file,"logger_simple_h.erl"},{line,172}]}]}
Kernel pid terminated (application_controller) ("{application_start_failure,kernel,{{shutdown,{failed_to_start_child,inet_db,{'EXIT',{function_clause,[{erl_prim_loader,archive_split,['/tmp/inetrc-ipv6.erl',\"ze.\",[]],[]},{erl_prim_loader,name_split,2,[]},{erl_prim_loader,client_or_request,2,[]},{erl_prim_loader,read_file,1,[]},{inet_config,get_rc,1,[{file,\"inet_config.erl\"},{line,448}]},{inet_config,try_get_rc,1,[{file,\"inet_config.erl\"},{line,442}]},{inet_config,read_rc,0,[{file,\"inet_config.erl\"},{line,391}]},{inet_config,init,0,[{file,\"inet_config.erl\"},{line,90}]}]}}}},{kernel,start,[normal,[]]}}}")

Crash dump is being written to: erl_crash.dump...done

Expected behavior Better errors.

Affected versions OTP-27.

Additional context We will fix the RabbitMQ documentation. We will probably tell people to use the ERL_INETRC environment variable as it's less likely to lead to errors.

jhogberg commented 3 days ago

Thanks for your report, I've opened a draft PR #8902 for maint that restores the old behavior specifically for this argument. I figured that it's better to do so than to raise an error, as the latter is bound to get very confusing regardless of how we word it.