Skip to content

Commit 8ec43b6

Browse files
committed
remove time check
1 parent 3b8a6d0 commit 8ec43b6

3 files changed

Lines changed: 16 additions & 106 deletions

File tree

Doc/library/profiling.sampling.rst

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -249,10 +249,7 @@ GIL, has exception, or idle):
249249
result = expensive_call(req)
250250
251251
When the target's source files are readable, ``dump`` prints the source
252-
line for each frame and highlights the executing expression. If a source
253-
file's modification time is newer than the target process's start time,
254-
``dump`` replaces the line with ``[source file changed after process
255-
started]`` to avoid showing misleading code.
252+
line for each frame and highlights the executing expression.
256253

257254
Like ``attach``, ``dump`` requires permission to read the target process's
258255
memory. See :ref:`profiling-permissions`.

Lib/profiling/sampling/dump.py

Lines changed: 4 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ def _display_filename(filename):
120120
return filename
121121

122122

123-
def _format_frame(frame, theme, process_start_time, changed_cache):
123+
def _format_frame(frame, theme):
124124
filename, location, qualname, opcode = _frame_fields(frame)
125125
source_filename = filename
126126
lineno = extract_lineno(location)
@@ -144,9 +144,7 @@ def _format_frame(frame, theme, process_start_time, changed_cache):
144144
line = f"{line} {_color(f'opcode={format_opcode(opcode)}', theme.opcode, theme)}"
145145

146146
lines = [line]
147-
source = _source_line(
148-
source_filename, location, lineno, theme, process_start_time, changed_cache
149-
)
147+
source = _source_line(source_filename, location, lineno, theme)
150148
if source:
151149
lines.append(f" {source}")
152150
return lines
@@ -197,28 +195,9 @@ def _highlight_source_line(line, offsets, theme):
197195
return "".join(parts)
198196

199197

200-
def _source_file_changed(filename, process_start_time, cache):
201-
if process_start_time is None or not filename or filename.startswith("<"):
202-
return False
203-
if filename in cache:
204-
return cache[filename]
205-
try:
206-
changed = os.path.getmtime(filename) > process_start_time
207-
except OSError:
208-
changed = False
209-
cache[filename] = changed
210-
return changed
211-
212-
213-
def _source_line(filename, location, lineno, theme, process_start_time, changed_cache):
198+
def _source_line(filename, location, lineno, theme):
214199
if not filename or filename == "~" or lineno <= 0:
215200
return None
216-
if _source_file_changed(filename, process_start_time, changed_cache):
217-
return _color(
218-
"[source file changed after process started]",
219-
theme.warning,
220-
theme,
221-
)
222201
line = linecache.getline(filename, lineno).removesuffix("\n")
223202
if not line:
224203
return None
@@ -263,39 +242,12 @@ def _section_header(
263242
return _color(f"{subject} ({suffix}):", theme.header, theme)
264243

265244

266-
def _target_process_start_time(pid):
267-
if pid is None or not sys.platform.startswith("linux"):
268-
return None
269-
try:
270-
with open(f"/proc/{pid}/stat", encoding="utf-8") as stat_file:
271-
stat = stat_file.read()
272-
_pid, _sep, fields_text = stat.rpartition(") ")
273-
fields = fields_text.split()
274-
start_ticks = int(fields[19])
275-
clock_ticks = os.sysconf("SC_CLK_TCK")
276-
277-
boot_time = None
278-
with open("/proc/stat", encoding="utf-8") as stat_file:
279-
for line in stat_file:
280-
if line.startswith("btime "):
281-
boot_time = int(line.split()[1])
282-
break
283-
if boot_time is None:
284-
return None
285-
except (IndexError, OSError, ValueError):
286-
return None
287-
288-
return boot_time + start_ticks / clock_ticks
289-
290-
291245
def format_stack_dump(stack_frames, *, pid=None, file=None, colorize=None):
292246
"""Return a formatted one-shot stack dump."""
293247
if file is None:
294248
file = sys.stdout
295249

296250
theme = _theme_for(file, colorize)
297-
process_start_time = _target_process_start_time(pid)
298-
changed_cache = {}
299251
lines = []
300252
sections = list(_iter_dump_sections(stack_frames))
301253
if not sections:
@@ -331,7 +283,7 @@ def format_stack_dump(stack_frames, *, pid=None, file=None, colorize=None):
331283
continue
332284

333285
for frame in reversed(frames):
334-
lines.extend(_format_frame(frame, theme, process_start_time, changed_cache))
286+
lines.extend(_format_frame(frame, theme))
335287

336288
return "\n".join(lines) + "\n"
337289

Lib/test/test_profiling/test_sampling_profiler/test_dump.py

Lines changed: 11 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import opcode
66
import tempfile
77
import unittest
8-
from unittest import mock
98

109
import _colorize
1110

@@ -29,6 +28,11 @@
2928
MockThreadInfo,
3029
)
3130

