CMS 3D CMS Logo

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