ATLAS Offline Software
Toggle main menu visibility
Loading...
Searching...
No Matches
Control
AthenaCommon
python
Debugging.py
Go to the documentation of this file.
1
# Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
2
3
8
9
__doc__ =
"""py-module to hold a few tools and utilities to help debugging
10
configurables and/or Athena application.
11
"""
12
13
import
io
14
15
class
DbgStage
:
16
"""Class to hold the stage at which the user asked to hook the debugger
17
"""
18
value =
None
19
allowed_values = (
"conf"
,
"init"
,
"exec"
,
"fini"
)
20
pass
# class DbgStage
21
22
def
hookDebugger
():
23
"""debugging helper, hooks debugger to running interpreter process
24
gdb can be overridden via $ATLAS_DEBUGGER
25
"""
26
import
os
27
debugger = os.environ.get(
'ATLAS_DEBUGGER'
,
'gdb'
)
28
29
pid = os.spawnvp(os.P_NOWAIT,
30
debugger, [debugger,
'-q'
,
'python'
, str(os.getpid())])
31
32
# give debugger some time to attach to the python process
33
import
time
34
time.sleep( 1 )
35
36
# verify the process' existence (will raise OSError if failed)
37
os.waitpid( pid, os.WNOHANG )
38
os.kill( pid, 0 )
39
return
40
41
def
hookStrace
(out=None):
42
"""Same than for hookDebugger: spawn strace and attach to the running
43
interpreter process
44
"""
45
import
os
46
if
out
is
None
: out =
'athena.strace.log.%i'
% os.getpid()
47
if
isinstance(out, io.IOBase):
48
out = out.name
49
elif
not
isinstance(out,str):
50
raise
TypeError(
'argument 0 needs to be either a file or a filename'
)
51
52
pid = os.spawnvp(os.P_NOWAIT,
53
'strace'
, [
'strace'
,
54
'-f'
,
# follow children
55
'-p'
, str(os.getpid()),
56
'-o'
, out])
57
58
# give strace some time to attach to the python process
59
import
time
60
time.sleep( 1 )
61
62
# verify the process' existence (will raise OSError if failed)
63
os.waitpid( pid, os.WNOHANG )
64
os.kill( pid, 0 )
65
return
66
67
68
def
allowPtrace
():
69
"""On kernels with Yama enabled, ptrace may not work by default on processes
70
which are not decendants of the tracing process. Among other things, that
71
causes the way we attach the debugger to fail. However, we can disable this
72
on a per-process basis. Do that here.
73
74
See https://www.kernel.org/doc/Documentation/security/Yama.txt and prctl(2).
75
"""
76
77
# First test to see if ptrace restrictions are enabled.
78
import
os
79
# Return if this kernel does not support ptrace restrictions.
80
if
not
os.path.exists (
'/proc/sys/kernel/yama/ptrace_scope'
):
return
81
82
# Return if ptrace restrictions are disabled.
83
with
open(
'/proc/sys/kernel/yama/ptrace_scope'
)
as
f:
84
if
f.readline().
strip
() ==
'0'
:
85
return
86
87
# Use prctl to try to enable ptrace.
88
from
ctypes
import
CDLL
89
libc = CDLL(
"libc.so.6"
)
90
# Args are PTRACE_SET_PTRACER (4HYama) and
91
# PR_SET_PTRACER_ANY ((unsigned long)-1).
92
libc.prctl (0x59616d61, 0xffffffffffffffff)
93
94
return
95
96
97
def
dumpPythonProfile
(filename):
98
"""Save python profile data of the default athena profiler instance
99
into filename (.txt or .pkl format).
100
"""
101
from
AthenaCommon.Logging
import
log
102
import
cProfile
103
import
pstats
104
105
profiler = cProfile._athena_python_profiler
106
profiler.disable()
107
if
filename.endswith(
".txt"
):
108
stats = pstats.Stats(profiler, stream=open(filename,
'w'
))
109
stats.strip_dirs().sort_stats(
"time"
).print_stats()
110
log.info(
"Python profile summary stored in %s"
, filename)
111
else
:
112
profiler.dump_stats(filename)
113
log.info(
"Python profile stored in %s"
, filename)
114
115
116
def
traceExecution
(script, level):
117
"""Run script with the given trace level"""
118
import
sys
119
import
trace
120
ignore_dirs = []
121
ignore_mods = []
122
123
# exclude system and root libraries
124
if
level > 0:
125
ignore_dirs = [x
for
x
in
sys.path
if
x.find(
"ROOT"
)!=-1]
126
ignore_dirs.append(sys.prefix)
127
if
level > 1:
128
ignore_mods += [
'_db'
,
'__init__'
,
'_configurables'
,
'GaudiHandles'
,
'six'
]
129
if
level > 2:
130
ignore_mods += [
131
# Legacy stuff we pull in b/c PythonAlgorithms and such still derive from old-style configurables
132
'Configurable'
,
'Configurables'
,
'PropertyProxy'
,
'DataHandle'
,
'ConfigurableDb'
,
133
'ConfigurableMeta'
,
'CfgMgr'
,
134
# Internals of the ComponentAccumulator
135
'ComponentAccumulator'
,
'Logging'
,
'AthConfigFlags'
,
'AllConfigFlags'
,
'Deduplication'
,
136
'semantics'
,
'AccumulatorCache'
,
'DebuggingContext'
,
'AtlasSemantics'
,
'ComponentFactory'
,
137
'LegacySupport'
,
'ItemListSemantics'
138
]
139
140
# taken from cpython/Lib/trace.py
141
tracer = trace.Trace(ignoredirs=ignore_dirs, ignoremods=ignore_mods)
142
143
with
io.open_code(script)
as
f:
144
code = compile(f.read(), script,
'exec'
)
145
tracer.run(code)
SiliconTech::strip
@ strip
Definition
FPGATrackSimTypes.h:25
python.Debugging.DbgStage
Definition
Debugging.py:15
python.Debugging.hookStrace
hookStrace(out=None)
Definition
Debugging.py:41
python.Debugging.allowPtrace
allowPtrace()
Definition
Debugging.py:68
python.Debugging.traceExecution
traceExecution(script, level)
Definition
Debugging.py:116
python.Debugging.hookDebugger
hookDebugger()
Definition
Debugging.py:22
python.Debugging.dumpPythonProfile
dumpPythonProfile(filename)
Definition
Debugging.py:97
Generated on
for ATLAS Offline Software by
1.17.0