Closed GongT closed 6 years ago
This is the only similar issue https://github.com/docker-library/python/issues/177
The issue is alpine specific, perhaps it's an anomaly with musl.
I'm not sure what's causing it, but for someone who wants to dig into what's going on here, the end of an strace python ssssss.py
has the following:
...
stat("/usr/local/lib/python3.7", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat("/usr/local/lib/python3.7/lib-dynload", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat("/usr/local/lib/python3.7/site-packages", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat("ssssss.py", 0x7fff32d7e2f0) = -1 ENOENT (No such file or directory)
stat("ssssss.py", 0x7fff32d7db50) = -1 ENOENT (No such file or directory)
readlink("ssssss.py", 0x7fff32d6d570, 4096) = -1 ENOENT (No such file or directory)
open("ssssss.py", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_PATH) = -1 ENOENT (No such file or directory)
open("ssssss.py", O_RDONLY) = -1 ENOENT (No such file or directory)
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=NULL} ---
+++ killed by SIGSEGV (core dumped) +++
Segmentation fault
(Doesn't appear to contain any obvious clues.)
I've done a bit of digging. It seems that pymain->config.program
is null here for some reason:
I haven't managed to figure out anything more, though. There were a bunch of changes in that file for Python 3.7 and have been a bunch since 3.7.0 was released.
Confirming issue. Attempting to execute any non-existing file results in a segfault on fresh Alpine Python 3.6 docker image.
@JayH5 found reason. Investigated history and found the bug was introduced here: https://github.com/python/cpython/commit/19760863623b636a63ccf649107d9504c6465a92#diff-75445bdc3b6b3dd20b005698fa165444R2443 So it should be totally unrelated to Alpine... But on for example the stretch-slim Distro a "(null)" is returned for program name. Anyway it's a bug that has to be fixed and not "just an alpine issue"...
Bug is still present in current 3.7 branch..
So, I think this makes sense. It's the case that fprintf
comes from libc -- if pymain->config.program
is NULL
, then it appears GLIBC handles that gracefully and %ls
will give (null)
, where musl (arguably reasonably) segfaults when asked to format NULL
as a string. See https://stackoverflow.com/a/11589479/433558 for another discussion of this same issue (where it's noted that passing NULL
to %s
is "undefined" according to the ANSI spec).
Has this been raised on the Python bug tracker? I imagine the patch could be as trivial as a ternary to swap out a NULL
value for some other meaningful string, but I have to admit I don't understand the purpose of pymain->config.program
here (given that the filename in question appears later in the error message already).
@tianon yes it has been raise and fixed. (see reference in timeline) I made a POC change (simply move the code that sets the config to NULL to later position). Sure it would have been possible to just swap out the NULL value, but as it alsways would show null here the better solution would have been to just remove the config.program from output.
The config.program containst the executable name for the interpreter (so python, python3.7 or whatever the binary was called). It's more nice to keep the program name in output. Even more with python as You are quite likely to have different python executables running.
Anyway stinner merged some further changes he did to this section in the master/3.8 branch to 3.7 branch and so the problem is now fixed with not a simple change but with an already existing solution.
I already tested the patched version and it puts out program name correctly and does not dump core.
Nice! So this fix will be in the next 3.7 release?
(I'm closing this issue since the issue itself is very minor, the image's behavior is an accurate representation of Python's own behavior, and it appears it'll likely be fixed in the next 3.7 release. :+1:)
expect: