CMS 3D CMS Logo

Functions | Variables
cmsswConfigtrace Namespace Reference

Functions

def addprefixinfo (argv)
 
def auto_inspect ()
 
def cleanupenv (tmpdir)
 
def collect_trace (thing, name, graph, parent)
 
def flatten (args)
 
def help ()
 
def main ()
 
def new_items_ (self)
 
def searchinpath (progname, path)
 
def serve_main ()
 
def setupenv ()
 
def trace_command (argv)
 
def trace_location
 
def trace_python (prog_argv, path)
 
def writeoutput (graph)
 

Variables

 ARGV0
 
 IGNORE_PACKAGES
 
 OUTFILE_TREE
 
 PREFIXINFO
 
 SERVE_PORT
 
 STRIPPATHS
 

Function Documentation

◆ addprefixinfo()

def cmsswConfigtrace.addprefixinfo (   argv)
  1. Launch and keep track of all the processes.

Definition at line 252 of file cmsswConfigtrace.py.

Referenced by main().

252 def addprefixinfo(argv):
253  cwd = os.path.abspath(os.getcwd())
254  wf = re.match(".*/(\d+\.\d+)_", cwd)
255  if wf:
256  PREFIXINFO.append("wf")
257  PREFIXINFO.append(wf.groups()[0])
258  online = re.match("(.*/)?(.*)_dqm_sourceclient-live_cfg\.py", argv[0])
259  if online:
260  PREFIXINFO.append("online")
261  PREFIXINFO.append(online.groups()[1])
262  step = re.match("(step\d+)_.*\.py", argv[0])
263  if step:
264  PREFIXINFO.append(step.groups()[0])
265  processing = re.match("step\d+_.*(RECO|ALCA|HARVEST).*\.py", argv[0])
266  if processing:
267  PREFIXINFO.append(processing.groups()[0])
268  if not PREFIXINFO:
269  PREFIXINFO.append(argv[0])
270 

◆ auto_inspect()

def cmsswConfigtrace.auto_inspect ( )

Definition at line 36 of file cmsswConfigtrace.py.

References any(), and genParticles_cff.map.

Referenced by trace_location().

36 def auto_inspect():
37  # stolen from FWCore.GuiBrowsers.EnablePSetHistory, but needs more black-list
38  stack = inspect.stack()
39  i = 0
40  while i < len(stack) and len(stack[i])>=2 and any(map(lambda p: p in stack[i][1], IGNORE_PACKAGES)):
41  i += 1
42  res = stack[i: ]
43  j = 0
44  # for the other end we only use cmsRun (instead of IGNORE_PACKAGES) to avoid
45  # cutting traces in the middle that enter and leave IGNORE_PACKAGES
46  while j < len(res) and not 'cmsRun' in res[j][1]:
47  j += 1
48  res = res[:j]
49  if len(res)>=1 and len(res[0])>=3:
50  return res
51  else:
52  return [("unknown","unknown","unknown")]
53 
bool any(const std::vector< T > &v, const T &what)
Definition: ECalSD.cc:37

◆ cleanupenv()

def cmsswConfigtrace.cleanupenv (   tmpdir)

Definition at line 282 of file cmsswConfigtrace.py.

References filterCSVwithJSON.copy, and print().

Referenced by trace_command().

282 def cleanupenv(tmpdir):
283  print("+Cleaning up ", tmpdir)
284  copy(os.environ["CMSSWCALLTREE"], ".")
285  rmtree(tmpdir)
286 
287 
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
Definition: Utilities.cc:47
def cleanupenv(tmpdir)

◆ collect_trace()

def cmsswConfigtrace.collect_trace (   thing,
  name,
  graph,
  parent 
)
  1. The logic to collect, process, and save the information from the process.

Definition at line 133 of file cmsswConfigtrace.py.

References print().

Referenced by trace_python().

