Skip to content

Instantly share code, notes, and snippets.

@bslatkin
Created February 19, 2022 22:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bslatkin/49f31092a2a193bc152cd8d4d5d6414e to your computer and use it in GitHub Desktop.
Save bslatkin/49f31092a2a193bc152cd8d4d5d6414e to your computer and use it in GitHub Desktop.
Minimal bug reproduction case in the interaction of ctypes.Union with llvmlite
"""
# These are the values I see on my system that reproduces the bug:
$ uname -a
Darwin silver-surfer.lan 21.3.0 Darwin Kernel Version 21.3.0: Wed Jan 5 21:37:58 PST 2022; root:xnu-8019.80.24~20/RELEASE_X86_64 x86_64
$ /usr/local/Cellar/llvm@11/11.1.0_4/bin/clang -v
Homebrew clang version 11.1.0
Target: x86_64-apple-darwin21.3.0
Thread model: posix
InstalledDir: /usr/local/Cellar/llvm@11/11.1.0_4/bin
$ python3 -c 'import sys; print(sys.version)'
3.9.10 (main, Jan 15 2022, 11:48:04)
[Clang 13.0.0 (clang-1300.0.29.3)]
$ cat requirements.txt
llvmlite==0.38.0
$ python3 ./llvmlite_ctypes_bug.py
Target triple:
x86_64-apple-darwin21.3.0
Target machine data layout:
e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128
Abort trap: 6
"""
import ctypes
from llvmlite import binding
class MyValueType(ctypes.Union):
_fields_ = [
('a', ctypes.c_int64),
('b', ctypes.c_int64),
('c', ctypes.c_int64),
('d', ctypes.c_int64),
# Comment out or remove the following line and it works.
('e', ctypes.c_int64),
]
def main():
binding.initialize()
binding.initialize_native_target()
binding.initialize_native_asmprinter()
binding.check_jit_execution()
assembly = """
%struct.MyValue = type { i64 }
define %struct.MyValue @my_function() {
ret %struct.MyValue { i64 123 }
}
"""
module_ref = binding.parse_assembly(assembly)
target = binding.Target.from_default_triple()
target_machine = target.create_target_machine()
print(f'Target triple:\n{target.triple}')
print(f'Target machine data layout:\n{target_machine.target_data}')
engine = binding.create_mcjit_compiler(module_ref, target_machine)
engine.finalize_object()
func_addr = engine.get_function_address('my_function')
func_type = ctypes.CFUNCTYPE(MyValueType)
func_ptr = func_type(func_addr)
result = func_ptr()
print(result.a)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment