Skip to content

test_embed fails if Python is built with LTO and LLVM clang on macOS #110313

Closed

Description

@debohman

Bug report

Bug description:

# Next, run the profile task to generate the profile information.
LLVM_PROFILE_FILE="code-%p.profclangr"  ./python.exe -m test --pgo --timeout=
Raised RLIMIT_NOFILE: 256 -> 1024
0:00:00 load avg: 3.49 Run 44 tests sequentially
0:00:00 load avg: 3.49 [ 1/44] test_array
0:00:01 load avg: 3.49 [ 2/44] test_base64
0:00:01 load avg: 3.49 [ 3/44] test_binascii -- test_base64 failed (env changed)
0:00:01 load avg: 3.49 [ 4/44] test_binop
0:00:01 load avg: 3.49 [ 5/44] test_bisect
0:00:01 load avg: 3.49 [ 6/44] test_bytes
0:00:05 load avg: 3.37 [ 7/44] test_bz2 -- test_bytes failed (env changed)
0:00:07 load avg: 3.37 [ 8/44] test_cmath
0:00:07 load avg: 3.34 [ 9/44] test_codecs
0:00:09 load avg: 3.34 [10/44] test_collections
0:00:10 load avg: 3.34 [11/44] test_complex
0:00:10 load avg: 3.34 [12/44] test_dataclasses
0:00:11 load avg: 3.34 [13/44] test_datetime
0:00:16 load avg: 3.39 [14/44] test_decimal
-------------------------------------------------------- NOTICE --------------------------------------------------------
test_decimal may generate "malloc can't allocate region"
warnings on macOS systems. This behavior is known. Do not
report a bug unless tests are also failing.
See https://github.com/python/cpython/issues/85100
------------------------------------------------------------------------------------------------------------------------
./Modules/_decimal/libmpdec/context.c:57: warning: mpd_setminalloc: ignoring request to set MPD_MINALLOC a second time

python.exe(67804,0x7fffa28f43c0) malloc: *** mach_vm_map(size=842105263157895168) failed (error code=3)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
python.exe(67804,0x7fffa28f43c0) malloc: *** mach_vm_map(size=842105263157895168) failed (error code=3)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
python.exe(67804,0x7fffa28f43c0) malloc: *** mach_vm_map(size=421052631578947584) failed (error code=3)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
python.exe(67804,0x7fffa28f43c0) malloc: *** mach_vm_map(size=421052631578947584) failed (error code=3)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
0:00:22 load avg: 3.28 [15/44] test_difflib
0:00:23 load avg: 3.10 [16/44] test_embed
test test_embed failed
0:00:28 load avg: 3.17 [17/44] test_float -- test_embed failed (41 failures)
0:00:28 load avg: 3.17 [18/44] test_fstring
0:00:31 load avg: 3.17 [19/44] test_functools
./Modules/_decimal/libmpdec/context.c:57: warning: mpd_setminalloc: ignoring request to set MPD_MINALLOC a second time

0:00:31 load avg: 3.17 [20/44] test_generators
0:00:32 load avg: 3.17 [21/44] test_hashlib
0:00:33 load avg: 3.08 [22/44] test_heapq
0:00:34 load avg: 3.08 [23/44] test_int
0:00:34 load avg: 3.08 [24/44] test_itertools
0:00:38 load avg: 2.99 [25/44] test_json
0:00:41 load avg: 2.99 [26/44] test_long -- test_json failed (env changed)
0:00:44 load avg: 2.83 [27/44] test_lzma
0:00:45 load avg: 2.83 [28/44] test_math
0:00:48 load avg: 2.84 [29/44] test_memoryview
0:00:49 load avg: 2.84 [30/44] test_operator
0:00:49 load avg: 2.84 [31/44] test_ordered_dict
0:00:51 load avg: 2.84 [32/44] test_patma
0:00:51 load avg: 2.84 [33/44] test_pickle
0:00:58 load avg: 2.63 [34/44] test_pprint
0:00:58 load avg: 2.63 [35/44] test_re
0:01:00 load avg: 2.63 [36/44] test_set -- test_re failed (env changed)
0:01:05 load avg: 2.50 [37/44] test_sqlite3
0:01:06 load avg: 2.50 [38/44] test_statistics -- test_sqlite3 failed (env changed)
0:01:08 load avg: 2.38 [39/44] test_str
0:01:11 load avg: 2.38 [40/44] test_struct -- test_str failed (env changed)
0:01:12 load avg: 2.38 [41/44] test_tabnanny -- test_struct failed (env changed)
0:01:13 load avg: 2.51 [42/44] test_time -- test_tabnanny failed (env changed)
0:01:15 load avg: 2.51 [43/44] test_xml_etree
0:01:16 load avg: 2.51 [44/44] test_xml_etree_c

Total duration: 1 min 18 sec
Total tests: run=8,985 failures=41 skipped=192
Total test files: run=44/44 failed=1 env_changed=8
Result: FAILURE
make: *** [Makefile:800: profile-run-stamp] Error 2

This is on macOS 10.12.6, building with LLVM / Clang 17.0.1. The system otherwise has Python 3.11.6 installed.

CPython versions tested on:

CPython main branch

Operating systems tested on:

macOS