133 def collect_trace(thing, name, graph, parent):
134  # thing is what to look at, graph is the output list (of child, parent tuple pairs)
135  # thing could be pretty much anything.
136  classname = thing.__class__.__name__
137  if hasattr(thing, '_trace_events'):
138  events = list(getattr(thing, '_trace_events'))
139  getattr(thing, '_trace_events')[:] = [] # erase events so we can't end up in cycles
140  for action, loc, extra in events:
141  entry = (action, classname, loc)
142  graph.append((entry, parent, name))
143 
144  # items shall be a list of tuples (type, object) of the immediate children of the thing.
145  items = []
146  if hasattr(extra, 'items_'): # for cms.Process
147  items += extra.items_()
148  if hasattr(extra, '_seq'): # for sequences and similar
149  seq = getattr(extra, '_seq')
150  if seq:
151  items += [('seqitem', x) for x in getattr(seq, '_collection')]
152  if hasattr(extra, '_tasks'): # same
153  items += [('task', x) for x in getattr(extra, '_tasks')]
154  if hasattr(extra, '_collection'): # for cms.Task
155  items += [('subtask', x) for x in getattr(extra, '_collection')]
156  if hasattr(extra, '_operand'): # for _SeqenceNegation etc.
157  items += [('operand', getattr(extra, '_operand'))]
158  if isinstance(extra, dict): # stuff that we track explicitly^
159  for key, value in extra.items():
160  if isinstance(value, list):
161  items += [(key, x) for x in value]
162  else:
163  items += [(key, value)]
164 
165  for name, child in items:
166  collect_trace(child, name, graph, entry)
167 
168  else:
169  if not thing is None:
170  print("No _trace_events found in %s.\nMaybe turn on tracing for %s?" % (thing, classname))
171  print(" Found in %s" % (parent,))
172 
173 
def collect_trace(thing, name, graph, parent)
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
Definition: Utilities.cc:47

◆ flatten()

def cmsswConfigtrace.flatten (   args)

Definition at line 70 of file cmsswConfigtrace.py.

References trace_location().

Referenced by python.rootplot.root2matplotlib.Hist2D.box(), and python.rootplot.core.divide_axes().

70 def flatten(*args):
71  # that was surprisingly hard...
72  return [x for x in args if not isinstance(x, list)] + sum(
73  [flatten(*x) for x in args if isinstance(x, list)], [])
74 

◆ help()

def cmsswConfigtrace.help ( )

Definition at line 339 of file cmsswConfigtrace.py.

References print().

Referenced by main().

339 def help():
340  print("Usage: %s <some cmssw commandline>" % (sys.argv[0]))
341  print(" The given programs will be executed, instrumenting calls to cmsRun.")
342  print(" cmsRun will not actually run cmssw, but all the Python code will be executed and instrumentd. The results are written to the file `%s` in the same directory." % OUTFILE_TREE)
343  print(" The callgraph output lists edges pointing from each function to the one calling it.")
344  print(" To view the results using a simple webpage, use\n %s serve" % sys.argv[0])
345  print("Examples:")
346  print(" %s runTheMatrix.py -l 1000 --ibeos" % sys.argv[0])
347 
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
Definition: Utilities.cc:47

◆ main()

def cmsswConfigtrace.main ( )

Definition at line 348 of file cmsswConfigtrace.py.

References addprefixinfo(), help(), print(), trace_command(), and trace_python().

348 def main():
349  print("+Running cmsswConfigtrace...")
350  global ARGV0
351  ARGV0 = sys.argv[0]
352  if sys.argv[0].endswith('cmsRun'):
353  print("+Wrapping cmsRun...")
354  addprefixinfo(sys.argv[1:])
355  STRIPPATHS.append(os.environ["CMSSWCALLBASE"])
356  trace_python(sys.argv[1:], ["."])
357  return
358  if len(sys.argv) <= 1:
359  help()
360  return
361  # else
362  print("+Running command with tracing %s..." % sys.argv[1:])
363  trace_command(sys.argv[1:])
364 
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
Definition: Utilities.cc:47
def trace_python(prog_argv, path)

◆ new_items_()

def cmsswConfigtrace.new_items_ (   self)

Definition at line 109 of file cmsswConfigtrace.py.

References mps_monitormerge.items, and mkLumiAveragedPlots.tuple.

