CMS 3D CMS Logo

symbols.py
Go to the documentation of this file.
1 #! /usr/bin/env python
2 
3 from __future__ import print_function
4 import collections
5 import os
6 import re
7 import subprocess
8 
9 addr_re = r"(?P<address>[0-9a-f]{1,16})?"
10 code_re = r"(?P<code>[a-zA-Z])"
11 symbol_re = r"(?P<symbol>[a-zA-Z0-9_.$@]+)"
12 symbol_demunged_re = r"(?P<symbol>[a-zA-Z0-9_.$@:&()<>{}\[\]|^!%,~*+-=# ]+)"
13 symbols_re_skip = re.compile("(@@)")
14 nm_line_re = re.compile(r"\s+".join([addr_re, code_re, symbol_re]) + "\s*$",
15  re.I)
16 ldd_line_re = re.compile(r"\s+(.*) => (.*) \(0x")
17 
18 requires = collections.defaultdict(set)
19 provides = collections.defaultdict(set)
20 dependencies = collections.defaultdict(set)
21 libraries = collections.defaultdict(set)
22 
23 def get_symbols(fname):
24  lines = subprocess.check_output(["nm", "-g", fname])
25  for l in lines.splitlines():
26  m = nm_line_re.match(l)
27  if not m : continue
28  symbol = m.group('symbol')
29  if m.group('code') == 'U':
30  requires[os.path.basename(fname)].add(symbol)
31  else:
32  provides[symbol].add(os.path.basename(fname))
33 
34 def get_libraries(fname):
35  lines = subprocess.check_output(["ldd",fname])
36  for l in lines.splitlines():
37  m = ldd_line_re.match(l)
38  if not m: continue
39  library = m.group(2)
40  libraries[os.path.basename(fname)].add(os.path.basename(library.rstrip('\r\n')))
41 
42 
43 paths=os.environ['LD_LIBRARY_PATH'].split(':')
44 
45 for p in paths:
46  for dirpath, dirnames, filenames in os.walk(p):
47  for f in filenames:
48  fpth=os.path.realpath(os.path.join(dirpath,f))
49  filetype = subprocess.check_output(["file", fpth])
50  if filetype.find("dynamically linked") >= 0 :
51  get_symbols(fpth)
52  get_libraries(fpth)
53 
54 for fname, symbols in requires.items():
55  deps=set()
56  for library in libraries[fname]:
57  for s in symbols :
58  if library in provides[s] : deps.add(library)
59  dependencies[fname]=deps
60  print(fname + ' : primary dependencies : ' + ', '.join(sorted(dependencies[fname]))+'\n')
61  unmet = set()
62  demangled = set()
63  for s in symbols:
64  if s not in provides and not symbols_re_skip.search(s) : unmet.add(s)
65  for u in sorted(unmet):
66  dm = subprocess.check_output(["c++filt",u])
67  demangled.add(dm.rstrip('\r\n'))
68  if demangled : print(fname + ': undefined : ' + ', '.join(sorted(demangled)))
69 
70 import networkx as nx
71 G=nx.DiGraph()
72 for key,values in dependencies.items():
73  G.add_node(key)
74  for val in values: G.add_edge(key,val)
75 
76 for node in nx.nodes_iter(G):
77  s = nx.dfs_successors(G,node)
78  deps=set()
79  if s :
80  for key,vals in s.items() :
81  if key != node : deps.add(key)
82  for v in vals :
83  deps.add(v)
84  print(node + ': primary and secondary dependencies :' + ', '.join(sorted(deps)))
85 
86 import pydot
87 
88 H=nx.DiGraph()
89 for key,values in dependencies.items():
90  H.add_node(os.path.basename(key))
91  for val in values: H.add_edge(os.path.basename(key),os.path.basename(val))
92 for node in nx.nodes_iter(H):
93  T = nx.dfs_tree(H,node)
94  name = node + ".dot"
95  nx.write_dot(T,name)
symbols.get_symbols
def get_symbols(fname)
Definition: symbols.py:23
join
static std::string join(char **cmd)
Definition: RemoteFile.cc:17
cms::dd::split
std::vector< std::string_view > split(std::string_view, const char *)
symbols.get_libraries
def get_libraries(fname)
Definition: symbols.py:34
PVValHelper::add
void add(std::map< std::string, TH1 * > &h, TH1 *hist)
Definition: PVValidationHelpers.cc:12
edm::print
S & print(S &os, JobReport::InputFile const &f)
Definition: JobReport.cc:66