ATLAS Offline Software
athena.py
Go to the documentation of this file.
1 #!/bin/sh
2 # Emacs, this is mostly -*-Python-*-
3 #
4 # Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
5 #
6 # athena.py is born as shell script to preload some optional libraries.
7 #
8 """date"
9 
10 # defaults
11 export USETCMALLOC=0
12 export USEIMF=0
13 export USEEXCTRACE=0
14 export USEEXCABORT=1
15 otherargs=()
16 # but use tcmalloc by default if TCMALLOCDIR is defined
17 if [ -n "$TCMALLOCDIR" ]; then
18  export USETCMALLOC=1
19 fi
20 
21 # parse LD_PRELOAD related command line arguments
22 for a in "$@"
23 do
24  case "$a" in
25  --leak-check*) USETCMALLOC=0;;
26  --delete-check*) USETCMALLOC=0;;
27  --stdcmalloc) USETCMALLOC=0;;
28  --tcmalloc) USETCMALLOC=1;;
29  --stdcmath) USEIMF=0;;
30  --imf) USEIMF=1;;
31  --exctrace) USEEXCTRACE=1;;
32  --no-excabort) USEEXCABORT=0;;
33  --preloadlib*) export ATHENA_ADD_PRELOAD=${a#*=};;
34  --drop-and-reload) ATHENA_DROP_RELOAD=1;;
35  *) otherargs+=("$a");;
36  esac
37 done
38 
39 
40 # Do the actual preloading via LD_PRELOAD and save the original value
41 export LD_PRELOAD_ORIG=${LD_PRELOAD}
42 source `which athena_preload.sh `
43 
44 # Now resurrect ourselves as python script
45 python_path=`which python`
46 "exec" "$python_path" "-tt" "$0" "$@";
47 
48 """
49 
50 # File: athena.py
51 # Author: Wim Lavrijsen (WLavrijsen@lbl.gov)
52 # "
53 # This script allows you to run Athena from python.
54 #
55 # Debugging is supported with the '-d' option (hook debugger after running
56 # all user scripts, and just before calling initialize) and the --debug
57 # option (requires "conf", "init", or "exec" and will hook just before that
58 # stage). The hook will give you the gdb prompt, from where you can set
59 # break points, load additional shared libraries, or drop into interactive
60 # athena mode (if -i specified on the cli). Alternatively, you can start
61 # with gdb, like so:
62 #
63 # $ gdb python
64 # (gdb) run `which athena.py` [options] [<file1>.py [<file2>.py ...
65 #
66 # Usage of valgrind is supported, but it requires full paths and explicit
67 # arguments in its run, like so:
68 #
69 # $ valgrind `which python` `which athena.py` [options] [<file1>.py ...
70 #
71 # or, alternatively (valgrind 3.2.0 and up):
72 #
73 # $ valgrind --trace-children=yes `which athena.py` [options] [<file1>.py ...
74 #
75 # Note that any error messages/leaks that valgrind reports on python can be
76 # ignored, as valgrind is wrong (see the file Misc/README.valgrind in the
77 # python installation).
78 #
79 
80 __author__ = 'Wim Lavrijsen (WLavrijsen@lbl.gov)'
81 __doc__ = 'For details about athena.py, run "less `which athena.py`"'
82 
83 import sys, os
84 
85 
86 import AthenaCommon.AthOptionsParser as aop
87 aop.enable_athenaCLI()
88 opts = aop.parse(legacy_args=True)
89 
90 
91 if opts.scripts:
92  from AthenaCommon.Utils.unixtools import FindFile
93  path_list = ['./'] + os.environ.get('PYTHONPATH', '').split(os.pathsep)
94  file_path = FindFile( os.path.expanduser( os.path.expandvars(opts.scripts[0]) ),
95  path_list, os.R_OK )
96 
97  if file_path is not None:
98  with open(file_path) as f:
99  if f.readline().startswith('#!'): # shebang means CA mode
100  opts.CA = True
101 
102  if opts.CA:
103  sys.argv.remove(opts.scripts[0]) # drop script path from args
104  opts.scripts[0] = file_path # replace with resolved path
105 
106 elif opts.fromdb:
107  import pickle
108  with open(opts.fromdb, 'rb') as f:
109  try:
110  acc = pickle.load(f)
111  opts.CA = not isinstance(acc, dict) # legacy pkl is a dict
112  if not opts.CA:
113  del acc # legacy pkl is loaded in Execution.py
114  except ModuleNotFoundError:
115  pass # in case ComponentAccumulator class is not available in release
116 
117 
118 if 'LD_PRELOAD_ORIG' in os.environ:
119  os.environ['LD_PRELOAD'] = os.getenv('LD_PRELOAD_ORIG')
120  os.unsetenv('LD_PRELOAD_ORIG')
121 
122 
123 from AthenaCommon.Debugging import DbgStage
124 DbgStage.value = opts.debug
125 
126 
127 if not os.getcwd() in sys.path:
128  sys.path = [ os.getcwd() ] + sys.path
129 
130 if '' not in sys.path:
131  sys.path = [ '' ] + sys.path
132 
133 
134 
135 sys.ps1 = 'athena> '
136 sys.ps2 = '. ... '
137 
138 try:
139  import ctypes
140  from ctypes.util import find_library as ctypes_find_library
141  libc = ctypes.cdll.LoadLibrary( ctypes_find_library('c') )
142  libc.prctl( 15, b'athena.py', 0, 0, 0 )
143 except Exception:
144  pass # don't worry about it failing ...
145 
146 
147 
148 if not (opts.interactive or opts.debug):
149  # in batch there is no need for stdin
150  if sys.stdin and os.isatty( sys.stdin.fileno() ):
151  os.close( sys.stdin.fileno() )
152 else:
153  # Make sure ROOT gets initialized early, so that it shuts down last.
154  # Otherwise, ROOT can get shut down before Gaudi, leading to crashes
155  # when Athena components dereference ROOT objects that have been deleted.
156  import ROOT # noqa: F401
157 
158 
159 if opts.CA:
160  from AthenaCommon import ExitCodes
161  exitcode = 0
162  try:
163  if opts.scripts: # CA script
164  if not opts.tracelevel:
165  import runpy
166  runpy.run_path( opts.scripts[0], run_name='__main__' )
167  else:
168  from AthenaCommon.Debugging import traceExecution
169  traceExecution( opts.scripts[0], opts.tracelevel )
170 
171  elif opts.fromdb: # pickle
172  from AthenaCommon.AthOptionsParser import configureCAfromArgs
173  configureCAfromArgs( acc, opts )
174  sys.exit(acc.run(opts.evtMax).isFailure())
175 
176  except SystemExit as e:
177  # Failure in ComponentAccumulator.run() is very likely an algorithm error
178  exitcode = ExitCodes.EXE_ALG_FAILURE if e.code==1 else e.code
179 
180  from AthenaCommon import Logging
181  Logging.log.info( 'leaving with code %d: "%s"',
182  exitcode, ExitCodes.what(exitcode) )
183  sys.exit( exitcode )
184 
185 
186 else:
187  # logging and messages
188  from AthenaCommon.Logging import logging, log
189  _msg = log
190 
191  # test and set log level
192  try:
193  _msg.setLevel (getattr(logging, opts.loglevel))
194  except Exception:
195  aop._help_and_exit()
196 
197  # start profiler, if requested
198  if opts.profile_python:
199  import cProfile
200  # profiler is created and controlled programmatically b/c a CLI profiling of
201  # athena.py doesn't work (globals are lost from include() execfile() calls),
202  # and because this allows easy excluding of the (all C++) Gaudi run
203  cProfile._athena_python_profiler = cProfile.Profile()
204  cProfile._athena_python_profiler.enable()
205 
206  # Fill athena job properties
207  aop.fill_athenaCommonFlags(opts)
208 
209  # file inclusion and tracing
210  from AthenaCommon.Include import include
211  include.setShowIncludes(opts.showincludes)
212 
213  # pre-execution step
214  include( "AthenaCommon/Preparation.py" )
215 
216  # execution of user script and drop into batch or interactive mode ---------
217  include( "AthenaCommon/Execution.py" )
python.Debugging.traceExecution
def traceExecution(script, level)
Definition: Debugging.py:113
python.Utils.unixtools.FindFile
def FindFile(filename, pathlist, access)
helper -------------------------------------------------------------------—
Definition: unixtools.py:20
python.Include.include
include
Definition: Include.py:318
Trk::open
@ open
Definition: BinningType.h:40
python.AthOptionsParser.configureCAfromArgs
def configureCAfromArgs(acc, opts)
Definition: AthOptionsParser.py:120
Trk::split
@ split
Definition: LayerMaterialProperties.h:38