109 def new_items_(self):
110  items = []
111  if self.source:
112  items += [("source", self.source)]
113  if self.looper:
114  items += [("looper", self.looper)]
115  #items += self.moduleItems_()
116  items += self.outputModules.items()
117  #items += self.sequences.items() # TODO: we don't need sequences that are not paths?
118  items += self.paths.items()
119  items += self.endpaths.items()
120  items += self.services.items()
121  items += self.es_producers.items()
122  items += self.es_sources.items()
123  items += self.es_prefers.items()
124  #items += self.psets.items()
125  #items += self.vpsets.items()
126  if self.schedule:
127  items += [("schedule", self.schedule)]
128  return tuple(items)
129 Process.items_=new_items_
130 

◆ searchinpath()

def cmsswConfigtrace.searchinpath (   progname,
  path 
)

Definition at line 326 of file cmsswConfigtrace.py.

References print().

Referenced by trace_python().

326 def searchinpath(progname, path):
327  # Search $PATH. There seems to be no pre-made function for this.
328  for entry in path:
329  file_path = os.path.join(entry, progname)
330  if os.path.isfile(file_path):
331  break
332  if not os.path.isfile(file_path):
333  print("+Cannot find program (%s) in modified $PATH (%s)." % (progname, path))
334  sys.exit(1)
335  print("+Found %s as %s in %s." % (progname, file_path, path))
336  return file_path
337 
338 
def searchinpath(progname, path)
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
Definition: Utilities.cc:47

◆ serve_main()

def cmsswConfigtrace.serve_main ( )
  1. The web-based GUI.

Definition at line 367 of file cmsswConfigtrace.py.

References mps_setup.append, ALCARECOTkAlBeamHalo_cff.filter, EcalMonitorTask_cff.func, createfilelist.int, join(), print(), python.rootplot.root2matplotlib.replace(), str, and writeEcalDQMStatus.write.