Linked PRs

Activity

  1. debohman commented on Oct 10, 2023

    @debohman
    ContributorAuthor

    I see now that test_embed uses Programs/_testembed to execute. I don't know how embedding works, but clearly something has broken in 3.13. It works properly in 3.12.0 built with the same toolchain.

    Under 3.13:

    % Programs/_testembed test_init_main
    Run Python code before _Py_InitializeMain
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
    ImportError: dlopen(/tera/tera/debo/Projects/Python/main/build/lib.macosx-10.12-x86_64-3.13/_testinternalcapi.cpython-313-darwin.so, 2): Symbol not found: _PyBaseObject_Type
      Referenced from: /tera/tera/debo/Projects/Python/main/build/lib.macosx-10.12-x86_64-3.13/_testinternalcapi.cpython-313-darwin.so
      Expected in: flat namespace
     in /tera/tera/debo/Projects/Python/main/build/lib.macosx-10.12-x86_64-3.13/_testinternalcapi.cpython-313-darwin.so
    

    Under 3.12.0:

    % Programs/_testembed test_init_main
    Run Python code before _Py_InitializeMain
    {"global_config": {"Py_FileSystemDefaultEncoding": "utf-8", "Py_HasFileSystemDefaultEncoding": 0, "Py_FileSystemDefaultEncodeErrors": "surrogateescape", "_Py_HasFileSystemDefaultEncodeErrors": 0, "Py_UTF8Mode": 0, "Py_DebugFlag": 0, "Py_VerboseFlag": 0, "Py_QuietFlag": 0, "Py_InteractiveFlag": 0, "Py_InspectFlag": 0, "Py_OptimizeFlag": 0, "Py_NoSiteFlag": 0, "Py_BytesWarningFlag": 0, "Py_FrozenFlag": 0, "Py_IgnoreEnvironmentFlag": 0, "Py_DontWriteBytecodeFlag": 0, "Py_NoUserSiteDirectory": 0, "Py_UnbufferedStdioFlag": 0, "Py_HashRandomizationFlag": 1, "Py_IsolatedFlag": 0}, "pre_config": {"_config_init": 2, "parse_argv": 1, "isolated": 0, "use_environment": 1, "configure_locale": 1, "coerce_c_locale": 0, "coerce_c_locale_warn": 0, "utf8_mode": 0, "dev_mode": 0, "allocator": 0}, "config": {"_config_init": 2, "isolated": 0, "use_environment": 1, "dev_mode": 0, "install_signal_handlers": 1, "use_hash_seed": 0, "hash_seed": 0, "faulthandler": 0, "tracemalloc": 0, "perf_profiling": 0, "import_time": 0, "code_debug_ranges": 1, "show_ref_count": 0, "dump_refs": 0, "malloc_stats": 0, "filesystem_encoding": "utf-8", "filesystem_errors": "surrogateescape", "pycache_prefix": null, "program_name": "./python3", "parse_argv": 2, "argv": ["-c", "arg2"], "xoptions": [], "warnoptions": [], "pythonpath_env": null, "home": null, "module_search_paths_set": 1, "module_search_paths": ["/usr/local/lib/python312.zip", "/tera/tera/debo/Projects/Python/v3.12.0/Lib", "/tera/tera/debo/Projects/Python/v3.12.0/build/lib.macosx-10.12-x86_64-3.12"], "stdlib_dir": "/tera/tera/debo/Projects/Python/v3.12.0/Lib", "executable": "/tera/tera/debo/Projects/Python/v3.12.0/python3", "base_executable": "/tera/tera/debo/Projects/Python/v3.12.0/python3", "prefix": "/usr/local", "base_prefix": "/usr/local", "exec_prefix": "/usr/local", "base_exec_prefix": "/usr/local", "platlibdir": "lib", "site_import": 1, "bytes_warning": 0, "warn_default_encoding": 0, "inspect": 0, "interactive": 0, "optimization_level": 0, "parser_debug": 0, "write_bytecode": 1, "verbose": 0, "quiet": 0, "user_site_directory": 1, "configure_c_stdio": 1, "buffered_stdio": 1, "stdio_encoding": "utf-8", "stdio_errors": "strict", "skip_source_first_line": 0, "run_command": "import _testinternalcapi, json; print(json.dumps(_testinternalcapi.get_configs()))\n", "run_module": null, "run_filename": null, "_install_importlib": 1, "check_hash_pycs_mode": "default", "pathconfig_warnings": 1, "_init_main": 0, "orig_argv": ["python3", "-c", "import _testinternalcapi, json; print(json.dumps(_testinternalcapi.get_configs()))", "arg2"], "use_frozen_modules": 1, "safe_path": 0, "_is_python_build": 1, "int_max_str_digits": 4300}}
    
  2. vstinner commented on Oct 10, 2023

    @vstinner
    Member

    I don't understand this test_embed error neither:

    ImportError: dlopen(/tera/tera/debo/Projects/Python/main/build/lib.macosx-10.12-x86_64-3.13/_testinternalcapi.cpython-313-darwin.so, 2):
    Symbol not found: _PyBaseObject_Type
    

    In Include/object.h, PyBaseObject_Type variable is exported by:

    PyAPI_DATA(PyTypeObject) PyBaseObject_Type; /* built-in 'object' */
    

    Log:

    % python.exe Lib/test/test_embed.py
    .....................--- ['/tera/tera/debo/Projects/Python/main/Programs/_testembed', 'test_repeated_init_exec', 'import dis\nimport importlib._bootstrap\nimport opcode\nimport test.test_dis\n\ndef is_specialized(f):\n    for instruction in dis.get_instructions(f, adaptive=True):\n        opname = instruction.opname\n        if (\n            opname in opcode._specialized_opmap\n            # Exclude superinstructions:\n            and "__" not in opname\n        ):\n            return True\n    return False\n\nfunc = importlib._bootstrap._handle_fromlist\n\n# "copy" the code to un-specialize it:\nfunc.__code__ = func.__code__.replace()\n\nassert not is_specialized(func), "specialized instructions found"\n\nfor i in range(test.test_dis.ADAPTIVE_WARMUP_DELAY):\n    func(importlib._bootstrap, ["x"], lambda *args: None)\n\nassert is_specialized(func), "no specialized instructions found"\n\nprint("Tests passed")\n'] failed ---
    stdout:
    
    stderr:
    --- Loop #1 ---
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tera/tera/debo/Projects/Python/main/Lib/dis.py", line 8, in <module>
        from opcode import *
      File "/tera/tera/debo/Projects/Python/main/Lib/opcode.py", line 12, in <module>
        import _opcode
    ImportError: dlopen(/tera/tera/debo/Projects/Python/main/build/lib.macosx-10.12-x86_64-3.13/_opcode.cpython-313-darwin.so, 2): Symbol not found: _PyExc_ValueError
      Referenced from: /tera/tera/debo/Projects/Python/main/build/lib.macosx-10.12-x86_64-3.13/_opcode.cpython-313-darwin.so
      Expected in: flat namespace
     in /tera/tera/debo/Projects/Python/main/build/lib.macosx-10.12-x86_64-3.13/_opcode.cpython-313-darwin.so
    
  3. vstinner commented on Oct 10, 2023

    @vstinner
    Member

    Python/dynload_shlib.c adds a lead underscore:

    #if (defined(__OpenBSD__) || defined(__NetBSD__)) && !defined(__ELF__)
    #define LEAD_UNDERSCORE "_" 
    #else             
    #define LEAD_UNDERSCORE ""
    #endif 
    ...
        PyOS_snprintf(funcname, sizeof(funcname),
                      LEAD_UNDERSCORE "%.20s_%.200s", prefix, shortname);
    
  4. vstinner commented on Oct 10, 2023

    @vstinner
    Member

    cc @sobolevn @corona10: Can you reproduce these issues?

  5. debohman commented on Oct 10, 2023

    @debohman
    ContributorAuthor

    I think it is a problem with embedding on my platform in 3.13, which I assume enables executing Python code from inside a a C program. As I have demonstrated, it works fine in 3.12.0 with the same exact toolchain.

  6. debohman commented on Oct 10, 2023

    @debohman
    ContributorAuthor

    I suspect that the problem occurs when Python code being executed in an embedded environment tries to import a runtime loaded module. That is why much of test_embed fails.

  7. vstinner commented on Oct 10, 2023

    @vstinner
    Member

    It is not clear why _PyExc_ValueError is not found when loading _opcode.cpython-313-darwin.so. The symbol is present in python.exe

    In the Python API, the variable is called PyExc_ValueError without the leading underscore.

  8. vstinner commented on Oct 10, 2023

    @vstinner
    Member

    CC=clang CXX=clang++ CPPFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib ./configure --enable-optimizations --with-lto=full

    Do you reproduce the issue with a more classic command?

    CC=clang CXX=clang++ ./configure

    then:

    make && ./python.exe -m test -v test_embed

  9. debohman commented on Oct 10, 2023

    @debohman
    ContributorAuthor

    It is not clear why _PyExc_ValueError is not found when loading _opcode.cpython-313-darwin.so. The symbol is present in python.exe

    In the Python API, the variable is called PyExc_ValueError without the leading underscore.

    That is because macOS uses the traditional C symbol naming, which places an underscore before C symbols.

  10. vstinner commented on Oct 10, 2023

    @vstinner
    Member

    Aha, I can reproduce some issues on Linux: 8 tests failed with "env changed".

    $ CC=clang ./configure --enable-optimizations
    $ make
    (...)
    touch profile-gen-stamp
    make[1]: Leaving directory '/home/vstinner/python/main'
    # Next, run the profile task to generate the profile information.
    LLVM_PROFILE_FILE="code-%p.profclangr"  ./python -m test --pgo --timeout=
    Using random seed 297553162
    0:00:00 load avg: 6.89 Run 44 tests sequentially
    0:00:00 load avg: 6.89 [ 1/44] test_array
    0:00:00 load avg: 6.89 [ 2/44] test_base64
    0:00:00 load avg: 6.89 [ 3/44] test_binascii -- test_base64 failed (env changed)
    0:00:00 load avg: 6.89 [ 4/44] test_binop
    0:00:00 load avg: 6.89 [ 5/44] test_bisect
    0:00:00 load avg: 6.89 [ 6/44] test_bytes
    0:00:03 load avg: 6.89 [ 7/44] test_bz2 -- test_bytes failed (env changed)
    0:00:04 load avg: 6.89 [ 8/44] test_cmath
    0:00:04 load avg: 6.89 [ 9/44] test_codecs
    0:00:05 load avg: 6.42 [10/44] test_collections
    0:00:05 load avg: 6.42 [11/44] test_complex
    0:00:05 load avg: 6.42 [12/44] test_dataclasses
    0:00:06 load avg: 6.42 [13/44] test_datetime
    0:00:09 load avg: 5.91 [14/44] test_decimal
    0:00:12 load avg: 5.91 [15/44] test_difflib
    0:00:13 load avg: 5.91 [16/44] test_embed
    0:00:17 load avg: 5.51 [17/44] test_float -- test_embed failed (env changed)
    0:00:17 load avg: 5.51 [18/44] test_fstring
    0:00:18 load avg: 5.51 [19/44] test_functools
    0:00:18 load avg: 5.51 [20/44] test_generators
    0:00:18 load avg: 5.51 [21/44] test_hashlib
    0:00:19 load avg: 5.51 [22/44] test_heapq
    0:00:19 load avg: 5.15 [23/44] test_int
    0:00:20 load avg: 5.15 [24/44] test_itertools
    0:00:22 load avg: 5.15 [25/44] test_json
    0:00:23 load avg: 5.15 [26/44] test_long -- test_json failed (env changed)
    0:00:25 load avg: 4.82 [27/44] test_lzma
    0:00:25 load avg: 4.82 [28/44] test_math
    0:00:26 load avg: 4.82 [29/44] test_memoryview
    0:00:27 load avg: 4.82 [30/44] test_operator
    0:00:27 load avg: 4.82 [31/44] test_ordered_dict
    0:00:28 load avg: 4.82 [32/44] test_patma
    0:00:28 load avg: 4.82 [33/44] test_pickle
    0:00:31 load avg: 4.51 [34/44] test_pprint
    0:00:31 load avg: 4.51 [35/44] test_re
    0:00:32 load avg: 4.51 [36/44] test_set
    0:00:35 load avg: 4.23 [37/44] test_sqlite3
    0:00:35 load avg: 4.23 [38/44] test_statistics -- test_sqlite3 failed (env changed)
    0:00:37 load avg: 4.23 [39/44] test_str
    0:00:38 load avg: 4.23 [40/44] test_struct -- test_str failed (env changed)
    0:00:39 load avg: 4.23 [41/44] test_tabnanny -- test_struct failed (env changed)
    0:00:39 load avg: 3.97 [42/44] test_time -- test_tabnanny failed (env changed)
    0:00:41 load avg: 3.97 [43/44] test_xml_etree
    0:00:42 load avg: 3.97 [44/44] test_xml_etree_c
    
    Total duration: 43.1 sec
    Total tests: run=8,990 skipped=187
    Total test files: run=44/44 env_changed=8
    Result: SUCCESS
    

    Example:

    vstinner@mona$ LLVM_PROFILE_FILE=code-%p.profclangr ./python -m test --fail-env-changed test_bytes -m test_check_encoding_errors -v
    == CPython 3.13.0a0 (heads/main:732532b0af, Oct 11 2023, 00:54:44) [Clang 16.0.6 (Fedora 16.0.6-3.fc38)]
    == Linux-6.5.5-200.fc38.x86_64-x86_64-with-glibc2.37 little-endian
    == Python build: release
    == cwd: /home/vstinner/python/main/build/test_python_worker_31170æ
    == CPU count: 12
    == encodings: locale=UTF-8 FS=utf-8
    == resources: all test resources are disabled, use -u option to unskip tests
    
    Using random seed 4098483406
    0:00:00 load avg: 1.57 Run 1 test sequentially
    0:00:00 load avg: 1.57 [1/1] test_bytes
    test_check_encoding_errors (test.test_bytes.ByteArrayTest.test_check_encoding_errors) ... ok
    test_check_encoding_errors (test.test_bytes.BytesTest.test_check_encoding_errors) ... ok
    
    ----------------------------------------------------------------------
    Ran 2 tests in 0.053s
    
    OK
    Warning -- files was modified by test_bytes
    Warning --   Before: []
    Warning --   After:  ['code-31172.profclangr', 'code-31173.profclangr', 'code-31174.profclangr'] 
    test_bytes failed (env changed)
    
    == Tests result: ENV CHANGED ==
    
    1 test altered the execution environment (env changed):
        test_bytes
    
    Total duration: 97 ms
    Total tests: run=2 (filtered)
    Total test files: run=1/1 (filtered) env_changed=1
    Result: ENV CHANGED
    

    Each subprocess spawned by tests create a code-<pid>.profclangr file.

  11. debohman commented on Oct 10, 2023

    @debohman
    ContributorAuthor

    Okay, here is what I have determined so far: Programs/_testembed has no symbols in 3.13! That is why the runtime loading is failing. I am trying to figure out what is different in the build environment for Programs/_testembed between 3.12 and 3.13.

  12. added a commit that references this issue on Oct 10, 2023
  13. vstinner commented on Oct 10, 2023

    @vstinner
    Member

    Tests spawning subprocesses create many code-<pid>.profclangr files in the current directory. It's unclear to me if they should be used to train the PGO build or not.

    PR #110654 avoids the warning, but .profclangr created by subprocesses are still removed, since regrtest starts by creating a temporary directory and changes the current working directory for this one.

  14. vstinner commented on Oct 10, 2023

    @vstinner
    Member

    If you want to to bisect the test_embed regression, you can use ./configure PROFILE_TASK="-m test --pgo test_embed" command to only run test_embed. Oh. But before, failures of the profile task were ignored by || true:

            $(LLVM_PROF_FILE) $(RUNSHARED) ./$(BUILDPYTHON) $(PROFILE_TASK) || true
    
  15. debohman commented on Oct 11, 2023

    @debohman
    ContributorAuthor

    I found the problem. The offending commit is 3e3a7da. After reverting that and rebuilding from scratch:

    Details
    % ./python.exe -m test -v test_embed
    == CPython 3.13.0a0 (main, Oct 10 2023, 18:03:59) [Clang 17.0.1]
    == macOS-10.12.6-x86_64-i386-64bit little-endian
    == Python build: release LTO
    == cwd: /tera/tera/debo/Projects/Python/main/build/test_python_worker_82633æ
    == CPU count: 24
    == encodings: locale=UTF-8 FS=utf-8
    == resources: all test resources are disabled, use -u option to unskip tests
    
    Using random seed 878659710
    Raised RLIMIT_NOFILE: 256 -> 1024
    0:00:00 load avg: 1.52 Run 1 test sequentially
    0:00:00 load avg: 1.52 [1/1] test_embed
    test_audit (test.test_embed.AuditingTests.test_audit) ... ok
    test_audit_run_command (test.test_embed.AuditingTests.test_audit_run_command) ... ok
    test_audit_run_file (test.test_embed.AuditingTests.test_audit_run_file) ... ok
    test_audit_run_interactivehook (test.test_embed.AuditingTests.test_audit_run_interactivehook) ... ok
    test_audit_run_startup (test.test_embed.AuditingTests.test_audit_run_startup) ... ok
    test_audit_run_stdin (test.test_embed.AuditingTests.test_audit_run_stdin) ... ok
    test_audit_subinterpreter (test.test_embed.AuditingTests.test_audit_subinterpreter) ... ok
    test_audit_tuple (test.test_embed.AuditingTests.test_audit_tuple) ... ok
    test_get_incomplete_frame (test.test_embed.AuditingTests.test_get_incomplete_frame) ... ok
    test_open_code_hook (test.test_embed.AuditingTests.test_open_code_hook) ... ok
    test_bpo20891 (test.test_embed.EmbeddingTests.test_bpo20891)
    bpo-20891: Calling PyGILState_Ensure in a non-Python thread must not ... ok
    test_finalize_structseq (test.test_embed.EmbeddingTests.test_finalize_structseq) ... ok
    test_forced_io_encoding (test.test_embed.EmbeddingTests.test_forced_io_encoding) ... ok
    test_initialize_pymain (test.test_embed.EmbeddingTests.test_initialize_pymain)
    bpo-34008: Calling Py_Main() after Py_Initialize() must not fail. ... ok
    test_initialize_twice (test.test_embed.EmbeddingTests.test_initialize_twice)
    bpo-33932: Calling Py_Initialize() twice should do nothing (and not ... ok
    test_pre_initialization_api (test.test_embed.EmbeddingTests.test_pre_initialization_api)
    Checks some key parts of the C-API that need to work before the runtime ... ok
    test_pre_initialization_sys_options (test.test_embed.EmbeddingTests.test_pre_initialization_sys_options)
    Checks that sys.warnoptions and sys._xoptions can be set before the ... ok
    test_repeated_init_and_inittab (test.test_embed.EmbeddingTests.test_repeated_init_and_inittab) ... ok
    test_run_main (test.test_embed.EmbeddingTests.test_run_main) ... ok
    test_run_main_loop (test.test_embed.EmbeddingTests.test_run_main_loop) ... ok
    test_simple_initialization_api (test.test_embed.EmbeddingTests.test_simple_initialization_api) ... ok
    test_specialized_static_code_gets_unspecialized_at_Py_FINALIZE (test.test_embed.EmbeddingTests.test_specialized_static_code_gets_unspecialized_at_Py_FINALIZE) ... ok
    test_subinterps_different_ids (test.test_embed.EmbeddingTests.test_subinterps_different_ids) ... ok
    test_subinterps_distinct_state (test.test_embed.EmbeddingTests.test_subinterps_distinct_state) ... ok
    test_subinterps_main (test.test_embed.EmbeddingTests.test_subinterps_main) ... ok
    test_ucnhash_capi_reset (test.test_embed.EmbeddingTests.test_ucnhash_capi_reset) ... ok
    test_get_argc_argv (test.test_embed.InitConfigTests.test_get_argc_argv) ... ok
    test_getpath_abspath_win32 (test.test_embed.InitConfigTests.test_getpath_abspath_win32) ... skipped 'specific to Windows'
    test_global_pathconfig (test.test_embed.InitConfigTests.test_global_pathconfig) ... ok
    test_init_compat_config (test.test_embed.InitConfigTests.test_init_compat_config) ... ok
    test_init_compat_env (test.test_embed.InitConfigTests.test_init_compat_env) ... ok
    test_init_default_config (test.test_embed.InitConfigTests.test_init_default_config) ... ok
    test_init_dev_mode (test.test_embed.InitConfigTests.test_init_dev_mode) ... ok
    test_init_dont_configure_locale (test.test_embed.InitConfigTests.test_init_dont_configure_locale) ... ok
    test_init_dont_parse_argv (test.test_embed.InitConfigTests.test_init_dont_parse_argv) ... ok
    test_init_env_dev_mode (test.test_embed.InitConfigTests.test_init_env_dev_mode) ... ok
    test_init_env_dev_mode_alloc (test.test_embed.InitConfigTests.test_init_env_dev_mode_alloc) ... ok
    test_init_from_config (test.test_embed.InitConfigTests.test_init_from_config) ... ok
    test_init_global_config (test.test_embed.InitConfigTests.test_init_global_config) ... ok
    test_init_is_python_build_with_home (test.test_embed.InitConfigTests.test_init_is_python_build_with_home) ... ok
    test_init_isolated_config (test.test_embed.InitConfigTests.test_init_isolated_config) ... ok
    test_init_isolated_flag (test.test_embed.InitConfigTests.test_init_isolated_flag) ... ok
    test_init_main (test.test_embed.InitConfigTests.test_init_main) ... ok
    test_init_main_interpreter_settings (test.test_embed.InitConfigTests.test_init_main_interpreter_settings) ... ok
    test_init_parse_argv (test.test_embed.InitConfigTests.test_init_parse_argv) ... ok
    test_init_pybuilddir (test.test_embed.InitConfigTests.test_init_pybuilddir) ... ok
    test_init_pybuilddir_win32 (test.test_embed.InitConfigTests.test_init_pybuilddir_win32) ... skipped 'See test_init_pybuilddir'
    test_init_python_config (test.test_embed.InitConfigTests.test_init_python_config) ... ok
    test_init_python_env (test.test_embed.InitConfigTests.test_init_python_env) ... ok
    test_init_pyvenv_cfg (test.test_embed.InitConfigTests.test_init_pyvenv_cfg) ... ok
    test_init_read_set (test.test_embed.InitConfigTests.test_init_read_set) ... skipped 'as of 3.11 this test no longer works because path calculations do not occur on read'
    test_init_run_main (test.test_embed.InitConfigTests.test_init_run_main) ... ok
    test_init_set_config (test.test_embed.InitConfigTests.test_init_set_config) ... ok
    test_init_setpath (test.test_embed.InitConfigTests.test_init_setpath) ... ok
    test_init_setpath_config (test.test_embed.InitConfigTests.test_init_setpath_config) ... ok
    test_init_setpythonhome (test.test_embed.InitConfigTests.test_init_setpythonhome) ... ok
    test_init_sys_add (test.test_embed.InitConfigTests.test_init_sys_add) ... ok
    test_init_use_frozen_modules (test.test_embed.InitConfigTests.test_init_use_frozen_modules) ... ok
    test_init_warnoptions (test.test_embed.InitConfigTests.test_init_warnoptions) ... ok
    test_preinit_compat_config (test.test_embed.InitConfigTests.test_preinit_compat_config) ... ok
    test_preinit_dont_parse_argv (test.test_embed.InitConfigTests.test_preinit_dont_parse_argv) ... ok
    test_preinit_isolated1 (test.test_embed.InitConfigTests.test_preinit_isolated1) ... ok
    test_preinit_isolated2 (test.test_embed.InitConfigTests.test_preinit_isolated2) ... ok
    test_preinit_isolated_config (test.test_embed.InitConfigTests.test_preinit_isolated_config) ... ok
    test_preinit_parse_argv (test.test_embed.InitConfigTests.test_preinit_parse_argv) ... ok
    test_preinit_python_config (test.test_embed.InitConfigTests.test_preinit_python_config) ... ok
    test_frozenmain (test.test_embed.MiscTests.test_frozenmain) ... ok
    test_no_memleak (test.test_embed.MiscTests.test_no_memleak) ... skipped '-X showrefcount requires a Python debug build'
    test_unicode_id_init (test.test_embed.MiscTests.test_unicode_id_init) ... ok
    test_set_config (test.test_embed.SetConfigTests.test_set_config) ... ok
    test_disallow_instantiation (test.test_embed.StdPrinterTests.test_disallow_instantiation) ... ok
    test_methods (test.test_embed.StdPrinterTests.test_methods) ... ok
    test_write (test.test_embed.StdPrinterTests.test_write) ... ok
    
    ----------------------------------------------------------------------
    Ran 69 tests in 5.428s
    
    OK (skipped=4)
    
    == Tests result: SUCCESS ==
    
    1 test OK.
    
    Total duration: 5.5 sec
    Total tests: run=69 skipped=4
    Total test files: run=1/1
    Result: SUCCESS
    
  16. vstinner commented on Oct 11, 2023

    @vstinner
    Member

    Can you reproduce the issue without PGO, just with LTO? In short, does the following command reproduce your issue?

    CC=clang ./configure --with-lto=full && make && ./python -m test test_embed -v
    

    On Fedora 38 with clang 16 (clang version 16.0.6 (Fedora 16.0.6-3.fc38)), I get:

    $ CC=clang LD=clang ./configure --with-lto=full
    $ grep NOLTO= Makefile
    CONFIGURE_LDFLAGS_NOLTO=-flto=thin
    PY_LDFLAGS_NOLTO=$(PY_LDFLAGS) $(CONFIGURE_LDFLAGS_NOLTO) $(LDFLAGS_NODIST)
    
    $ make
    
    $ ./Programs/_testembed test_audit; echo $?
    0
    $ ./python -m test test_embed 
    (...)
    Total duration: 2.9 sec
    Total tests: run=69 skipped=4
    Total test files: run=1/1
    Result: SUCCESS
    

    The NOLTO value comes from configure.ac:

    if test "$Py_LTO" = 'true' ; then
      case $CC in
        *clang*)
          LDFLAGS_NOLTO="-fno-lto"
          dnl Clang linker requires -flto in order to link objects with LTO information.
          dnl Thin LTO is faster and works for object files with full LTO information, too.
          AX_CHECK_COMPILE_FLAG([-flto=thin],[LDFLAGS_NOLTO="-flto=thin"],[LDFLAGS_NOLTO="-flto"])
    
  17. changed the title [-]PGO: test_embed fails which causes python build to fail[/-] [+]test_embed fails if Python is built with LTO=fulll and LLVM clang 17[/+] on Oct 11, 2023
  18. changed the title [-]test_embed fails if Python is built with LTO=fulll and LLVM clang 17[/-] [+]test_embed fails if Python is built with LTO=full and LLVM clang 17[/+] on Oct 11, 2023
  19. vstinner commented on Oct 11, 2023

    @vstinner
    Member

    @mdboom:

    We are running into this bug on the CPython benchmarking infrastructure, too. git bisect says the first bad commit is 6ab6040.

    What is your macOS version? What is your LLVM clang version?

  20. vstinner commented on Oct 11, 2023

    @vstinner
    Member

    I found the problem. The offending commit is 3e3a7da.

    Great bisection, that's very helpful, thanks a lot!

  21. debohman commented on Oct 11, 2023

    @debohman
    ContributorAuthor

    Can you reproduce the issue without PGO, just with LTO? In short, does the following command reproduce your issue?

    I was testing with LTO and without PGO, now I am rebuilding with LTO and PGO.

  22. vstinner commented on Oct 11, 2023

    @vstinner
    Member

    I was testing with LTO and without PGO

    Ok, so the issue only comes from LTO=full.

  23. debohman commented on Oct 11, 2023

    @debohman
    ContributorAuthor

    It seems to be the embedding that is somehow tripped up by this.

  24. debohman commented on Oct 11, 2023

    @debohman
    ContributorAuthor

    I don't think we have established that LLVM 17 is the problem. To do that we would need to try building with LLVM 16.

  25. debohman commented on Oct 11, 2023

    @debohman
    ContributorAuthor

    Building with PGO and LTO are fine now.

  26. vstinner commented on Oct 11, 2023

    @vstinner
    Member

    Test on Fedora Rawhide with LLVM clang 17:

    $ CC=clang LD=clang ./configure --with-lto=full
    $ make -j10 
    
    $ ./Programs/_testembed test_audit; echo $?
    0
    
    $ ./python -m test test_embed 
    (...)
    Total duration: 4.7 sec
    Total tests: run=69 skipped=4
    Total test files: run=1/1
    Result: SUCCESS
    

    It works as expected. By the way, PGO+LTO build is tested on Fedora Rawhide on multiple architectures:

  27. vstinner commented on Oct 11, 2023

    @vstinner
    Member

    Building with PGO and LTO are fine now.

    Would you mind to elaborate "now"? Before you wrote that it didn't work. What changed? Are you still testing the latest main branch?

    You're doing tests on macOS 10.12.6 with Clang 17.0.1, right?

  28. changed the title [-]test_embed fails if Python is built with LTO=full and LLVM clang 17[/-] [+]test_embed fails if Python is built with LTO=full and LLVM clang 17 on macOS[/+] on Oct 11, 2023
  29. vstinner commented on Oct 11, 2023

    @vstinner
    Member

    I don't think we have established that LLVM 17 is the problem.

    I added "on macOS" to the issue title :-)

  30. debohman commented on Oct 11, 2023

    @debohman
    ContributorAuthor

    Building with PGO and LTO are fine now.

    Would you mind to elaborate "now"? Before you wrote that it didn't work. What changed? Are you still testing the latest main branch?

    You're doing tests on macOS 10.12.6 with Clang 17.0.1, right?

    Sorry, with 3e3a7da reverted.

  31. vstinner commented on Oct 11, 2023

    @vstinner
    Member

    To do that we would need to try building with LLVM 16.

    If you can run your test with LLVM 16 on macOS, that would be nice yes, since I fail to reproduce the issue on Linux with LLVM 17.

  32. debohman commented on Oct 11, 2023

    @debohman
    ContributorAuthor

    To do that we would need to try building with LLVM 16.

    If you can run your test with LLVM 16 on macOS, that would be nice yes, since I fail to reproduce the issue on Linux with LLVM 17.

    Yes, I will try that, but it will have to be later. It is past dinnertime now.

  33. debohman commented on Oct 11, 2023

    @debohman
    ContributorAuthor

    The issue exists when building with LLVM 16, and backing out commit 3e3a7da resolves it.

  34. vstinner commented on Oct 11, 2023

    @vstinner
    Member

    @corona10: Should we just give up on the "NOLTO" idea, building some object files with LTO (full) or then attempt to use a different LTO mode (thin) to link them? Nor only revert 3e3a7da but also remove NOLTO variables.

  35. corona10 commented on Oct 11, 2023

    @corona10
    Member

    This is on macOS 10.12.6, building with LLVM / Clang 17.0.1. The system otherwise has Python 3.11.6 installed.

    @debohman Are you using a custom compiler toolchain rather than using the Apple basic toolchain?

  36. corona10 commented on Oct 11, 2023

    @corona10
    Member

    Nor only revert 3e3a7da but also remove NOLTO variables.

    I am okay with reverting the PR, IIUC it was just intended to speed up the build, but I need to know what effect will occur if drop the "NOLTO" idea.

  37. corona10 commented on Oct 11, 2023

    @corona10
    Member

    If we drop the "NOLTO" idea, it will occur #96761 again. Please let me know If I misunderstand.

  38. corona10 commented on Oct 11, 2023

    @corona10
    Member

    Or do you intend to revert #29859 too?

  39. debohman commented on Oct 11, 2023

    @debohman
    ContributorAuthor

    This is on macOS 10.12.6, building with LLVM / Clang 17.0.1. The system otherwise has Python 3.11.6 installed.

    @debohman Are you using a custom compiler toolchain rather than using the Apple basic toolchain?

    The stock linker is being used, the rest of the toolchain is the newer llvm / clang.

  40. mdboom commented on Oct 11, 2023

    @mdboom
    Contributor

    What is your macOS version? What is your LLVM clang version?

    It's macOS 13.6

    % clang --version
    Apple clang version 14.0.3 (clang-1403.0.22.14.1)
    Target: arm64-apple-darwin22.6.0
    Thread model: posix
    InstalledDir: /Library/Developer/CommandLineTools/usr/bin
    % uname -a
    Darwin CPythons-Mac-mini.local 22.6.0 Darwin Kernel Version 22.6.0: Fri Sep 15 13:41:30 PDT 2023; root:xnu-8796.141.3.700.8~1/RELEASE_ARM64_T8103 arm64
    

    I'm building CPython as follows:

    ./configure --with-openssl=$(brew --prefix openssl) --enable-optimizations --with-lto
    make -j
    
  41. mdboom commented on Oct 11, 2023

    @mdboom
    Contributor

    I can confirm that backing out 3e3a7da also resolves things for me.

  42. added a commit that references this issue on Oct 11, 2023
  43. vstinner commented on Oct 11, 2023

    @vstinner
    Member

    I wrote PR #110720 to revert my "NoLTO" change which introduced the bug.

    I don't understand exactly why/how Programs/_testembed is miscompiled on macOS using LLVM 16 or 17, but it's bad: we should not miscompile Python. My change was just to optimize "build Python" command faster (run make), it should not miscompile Python.

    It would be nice if someone can dig into the issue, but I don't have the bandwidth for that. I cannot reproduce the issue on Linux, and I don't have access to any macOS machine.

  44. added a commit that references this issue on Oct 11, 2023
  45. changed the title [-]test_embed fails if Python is built with LTO=full and LLVM clang 17 on macOS[/-] [+]test_embed fails if Python is built with LTO and LLVM clang on macOS[/+] on Oct 11, 2023
  46. debohman commented on Oct 11, 2023

    @debohman
    ContributorAuthor

    If I may hazard a guess as to why this is failing, we seem to be using objects built with LTO and linking them to create Programs/_testembed without LTO. Perhaps if you wish to to build _testembed without LTO, then you need a set of object files built without any LTO. Note that everything works fine when building Python without any LTO.

    In the case which fails, the generated _testembed contains no symbols, so when it tries to runtime load a module, it fails because it cannot resolve the undefined symbols in the module.

  47. vstinner commented on Oct 12, 2023

    @vstinner
    Member

    I suppose that the best way to build with LTO only once instead of 3 times (freeze, testembed, libpython) is to use ./configure --enable-shared. So most object files are only linked once into libpython, and then libpython is reused in freeze and testembed.

    If I recall correctly, GCC implementation of LTO is very different and so the NOLTO hack to reduce build time when enable-shared is not used still works. Maybe we just use -flto=full in NOLTO on macOS (when cland is used).

  48. debohman commented on Nov 6, 2023

    @debohman
    ContributorAuthor

    Shall we close this issue? I have successfully built 3.13.0a1 and current main with both PGO and LTO.

  49. debohman commented on Nov 6, 2023

    @debohman
    ContributorAuthor

    I am also using the latest Clang 17.0.4.

  50. vstinner commented on Nov 6, 2023

    @vstinner
    Member

    Ok, I close the issue.

  51. added a commit that references this issue on Sep 2, 2024
  52. Abhaygarg656 commented on Oct 14, 2024

    @Abhaygarg656
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    type-bugAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions