Skip to content

Commit a4378de

Browse files
authored
fix(profiler): Add function name to profiler frame cache (#2164)
Wrapper functions can take on the same name as the wrapped function. This means that if a decorator is used to wrap different functions, even though the filename and line number will be the same for all instances of the frame, the function name can vary. Add the function name to the cache to avoid these cache collisions.
1 parent d991be7 commit a4378de

File tree

2 files changed

+11
-9
lines changed

2 files changed

+11
-9
lines changed

sentry_sdk/profiler.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@
111111
FrameId = Tuple[
112112
str, # abs_path
113113
int, # lineno
114+
str, # function
114115
]
115116
FrameIds = Tuple[FrameId, ...]
116117

@@ -278,7 +279,7 @@ def extract_stack(
278279
for i, fid in enumerate(frame_ids):
279280
frame = cache.get(fid)
280281
if frame is None:
281-
frame = extract_frame(raw_frames[i], cwd)
282+
frame = extract_frame(fid, raw_frames[i], cwd)
282283
cache.set(fid, frame)
283284
frames.append(frame)
284285

@@ -300,15 +301,15 @@ def extract_stack(
300301

301302
def frame_id(raw_frame):
302303
# type: (FrameType) -> FrameId
303-
return (raw_frame.f_code.co_filename, raw_frame.f_lineno)
304+
return (raw_frame.f_code.co_filename, raw_frame.f_lineno, get_frame_name(raw_frame))
304305

305306

306-
def extract_frame(frame, cwd):
307-
# type: (FrameType, str) -> ProcessedFrame
308-
abs_path = frame.f_code.co_filename
307+
def extract_frame(fid, raw_frame, cwd):
308+
# type: (FrameId, FrameType, str) -> ProcessedFrame
309+
abs_path = raw_frame.f_code.co_filename
309310

310311
try:
311-
module = frame.f_globals["__name__"]
312+
module = raw_frame.f_globals["__name__"]
312313
except Exception:
313314
module = None
314315

@@ -327,8 +328,8 @@ def extract_frame(frame, cwd):
327328
"abs_path": os.path.join(cwd, abs_path),
328329
"module": module,
329330
"filename": filename_for_module(module, abs_path) or None,
330-
"function": get_frame_name(frame),
331-
"lineno": frame.f_lineno,
331+
"function": fid[2],
332+
"lineno": raw_frame.f_lineno,
332333
}
333334

334335

tests/test_profiler.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
ThreadScheduler,
1616
extract_frame,
1717
extract_stack,
18+
frame_id,
1819
get_current_thread_id,
1920
get_frame_name,
2021
setup_profiler,
@@ -444,7 +445,7 @@ def test_get_frame_name(frame, frame_name):
444445
def test_extract_frame(get_frame, function):
445446
cwd = os.getcwd()
446447
frame = get_frame()
447-
extracted_frame = extract_frame(frame, cwd)
448+
extracted_frame = extract_frame(frame_id(frame), frame, cwd)
448449

449450
# the abs_path should be equal toe the normalized path of the co_filename
450451
assert extracted_frame["abs_path"] == os.path.normpath(frame.f_code.co_filename)

0 commit comments

Comments
 (0)