367 def serve_main():
368  # we use STRIPPATHS as a search path to find code files.
369  STRIPPATHS.append(os.path.abspath(os.getcwd()) + "/")
370 
371  import SimpleHTTPServer
372  import SocketServer
373  import urllib
374 
375  conn = sqlite3.connect(OUTFILE_TREE)
376 
377  def escape(s):
378  return str(s).replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;").replace('"', "&quot;")
379 
380  def formatsource(source, formatstr = '<em class="%s">%s</em>'):
381  processings = ["ALCA", "RECO", "HARVEST", "online"]
382  info = source.split(" ")
383  processing = " ".join(filter(lambda x: x in processings, info))
384  source = " ".join(filter(lambda x: x not in processings, info))
385  return formatstr % (processing, escape(source))
386 
387  def formatplace(filename, line):
388  MAXLEN = 80
389  shortname = filename[ :(MAXLEN-3)/2] + "..." + filename[-(MAXLEN-3)/2: ] if len(filename) > MAXLEN else filename
390  return '<a href="/%s#%s" target="_blank">%s:%s</a>' % (escape(filename), line, escape(shortname), line)
391 
392  def index():
393  out = [escape('goto to /<filename> for info about a file')]
394 
395  wfs = defaultdict(list)
396  for source, wf in conn.execute(""" -- some SQL hackery here to parse "source"
397  SELECT DISTINCT source, substr(source, instr(source, "wf ")+3)*1 FROM relation ORDER BY 2, 1;"""):
398  wfs[wf].append('<a href="/workflow/%s">%s</a>' % (urllib.quote(source), formatsource(source)))
399  out.append("<ul>")
400  for wf in wfs:
401  out.append('<li>' + " ".join(wfs[wf]) + "</li>")
402  out.append("</ul>")
403 
404  out.append("<ul>")
405  for f in conn.execute("SELECT name FROM file ORDER BY name;"):
406  name = escape(f[0])
407  out.append('<li><a href="/%s">%s</a></li>' % (name, name))
408  out.append("</ul>")
409 
410  return "\n".join(out)
411 
412  def showworkflow(source):
413  source = urllib.unquote(source)
414  cur = conn.execute("""
415  SELECT DISTINCT file.name FROM relation
416  INNER JOIN trace ON place = trace.id
417  INNER JOIN file ON file.id = trace.file
418  WHERE relation.source = ?
419  ORDER BY file.name;
420  """, (source, ))
421  out = ["Files used by workflow %s: <ul>" % formatsource(source)]
422  for f in cur:
423  name = escape(f[0])
424  out.append('<li><a href="/%s">%s</a></li>' % (name, name))
425  out.append("</ul>")
426  return "\n".join(out)
427 
428  def showfile(filename):
429  out = []
430  out.append('<script src="https://rawgit.com/google/code-prettify/master/src/prettify.js"></script>')
431  out.append('<link rel="stylesheet" href="https://rawgit.com/google/code-prettify/master/src/prettify.css"></link>')
432 
433  lines = None
434  for d in STRIPPATHS:
435  try:
436  with open(d + filename) as f:
437  lines = f.readlines()
438  out.append("Read %s" % f.name)
439  break
440  except:
441  pass
442 
443  if lines:
444  cur = conn.execute("""
445  SELECT DISTINCT trace.line, source FROM relation
446  INNER JOIN trace on relation.place = trace.id
447  INNER JOIN file ON trace.file == file.id
448  WHERE file.name == ? ORDER BY line, source;""", (filename,))
449  sourceinfo = defaultdict(list)
450  for line, source in cur:
451  sourceinfo[line].append(source)
452 
453  out.append('<pre class="prettyprint linenums">')
454  for i, l in enumerate(lines):
455  # put the text into data-tag here and move it later, to not mess up syntax HL
456  tags = [formatsource(source, '<em class="%%s" data-tag="%%s" data-line="%d"></em>' % (i+1)) for source in sourceinfo[i+1]]
457  out.append(escape(l).rstrip() + "".join(tags))
458  out.append('</pre>')
459 
460  out.append("""<script type="text/javascript">
461  PR.prettyPrint();
462  clickfunc = function(evt) {
463  document.querySelectorAll("li > iframe, li > br").forEach(function(e) {e.remove()});
464  dest = "/info" + window.location.pathname + ":" + this.getAttribute("data-line");
465  this.parentElement.insertAdjacentHTML("beforeend", '<br><iframe width="90%" height="500px" frameborder="0" src="' + dest + '"></iframe><br>');
466  };
467  document.querySelectorAll("li > em").forEach(function(e) {
468  e.innerText = e.getAttribute("data-tag");
469  e.onclick = clickfunc;
470  })
471 
472  n = 1*window.location.hash.replace("#", "");
473  if (n > 0) {
474  li = document.querySelectorAll("li")[n-1];
475  li.style = "background: #ee7";
476  li.scrollIntoView();
477  }
478  </script>""")
479 
480  else:
481  out.append("Could not find %s" % filename)
482 
483  return "\n".join(out)
484 
485 
486  def showinfo(filename, line):
487  line = int(line)
488  out = []
489  def queryandoutput(startfrom, to, directiontext):
490  # we format in the side of the relation to query for here...
491  cur = conn.execute("""
492  SELECT place_type, -- why did we trace this line?
493  <to>file.name, <to>trace.line, -- where was it used?
494  usedby, usedby_type, relation, -- what was it used for?
495  place, source -- why did this code run?
496  FROM relation
497  INNER JOIN trace AS placetrace ON placetrace.id = relation.place
498  INNER JOIN trace AS usedbytrace ON usedbytrace.id = relation.usedby
499  INNER JOIN file AS placefile ON placefile.id = placetrace.file
500  INNER JOIN file AS usedbyfile ON usedbyfile.id = usedbytrace.file
501  WHERE <from>file.name = ? AND <from>trace.line = ?
502  LIMIT 1000; """
503  .replace("<from>", startfrom).replace("<to>", to), (filename, line))
504  out.append("<p>%s %s <ul>" % (formatplace(filename, line), directiontext))
505  for place_type, pname, pline, usedby, usedby_type, relation, place, source in cur:
506  out.append(
507  '<li><tt>%s</tt> at %s by <tt>%s</tt> as <a href="/why/%d">%s</a> <a href="/why/%d">in</a> %s</li>'
508  % (escape(place_type), formatplace(pname, pline), escape(usedby_type), usedby, escape(relation), place, formatsource(source)))
509  out.append("</ul></p>")
510 
511  queryandoutput("place", "usedby", "is used as")
512  queryandoutput("usedby", "place", "uses")
513 
514  return "\n".join(out)
515 
516  def showwhy(id):
517  id = int(id)
518  # this (WHERE before recursion) will optimize better than the view.
519  cur = conn.execute("""
520  WITH RECURSIVE fulltrace(level, baseid, parent, file, name, line) AS (
521  SELECT 1 AS level, trace.id, parent, trace.file, file.name, line FROM trace
522  INNER JOIN file ON file.id = trace.file
523  WHERE trace.id = ?
524  UNION SELECT level+1, baseid, trace.parent, trace.file, file.name, trace.line FROM fulltrace
525  INNER JOIN trace ON trace.id = fulltrace.parent
526  INNER JOIN file ON file.id = trace.file)
527  SELECT name, line FROM fulltrace ORDER BY level;""", (id,))
528  out = []
529  out.append("Full stack trace:<ul>")
530  for name, line in cur:
531  out.append('<li>%s</li>' % formatplace(name, line))
532  out.append("</ul>")
533  return "\n".join(out)
534 
535  ROUTES = [
536  (re.compile('/workflow/(.*)$'), showworkflow),
537  (re.compile('/info/(.*):(\d+)$'), showinfo),
538  (re.compile('/why/(\d+)$'), showwhy),
539  (re.compile('/([^.]*[.]?[^.]+[.]?[^.]*)$'), showfile),
540  (re.compile('/$'), index),
541  ]
542 
543  def do_GET(self):
544  try:
545  res = None
546  for pattern, func in ROUTES:
547  m = pattern.match(self.path)
548  if m:
549  res = func(*m.groups())
550  break
551 
552  if res:
553  self.send_response(200, "Here you go")
554  self.send_header("Content-Type", "text/html; charset=utf-8")
555  self.end_headers()
556  self.wfile.write("""<html><style>
557  body {
558  font-family: sans;
559  }
560  em {
561  cursor: pointer;
562  padding: 0 2px;
563  margin: 1 2px;
564  background: #999;
565  }
566  em.ALCA {background: #ee9; }
567  em.RECO {background: #9e9; }
568  em.HARVEST {background: #99e; }
569  em.online {background: #e99; }
570  </style><body>""")
571  self.wfile.write(res)
572  self.wfile.write("</body></html>")
573  self.wfile.close()
574  else:
575  self.send_response(400, "Something went wrong")
576  except:
577  trace = traceback.format_exc()
578  self.send_response(500, "Things went very wrong")
579  self.send_header("Content-Type", "text/plain; charset=utf-8")
580  self.end_headers()
581  self.wfile.write(trace)
582  self.wfile.close()
583 
584  Handler = SimpleHTTPServer.SimpleHTTPRequestHandler
585  Handler.do_GET = do_GET
586  httpd = SocketServer.TCPServer(("",SERVE_PORT), Handler)
587  print("serving at port", SERVE_PORT)
588  httpd.serve_forever()
589 
def replace(string, replacements)
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
Definition: Utilities.cc:47
static std::string join(char **cmd)
Definition: RemoteFile.cc:21
#define str(s)

