File indexing completed on 2023-03-17 11:26:51
0001
0002 from __future__ import print_function
0003 import fileinput
0004 import networkx as nx
0005 import re
0006 datacl = re.compile("^class ")
0007 bfunc = re.compile("^function ")
0008 mbcl = re.compile("(base|data) class")
0009 farg = re.compile(r"(.*)\(\w+\)")
0010 nsep = re.compile(r"\:\:")
0011 topfunc = re.compile(
0012 r"::(produce|analyze|filter|beginLuminosityBlock|beginRun|beginStream)\(")
0013 baseclass = re.compile(
0014 r"edm::(one::|stream::|global::)?ED(Producer|Filter|Analyzer)(Base)?")
0015 getfunc = re.compile(
0016 r"edm::eventsetup::EventSetupRecord::get\<.*\>\((.*)&\) const")
0017 handle = re.compile("(.*),?class edm::ES(.*)Handle<(.*)>")
0018 skip = re.compile(
0019 "edm::serviceregistry::ServicesManager::MakerHolder::add() const")
0020 statics = set()
0021 toplevelfuncs = set()
0022 onefuncs = set()
0023 dataclassfuncs = set()
0024 virtfuncs = set()
0025 virtclasses = set()
0026 badfuncs = set()
0027 badclasses = set()
0028 esdclasses = set()
0029 dclasses = set()
0030 dataclasses = set()
0031 flaggedclasses = set()
0032 G = nx.DiGraph()
0033 H = nx.DiGraph()
0034
0035 f = open('classes.txt.dumperft')
0036 for line in f:
0037 if datacl.search(line):
0038 classname = line.split("'")[1]
0039 dclasses.add(classname)
0040 f.close()
0041
0042 f = open('classes.txt.inherits')
0043 for line in f:
0044 if datacl.search(line):
0045 classname = line.split("'")[1]
0046 dataclasses.add(classname)
0047 f.close()
0048
0049
0050 f = open('class-checker.txt')
0051 for line in f:
0052 if mbcl.search(line):
0053 fields = line.split("'")
0054 classname = fields[1]
0055 funcname = fields[3]
0056 badclasses.add(classname)
0057 badfuncs.add(funcname)
0058 f.close()
0059
0060
0061 f = open('classes.txt.dumperall')
0062 for line in f:
0063 if mbcl.search(line):
0064 fields = line.split("'")
0065 if fields[2] == ' member data class ':
0066 H.add_edge(fields[1], fields[3], kind=fields[2])
0067 if fields[2] == ' templated member data class ':
0068 H.add_edge(fields[1], fields[3], kind=fields[2])
0069 if fields[2] == ' base class ':
0070 H.add_edge(fields[1], fields[3], kind=fields[2])
0071 f.close()
0072
0073
0074 for line in fileinput.input(files=('function-statics-db.txt', 'function-calls-db.txt')):
0075 if not bfunc.search(line):
0076 continue
0077 fields = line.split("'")
0078 if skip.search(fields[1]) or skip.search(fields[3]):
0079 continue
0080 if fields[2] == ' calls function ':
0081 G.add_edge(fields[1], fields[3], kind=' calls function ')
0082 if getfunc.search(fields[3]):
0083 dataclassfuncs.add(fields[3])
0084 m = getfunc.match(fields[3])
0085 n = handle.match(m.group(1))
0086 if n:
0087 o = n.group(3)
0088 else:
0089 o = m.group(1)
0090 p = re.sub("class ", "", o)
0091 dataclass = re.sub("struct ", "", p)
0092 dataclasses.add(dataclass)
0093 if fields[2] == ' overrides function ':
0094 if baseclass.search(fields[3]):
0095 G.add_edge(fields[1], fields[3], kind=' overrides function ')
0096 if topfunc.search(fields[3]):
0097 toplevelfuncs.add(fields[1])
0098 else:
0099 G.add_edge(fields[3], fields[1], kind=' calls override function ')
0100 if fields[2] == ' static variable ':
0101 G.add_edge(fields[1], fields[3], kind=' static variable ')
0102 statics.add(fields[3])
0103 fileinput.close()
0104
0105 for n, nbrdict in G.adjacency():
0106 for nbr, eattr in nbrdict.items():
0107 if n in badfuncs or nbr in badfuncs:
0108 if 'kind' in eattr and eattr['kind'] == ' overrides function ':
0109 print("'"+n+"'"+eattr['kind']+"'"+nbr+"'")
0110 virtfuncs.add(nbr)
0111 print()
0112
0113 for n, nbrdict in H.adjacency():
0114 for nbr, eattr in nbrdict.items():
0115 if n in badclasses and 'kind' in eattr and eattr['kind'] == ' base class ':
0116 virtclasses.add(nbr)
0117
0118
0119 for n, nbrdict in H.adjacency():
0120 for nbr, eattr in nbrdict.items():
0121 if nbr in dclasses and 'kind' in eattr and eattr['kind'] == ' base class ':
0122 dclasses.add(n)
0123
0124 print("flagged functions found by checker")
0125 for dfunc in sorted(badfuncs):
0126 print(dfunc)
0127 print()
0128
0129 print("flagged classes found by checker ")
0130 for dclass in sorted(badclasses):
0131 print(dclass)
0132 print()
0133
0134 print("flagged classes found by checker union get")
0135 for dclass in sorted(dclasses.intersection(badclasses)):
0136 print(dclass)
0137 print()
0138
0139
0140 print("classes inheriting from flagged classes")
0141 for dclass in sorted(virtclasses):
0142 print(dclass)
0143 print()
0144
0145 print("functions overridden by flagged functions")
0146 for dfunc in sorted(virtfuncs):
0147 print(dfunc)
0148 print()
0149
0150
0151 for badclass in sorted(badclasses):
0152 print("Event setup data class '"+badclass+"' is flagged.")
0153 flaggedclasses.add(badclass)
0154 print()
0155
0156 for virtclass in sorted(virtclasses):
0157 print("Event setup data class '"+virtclass +
0158 "' is flagged because inheriting class is flagged")
0159 flaggedclasses.add(virtclass)
0160 print()
0161
0162 for badclass in sorted(badclasses):
0163 for dataclass in sorted(dataclasses):
0164 if H.has_node(badclass) and H.has_node(dataclass):
0165 if nx.has_path(H, dataclass, badclass):
0166 print("Event setup data class '" + dataclass +
0167 "' contains or inherits from flagged class '" + badclass + "'.")
0168 flaggedclasses.add(dataclass)
0169
0170 print()
0171
0172
0173 for dataclassfunc in sorted(dataclassfuncs):
0174 for tfunc in sorted(toplevelfuncs):
0175 if G.has_node(tfunc) and G.has_node(dataclassfunc) and nx.has_path(G, tfunc, dataclassfunc):
0176 m = getfunc.match(dataclassfunc)
0177 n = handle.match(m.group(1))
0178 if n:
0179 o = n.group(3)
0180 else:
0181 o = m.group(1)
0182 p = re.sub("class ", "", o)
0183 q = re.sub("struct ", "", p)
0184 dataclass = re.sub(r"\<.*\> ", "", q)
0185 for flaggedclass in sorted(flaggedclasses):
0186 exact = r"^" + re.escape(flaggedclass) + r"$"
0187 exactmatch = re.match(exact, dataclass)
0188 if exactmatch:
0189 print("Flagged event setup data class '"+dataclass +
0190 "' is accessed in call stack '", end=' ')
0191 path = nx.shortest_path(G, tfunc, dataclassfunc)
0192 for p in path:
0193 print(p+"; ", end=' ')
0194 print("' ", end=' ')
0195 for key in G[tfunc].keys():
0196 if 'kind' in G[tfunc][key] and G[tfunc][key]['kind'] == ' overrides function ':
0197 print("'"+tfunc+"'"+G[tfunc][key]
0198 ['kind']+"'"+key+"'", end=' ')
0199 print("")
0200 print("In call stack '", end=' ')
0201 path = nx.shortest_path(G, tfunc, dataclassfunc)
0202 for p in path:
0203 print(p+"; ", end=' ')
0204 print("' flagged event setup data class '" +
0205 dataclass+"' is accessed. ", end=' ')
0206 for key in G[tfunc].keys():
0207 if 'kind' in G[tfunc][key] and G[tfunc][key]['kind'] == ' overrides function ':
0208 print("'"+tfunc+"'"+G[tfunc][key]
0209 ['kind']+"'"+key+"'", end=' ')
0210 print("")