diff options
author | 2020-10-22 18:42:51 -0600 | |
---|---|---|
committer | 2020-10-22 18:42:51 -0600 | |
commit | 345cd37abe324ad4f60f80e2c3133b8849e54e9b (patch) | |
tree | 5d965e662dca9dcac19e7eddd63a3d9d0b816fed /Tools/c-analyzer/c_analyzer/symbols/_nm.py | |
parent | bpo-38486: Fix dead qmail links in the mailbox docs (GH-22239) (diff) | |
download | cpython-345cd37abe324ad4f60f80e2c3133b8849e54e9b.tar.gz cpython-345cd37abe324ad4f60f80e2c3133b8849e54e9b.tar.bz2 cpython-345cd37abe324ad4f60f80e2c3133b8849e54e9b.zip |
bpo-36876: Fix the C analyzer tool. (GH-22841)
The original tool wasn't working right and it was simpler to create a new one, partially re-using some of the old code. At this point the tool runs properly on the master. (Try: ./python Tools/c-analyzer/c-analyzer.py analyze.) It take ~40 seconds on my machine to analyze the full CPython code base.
Note that we'll need to iron out some OS-specific stuff (e.g. preprocessor). We're okay though since this tool isn't used yet in our workflow. We will also need to verify the analysis results in detail before activating the check in CI, though I'm pretty sure it's close.
https://bugs.python.org/issue36876
Diffstat (limited to 'Tools/c-analyzer/c_analyzer/symbols/_nm.py')
-rw-r--r-- | Tools/c-analyzer/c_analyzer/symbols/_nm.py | 117 |
1 files changed, 0 insertions, 117 deletions
diff --git a/Tools/c-analyzer/c_analyzer/symbols/_nm.py b/Tools/c-analyzer/c_analyzer/symbols/_nm.py deleted file mode 100644 index f3a75a6d4ba..00000000000 --- a/Tools/c-analyzer/c_analyzer/symbols/_nm.py +++ /dev/null @@ -1,117 +0,0 @@ -import os.path -import shutil - -from c_analyzer.common import util, info - -from .info import Symbol - - -# XXX need tests: -# * iter_symbols - -NM_KINDS = { - 'b': Symbol.KIND.VARIABLE, # uninitialized - 'd': Symbol.KIND.VARIABLE, # initialized - #'g': Symbol.KIND.VARIABLE, # uninitialized - #'s': Symbol.KIND.VARIABLE, # initialized - 't': Symbol.KIND.FUNCTION, - } - -SPECIAL_SYMBOLS = { - # binary format (e.g. ELF) - '__bss_start', - '__data_start', - '__dso_handle', - '_DYNAMIC', - '_edata', - '_end', - '__environ@@GLIBC_2.2.5', - '_GLOBAL_OFFSET_TABLE_', - '__JCR_END__', - '__JCR_LIST__', - '__TMC_END__', - } - - -def _is_special_symbol(name): - if name in SPECIAL_SYMBOLS: - return True - if '@@GLIBC' in name: - return True - return False - - -def iter_symbols(binfile, *, - nm=None, - handle_id=None, - _which=shutil.which, - _run=util.run_cmd, - ): - """Yield a Symbol for each relevant entry reported by the "nm" command.""" - if nm is None: - nm = _which('nm') - if not nm: - raise NotImplementedError - if handle_id is None: - handle_id = info.ID - - argv = [nm, - '--line-numbers', - binfile, - ] - try: - output = _run(argv) - except Exception: - if nm is None: - # XXX Use dumpbin.exe /SYMBOLS on Windows. - raise NotImplementedError - raise - for line in output.splitlines(): - (name, kind, external, filename, funcname, - ) = _parse_nm_line(line) - if kind != Symbol.KIND.VARIABLE: - continue - elif _is_special_symbol(name): - continue - yield Symbol( - id=handle_id(filename, funcname, name), - kind=kind, - external=external, - ) - - -def _parse_nm_line(line): - _origline = line - _, _, line = line.partition(' ') # strip off the address - line = line.strip() - - kind, _, line = line.partition(' ') - line = line.strip() - external = kind.isupper() - kind = NM_KINDS.get(kind.lower(), Symbol.KIND.OTHER) - - name, _, filename = line.partition('\t') - name = name.strip() - if filename: - filename = os.path.relpath(filename.partition(':')[0]) - else: - filename = info.UNKNOWN - - name, islocal = _parse_nm_name(name, kind) - funcname = info.UNKNOWN if islocal else None - return name, kind, external, filename, funcname - - -def _parse_nm_name(name, kind): - if kind != Symbol.KIND.VARIABLE: - return name, None - if _is_special_symbol(name): - return name, None - - actual, sep, digits = name.partition('.') - if not sep: - return name, False - - if not digits.isdigit(): - raise Exception(f'got bogus name {name}') - return actual, True |