◆ setupenv()

def cmsswConfigtrace.setupenv ( )

Definition at line 271 of file cmsswConfigtrace.py.

References print().

Referenced by trace_command().

271 def setupenv():
272  bindir = tempfile.mkdtemp()
273  print("+Setting up in ", bindir)
274  os.symlink(ARGV0, bindir + "/cmsRun")
275  os.environ["PATH"] = bindir + ":" + os.environ["PATH"]
276  os.environ["CMSSWCALLTREE"] = bindir + "/" + OUTFILE_TREE
277  os.environ["CMSSWCALLBASE"] = os.path.abspath(os.getcwd()) + "/"
278  with open(os.environ["CMSSWCALLTREE"], "w") as f:
279  pass
280  return bindir
281 
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
Definition: Utilities.cc:47

◆ trace_command()

def cmsswConfigtrace.trace_command (   argv)

Definition at line 288 of file cmsswConfigtrace.py.

References cleanupenv(), and setupenv().

Referenced by main().

288 def trace_command(argv):
289  tmpdir = None
290  if not "CMSSWCALLTREE" in os.environ:
291  tmpdir = setupenv()
292 
293  subprocess.call(argv)
294 
295  if tmpdir:
296  cleanupenv(tmpdir)
297 
def cleanupenv(tmpdir)