31+
try:
32+
import _remote_debugging # noqa: F401
33+
except ImportError:
34+
_remote_debugging = None
35+
3236

3337
StructseqInterpreterInfo = namedtuple(
3438
"StructseqInterpreterInfo",
@@ -45,13 +49,6 @@
4549

4650

4751
class TestStackDumpFormatting(unittest.TestCase):
48-
@staticmethod
49-
def _patch_start_time(value=None):
50-
return mock.patch(
51-
"profiling.sampling.dump._target_process_start_time",
52-
return_value=value,
53-
)
54-
5552
def test_format_stack_dump_single_thread(self):
5653
frames = [
5754
MockFrameInfo("leaf.py", 10, "leaf"),
@@ -74,8 +71,7 @@ def test_format_stack_dump_single_thread(self):
7471
)
7572
]
7673

77-
with self._patch_start_time():
78-
output = format_stack_dump(stack_frames, pid=42, colorize=False)
74+
output = format_stack_dump(stack_frames, pid=42, colorize=False)
7975

8076
self.assertIn(
8177
"Stack dump for PID 42, thread 123 "
@@ -112,8 +108,7 @@ def test_format_stack_dump_with_structseq_tuples(self):
112108
)
113109
]
114110

115-
with self._patch_start_time():
116-
output = format_stack_dump(stack_frames, pid=42, colorize=False)
111+
output = format_stack_dump(stack_frames, pid=42, colorize=False)
117112

118113
self.assertIn(
119114
"Stack dump for PID 42, thread 123 "
@@ -324,6 +319,7 @@ def test_format_stack_dump_filters_internal_frames(self):
324319
self.assertIn(' File "user.py", line 10, in user', output)
325320
self.assertNotIn("_sync_coordinator.py", output)
326321

322+
@unittest.skipIf(_remote_debugging is None, "requires _remote_debugging")
327323
def test_format_stack_dump_async_task(self):
328324
task = MockTaskInfo(
329325
task_id=1,
@@ -366,8 +362,7 @@ def test_format_stack_dump_strips_source_like_traceback(self):
366362
)
367363
]
368364

369-
with self._patch_start_time():
370-
output = format_stack_dump(stack_frames, pid=42, colorize=False)
365+
output = format_stack_dump(stack_frames, pid=42, colorize=False)
371366

372367
self.assertIn(' File "', output)
373368
self.assertIn('", line 1, in <module>', output)
@@ -395,8 +390,7 @@ def test_format_stack_dump_highlights_source_range(self):
395390
]
396391
theme = _colorize.get_theme(force_color=True).profiler_dump
397392

398-
with self._patch_start_time():
399-
output = format_stack_dump(stack_frames, pid=42, colorize=True)
393+
output = format_stack_dump(stack_frames, pid=42, colorize=True)
400394

401395
self.assertIn(
402396
f"{theme.source_highlight}\"\"\"{theme.reset}",
@@ -429,45 +423,12 @@ def test_format_stack_dump_highlights_source_range_after_trimming(self):
429423
]
430424
theme = _colorize.get_theme(force_color=True).profiler_dump
431425

432-
with self._patch_start_time():
433-
output = format_stack_dump(stack_frames, pid=42, colorize=True)
426+
output = format_stack_dump(stack_frames, pid=42, colorize=True)
434427

435428
self.assertIn(f"{theme.source_highlight}call{theme.reset}", output)
436429
self.assertIn("\n result = call(arg)\n", _colorize.decolor(output))
437430
self.assertNotIn("\n result = call(arg)\n", _colorize.decolor(output))
438431

439-
def test_format_stack_dump_warns_about_changed_source(self):
440-
with tempfile.TemporaryDirectory() as tmp_dir:
441-
filename = os.path.join(tmp_dir, "target.py")
442-
with open(filename, "w", encoding="utf-8") as file:
443-
file.write("time.sleep(SLEEP_SECONDS)\n")
444-
os.utime(filename, (200, 200))
445-
446-
stack_frames = [
447-
MockInterpreterInfo(
448-
0,
449-
[
450-
MockThreadInfo(
451-
123,
452-
[
453-
StructseqFrameInfo(
454-
filename,
455-
StructseqLocationInfo(1, 1, 0, 4),
456-
"<module>",
457-
None,
458-
)
459-
],
460-
)
461-
],
462-
)
463-
]
464-
465-
with self._patch_start_time(value=100):
466-
output = format_stack_dump(stack_frames, pid=42, colorize=False)
467-
468-
self.assertIn("[source file changed after process started]", output)
469-
self.assertNotIn("time.sleep", output)
470-
471432
def test_format_stack_dump_empty(self):
472433
output = format_stack_dump([], pid=42, colorize=False)
473434

0 commit comments

Comments
 (0)