SWI-Prolog / packages-clib

Assorted external libraries: processes, sockets, MIME, CGI, etc.
8 stars 19 forks source link

environment/1 option of process_create/3 doesn't work correctly #33

Closed dgelessus closed 3 years ago

dgelessus commented 3 years ago

This is on macOS 10.14.6, with SWI-Prolog built from source (swi-prolog/swipl-devel@2a16e87857605f59645ace4d578e9791fb5dbe92, swi-prolog/packages-clib@50b35f579d07e14e1b5833b0032bc60d75c41a10).

The environment(Env) option of process:process_create/3 doesn't work correctly. According to the docs, environment(Env) should pass the environment of the current process on to the called process, while replacing/adding the variables listed in Env. Actually, it seems that although all variables from Env are correctly passed to the new process, most of the variables from the current process are dropped and only a small random selection is kept:

?- process_create('/usr/bin/printenv', [], [environment(['CLICOLOR'=foo])]).
CLICOLOR=foo
MANPATH=/opt/local/share/man:
TERM_PROGRAM=Apple_Terminal
TERM=xterm-256color
SHELL=/bin/bash
true.

?- process_create('/usr/bin/printenv', [], [environment(['TERM'=dumb])]).
TERM=dumb
CLICOLOR=1
true.

?- process_create('/usr/bin/printenv', [], [environment(['FOO'=bar])]).
FOO=bar
MANPATH=/opt/local/share/man:
CLICOLOR=1
true.

Also, passing an empty Env (i. e. environment([])) causes a segmentation fault.

Stack trace ```prolog ?- process_create('/usr/bin/printenv', [], [environment([])]). SWI-Prolog [thread 1 (main) at Wed Dec 2 20:54:49 2020]: received fatal signal 11 (segv) C-stack trace labeled "crash": [0] /src/libswipl.8.dylib(save_backtrace+0x62) [0x1006a68d2] [1] /src/libswipl.8.dylib(print_c_backtrace+0x15) [0x1006a7205] [2] /src/libswipl.8.dylib(sigCrashHandler+0x146) [0x1006a70f6] [3] /src/libswipl.8.dylib(dispatch_signal+0x52e) [0x1005dff1e] [4] /src/libswipl.8.dylib(pl_signal_handler+0x15) [0x1005e2c95] [5] /usr/lib/system/libsystem_platform.dylib(_sigtramp+0x1d) [0x7fff5c3f4b5d] sh: addr2line: command not found [7] /packages/clib/process.so(parse_environment+0x2c8) [0x1015c0dd8] [8] /packages/clib/process.so(parse_options+0x2d0) [0x1015c0440] [9] /packages/clib/process.so(process_create+0x92) [0x1015bf9f2] [10] /src/libswipl.8.dylib(PL_next_solution+0x10d39) [0x10051a2b9] [11] /src/libswipl.8.dylib(query_loop+0xd5) [0x1005b2985] [12] /src/libswipl.8.dylib(prologToplevel+0x7a) [0x1005b366a] [13] /src/libswipl.8.dylib(PL_toplevel+0x21) [0x100537251] [14] /src/swipl(main+0x47) [0x100322f17] [15] /usr/lib/system/libdyld.dylib(start+0x1) [0x7fff5c2093d5] Prolog stack: [11] process:process_create/2 [PC=1 in supervisor] [9] $toplevel:toplevel_call/1 [PC=3 in clause 1] [8] $toplevel:stop_backtrace/1 [PC=4 in clause 1] [7] $tabling:$wfs_call/2 [PC=17 in clause 1] [5] $toplevel:$execute_goal2/3 [PC=29 in clause 1] [3] $toplevel:$query_loop/0 [PC=39 in clause 2] [2] $toplevel:$runtoplevel/0 [PC=19 in clause 1] [1] $toplevel:$toplevel/0 [PC=3 in clause 1] [0] system:$c_call_prolog/0 [PC=0 in top query clause] Running on_halt hooks with status 139 Killing 87710 with default signal handlers Segmentation fault: 11 -> exit 139 (SIGSEGV) ```

The segfault seems to be because the helper function already_in_env in process.c doesn't handle env being NULL. This happens when an empty environment list was passed, because then the buffer in which the environment is constructed never has any variables added to it, so it is still NULL by the time that already_in_env is called on it.

I haven't figured out though what's causing most of the existing environment variables to be "lost" when a non-empty list is passed.

JanWielemaker commented 3 years ago

Thanks. This was a quite serious bug that shows mostly on MacOS, but could harm any non-Windows system and indeed occasionally also affects Linux. Fixed with e2c203a591072dc78bb9452f84d4187c1c48b864 and d83ed3ef92aafb59387225ac8c4a106195cb4979.

First fixes the crash. Second loosing part of the environment and provides a cleaner fix for the crash.

dgelessus commented 3 years ago

Thank you for the quick fix! All seems to work correctly now on my machine.