◆ trace_location()

def cmsswConfigtrace.trace_location (   thing,
  name,
  extra = lambda thing,
  args,
  kwargs 
)

Definition at line 54 of file cmsswConfigtrace.py.

References mps_setup.append, auto_inspect(), and mkLumiAveragedPlots.tuple.

Referenced by flatten().

54 def trace_location(thing, name, extra = lambda thing, *args, **kwargs: thing):
55  old_method = getattr(thing, name)
56  def trace_location_hook(self, *args, **kwargs):
57  retval = old_method(self, *args, **kwargs)
58  where = auto_inspect()
59  #print("Called %s::%s at %s" % (thing.__name__, name, where[0][1:3]))
60  event = (name, tuple(w[1:3] for w in where), extra(self, *args, **kwargs))
61  if hasattr(self, "_trace_events"):
62  getattr(self, "_trace_events").append(event)
63  else:
64  # this bypasses setattr checks
65  self.__dict__["_trace_events"] = [ event ]
66 
67  return retval
68  setattr(thing, name, trace_location_hook)
69 

◆ trace_python()

def cmsswConfigtrace.trace_python (   prog_argv,
  path 
)

Definition at line 298 of file cmsswConfigtrace.py.

References collect_trace(), print(), searchinpath(), and writeoutput().

Referenced by main().

298 def trace_python(prog_argv, path):
299  graph = []
300  sys.argv = prog_argv
301  progname = prog_argv[0]
302  file_path = searchinpath(progname, path)
303  try:
304  with open(file_path) as fp:
305  code = compile(fp.read(), progname, 'exec')
306  globals = {}
307  try:
308  exec code in globals, globals
309  except:
310  print(traceback.format_exc())
311  finally:
312  # reporting is only possible if the config was executed successfully.
313  # we still do it in case of an exception, which can happen after convertToUnscheduled()
314  print("+Collecting trace information from %s..." % globals["process"])
315  collect_trace(globals["process"], 'cmsrun', graph, ('cmsRun', '', ((progname, 0),)))
316  writeoutput(graph)
317 
318  except OSError as err:
319  print("+Cannot run file %r because: %s" % (sys.argv[0], err))
320  sys.exit(1)
321  except SystemExit:
322  pass
323  # this is not necessarily reached at all.
324  sys.exit(0)
325 
def collect_trace(thing, name, graph, parent)
def writeoutput(graph)
def searchinpath(progname, path)
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
Definition: Utilities.cc:47
def trace_python(prog_argv, path)

◆ writeoutput()

def cmsswConfigtrace.writeoutput (   graph)

Definition at line 174 of file cmsswConfigtrace.py.

References cmsswFiletrace.formatfile(), join(), and print().

Referenced by trace_python().

