-
-
Notifications
You must be signed in to change notification settings - Fork 29.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Some C-API symbols (e.g. Py_FrozenMain) are not always exported on Unix #88299
Comments
When Python is built without --enable-shared, the "Py_FrozenMain" is not exported. When Python is built with --enable-shared, the "Py_FrozenMain" is exported as expected. I can reproduce the issue with attached reproduce.tar.gz example:
The difference is that build.sh links directly two object files (.o) into a binary, whereas build_ar.sh creates a static library (.a) and then link the static library into a binary. Python is always built with a static library (libpythonVERSION.a) which causes the issue. A solution is to pass -Wl,--whole-archive option to the linker to export *all* symbols exported by all object files, and not only export symbols of the object files which are used. I'm not sure why, but "Py_FrozenMain" is the *only* impacted symbol of the whole C API. This issue was discovered by Petr Viktorin who works on the stable ABI: |
The "python" binary exports 1610 symbols. With the attached fix, it exports 1611 symbols (+1): "Py_FrozenMain" is also exported :-) |
The symbol is not exported on Windows neither. My PR 26126 ("Test Py_FrozenMain()") fails on Windows with: "_testembed.obj : error LNK2001: unresolved external symbol __imp_Py_FrozenMain" ("__imp_" prefix is added by Windows DLL loader.) |
Apparently, on some platforms Should I rename the issue to cover these as well? |
Repurposing this bug to track all symbols that don't appear in some configurations.
|
On Solaris (and most likely several other platforms), |
Oh, I added an explicit test for that in my PR 30556.
I suggest to first fix the issue (export the symbol), and then write a second PR to add it to the stable ABI. |
Sadly, Py_FrozenMain() is still missing on Windows. See: Until Windows also exports the symbol, I don't think that we can add the symbol to the stable ABI. I prefer to not backport the change since it's always risky to break the build system on a stable branch. If someone wants to fix the Windows build to also export Py_FrozenMain(), please open a new issue. I consider that the initial issue is fixed, so I close the issue. |
Now it started failing on a different place: ====================================================================== Traceback (most recent call last):
File "/..../cpython-main/Lib/test/test_capi.py", line 662, in test_export_symbols
self.assertTrue(hasattr(ctypes.pythonapi, name))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: False is not true Looking at the test, is the expectation that all OSes must implement it since 3.11? |
Oh no, I expected that the new way to build Python would also export PyThread_get_thread_native_id() on Solaris. I reopen the issue. Can you please specify your configure command? Can you check without Python if the symbol is exported or not? If you use --enable-shared, check in libpython, otherwise check in the "python" binary. |
Ah, sorry, I could have described the issue better. It's not a problem with exporting, PyThread_get_thread_native_id() isn't available on Solaris (and possibly other platforms) at all. https://github.com/python/cpython/blob/main/Include/pythread.h#L28 The reason I didn't implement it yet is that Solaris doesn't expose anything like native thread id. We do have functions like If necessary, I guess that such a number can be created by masking pid and thread id together, but then there's a question of how it is supposed to be used (because OS would not understand it). |
Oh ok, it's a simple bug in my test. I wrote #74821 to fix it. |
Jakub, does this mean test_stable_abi_ctypes fails on Solaris? |
Yes, it still does, and PyThread_get_thread_native_id is the only symbol missing. |
|
The Py_TRACE_REF macro changes the ABI on purpose, I suggest you to open a separated issue if you plan to implement the stable ABI for this special debug build:
Extract of modsupport.h: #ifdef Py_TRACE_REFS
/* When we are tracing reference counts, rename module creation functions so
modules compiled with incompatible settings will generate a
link-time error. */
#define PyModule_Create2 PyModule_Create2TraceRefs
#define PyModule_FromDefAndSpec2 PyModule_FromDefAndSpec2TraceRefs
#endif Py_TRACE_REF is incompatible with the stable ABI, extract of object.h:
The PyObject layout is different, it adds two pointers to the structure: _ob_next and _ob_prev. In Python 3.8, I modified the Python debug build to make it ABI compatible with the release build by not defining Py_TRACE_REF if Py_DEBUG is defined. Someone proposed to reimplement Py_TRACE_REF with a separated list or hash table of all objects (the _ob_prev and _ob_next linked list), rather than modifying PyObject. But nobody implemented it. Note: Py_TRACE_REF requires additional _Py_AddToAllObjects() and _Py_ForgetReference() function calls in _Py_NewReference() and _Py_Dealloc(). But hopefully, _Py_NewReference() and _Py_Dealloc() are function calls at the ABI level, so the different implementation is not an issue. It seems like the only blocker issue is the PyObject layout change. |
Ah! I see. Sorry, I just added a quick comment and didn't investigate further immediately. |
No problem, thanks for working on clarifying the stable ABI! |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: