check-static-inits.py (1807B)
1 #!/usr/bin/env python3 2 3 import glob 4 import os 5 import re 6 import shutil 7 import subprocess 8 import sys 9 10 srcdir = sys.argv[1] 11 base_srcdir = sys.argv[2] 12 builddir = sys.argv[3] 13 14 objdump = os.getenv("OBJDUMP", shutil.which("objdump")) 15 if not objdump: 16 print("check-static-inits.py: 'ldd' not found; skipping test") 17 sys.exit(77) 18 19 if sys.version_info < (3, 5): 20 print("check-static-inits.py: needs python 3.5 for recursive support in glob") 21 sys.exit(77) 22 23 OBJS = glob.glob(os.path.join(builddir, "**", "*hb*.o"), recursive=True) 24 if not OBJS: 25 print("check-static-inits.py: object files not found; skipping test") 26 sys.exit(77) 27 28 stat = 0 29 tested = False 30 31 print("Checking that the following object files has no static initializers/finalizers") 32 print("\n".join(OBJS)) 33 34 result = subprocess.run( 35 objdump.split() + ["-t"] + OBJS, stdout=subprocess.PIPE, stderr=subprocess.PIPE 36 ) 37 38 if result.returncode: 39 if result.stderr.find(b"not recognized") != -1: 40 # https://github.com/harfbuzz/harfbuzz/issues/3019 41 print('objdump returned "not recognized", skipping') 42 else: 43 print("objdump returned error:\n%s" % (result.stderr.decode("utf-8"))) 44 stat = 2 45 else: 46 tested = True 47 48 result = result.stdout.decode("utf-8") 49 50 # Checking that no object file has static initializers 51 for lib in re.findall(r"^.*\.[cd]tors.*$", result, re.MULTILINE): 52 if not re.match(r".*\b0+\b", lib): 53 print("Ouch, library has static initializers/finalizers") 54 stat = 1 55 56 # Checking that no object file has lazy static C++ constructors/destructors or other such stuff 57 if ("__cxa_" in result) and ("__ubsan_handle" not in result): 58 print( 59 "Ouch, library has lazy static C++ constructors/destructors or other such stuff" 60 ) 61 stat = 1 62 63 64 sys.exit(stat if tested else 77)