174 def writeoutput(graph):
175  progname = " ".join(PREFIXINFO)
176  print("+Done running %s, writing output..." % progname)
177 
178  def formatfile(filename):
179  filename = os.path.abspath(filename)
180  for pfx in STRIPPATHS:
181  if filename.startswith(pfx):
182  filename = filename[len(pfx):]
183  return filename
184 
185  files = set()
186  for child, parent, relation in graph:
187  files.add(child[2][0][0])
188  files.add(parent[2][0][0])
189 
190  conn = sqlite3.connect(os.environ["CMSSWCALLTREE"])
191  cur = conn.cursor()
192  cur.executescript("""
193  CREATE TABLE IF NOT EXISTS file(id INTEGER PRIMARY KEY,
194  name TEXT, UNIQUE(name)
195  );
196  CREATE TABLE IF NOT EXISTS trace(id INTEGER PRIMARY KEY,
197  parent INTEGER, -- points into same table, recursively
198  file INTEGER, line INTEGER,
199  FOREIGN KEY(parent) REFERENCES trace(id),
200  FOREIGN KEY(file) REFERENCES file(id),
201  UNIQUE(parent, file, line)
202  );
203  CREATE TABLE IF NOT EXISTS relation(id INTEGER PRIMARY KEY,
204  place INTEGER,
205  place_type TEXT,
206  usedby INTEGER,
207  usedby_type TEXT,
208  relation TEXT,
209  source TEXT,
210  FOREIGN KEY(place) REFERENCES trace(id),
211  FOREIGN KEY(usedby) REFERENCES trace(id)
212  );
213  CREATE INDEX IF NOT EXISTS placeidx ON relation(place);
214  CREATE INDEX IF NOT EXISTS usedbyidx ON relation(usedby);
215  CREATE INDEX IF NOT EXISTS traceidx ON trace(file);
216  -- SQLite does not optimise that one well, but a VIEW is still nice to have...
217  CREATE VIEW IF NOT EXISTS fulltrace AS
218  WITH RECURSIVE fulltrace(level, baseid, parent, file, name, line) AS (
219  SELECT 1 AS level, trace.id, parent, trace.file, file.name, line FROM trace
220  INNER JOIN file ON file.id = trace.file
221  UNION SELECT level+1, baseid, trace.parent, trace.file, file.name, trace.line FROM fulltrace
222  INNER JOIN trace ON trace.id = fulltrace.parent
223  INNER JOIN file ON file.id = trace.file)
224  SELECT * FROM fulltrace;
225  """)
226  cur.executemany("INSERT OR IGNORE INTO file(name) VALUES (?);",
227  ((formatfile(f),) for f in files))
228  def inserttrace(loc):
229  parent = 0
230  for filename, line in reversed(loc):
231  conn.execute("INSERT OR IGNORE INTO trace(parent, file, line) SELECT ?, id, ? FROM file WHERE name == ?;", (parent, line, formatfile(filename)))
232  cur = conn.execute("SELECT trace.id FROM trace LEFT JOIN file ON trace.file == file.id WHERE trace.parent = ? AND file.name = ? AND trace.line = ?;", (parent, formatfile(filename), line))
233  for row in cur:
234  parent = row[0]
235  return parent
236 
237  for child, parent, relation in graph:
238  cevt, cclassname, cloc = child
239  pevt, pclassname, ploc = parent
240  place = inserttrace(cloc)
241  usedby = inserttrace(ploc)
242  cur.execute("INSERT OR IGNORE INTO relation(place, place_type, usedby, usedby_type, relation, source) VALUES (?,?,?,?,?,?);", (
243  place, "%s::%s" % (cclassname, cevt),
244  usedby, "%s::%s" % (pclassname, pevt),
245  relation, progname
246  ))
247  conn.commit()
248  conn.close()
249 
def writeoutput(graph)
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
Definition: Utilities.cc:47
static std::string join(char **cmd)
Definition: RemoteFile.cc:21
def formatfile(filename)

Variable Documentation

◆ ARGV0

cmsswConfigtrace.ARGV0

Definition at line 23 of file cmsswConfigtrace.py.

◆ IGNORE_PACKAGES

cmsswConfigtrace.IGNORE_PACKAGES

Definition at line 18 of file cmsswConfigtrace.py.

◆ OUTFILE_TREE

cmsswConfigtrace.OUTFILE_TREE

Definition at line 17 of file cmsswConfigtrace.py.

◆ PREFIXINFO

cmsswConfigtrace.PREFIXINFO

Definition at line 22 of file cmsswConfigtrace.py.

◆ SERVE_PORT

cmsswConfigtrace.SERVE_PORT
  1. Some configuration options.

Definition at line 15 of file cmsswConfigtrace.py.

◆ STRIPPATHS

cmsswConfigtrace.STRIPPATHS

Definition at line 19 of file cmsswConfigtrace.py.