Skip to content

Commit

Permalink
Better checks for when f_executable isn't a PyCodeObject
Browse files Browse the repository at this point in the history
  • Loading branch information
benfred committed Oct 23, 2024
1 parent adfcfdd commit 2df8edc
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 7 deletions.
3 changes: 0 additions & 3 deletions src/python_interpreters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -446,9 +446,6 @@ impl ThreadState for v3_13_0::PyThreadState {
impl FrameObject for v3_13_0::_PyInterpreterFrame {
type CodeObject = v3_13_0::PyCodeObject;
fn code(&self) -> *mut Self::CodeObject {
// TODO: this has been replaced with f_executable
// ... which means we might have to check the type etc
// https://github.com/python/cpython/issues/100987#issuecomment-1465963433
self.f_executable as *mut v3_13_0::PyCodeObject
}
fn lasti(&self) -> i32 {
Expand Down
16 changes: 12 additions & 4 deletions src/stack_trace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,26 +128,34 @@ where
let frame = process
.copy_pointer(frame_ptr)
.context("Failed to copy PyFrameObject")?;

let code = process
.copy_pointer(frame.code())
.context("Failed to copy PyCodeObject")?;

let filename = copy_string(code.filename(), process).context("Failed to copy filename");
if filename.is_err() {
// TODO: handle case where code isn't codeobject in py3.13+
let name = copy_string(code.name(), process).context("Failed to copy function name");

// just skip processing the current frame if we can't load the filename or function name.
// this can happen in python 3.13+ since the f_executable isn't guaranteed to be
// a PyCodeObject. We could check the type (and mimic the logic of PyCode_Check here)
// but that would require extra overhead of reading the ob_type per frame - and we
// would also have to figure out what the address of PyCode_Type is (which will be
// easier if something like https://github.com/python/cpython/issues/100987#issuecomment-1487227139
// is merged )
if filename.is_err() || name.is_err() {
frame_ptr = frame.back();
continue;
}
let filename = filename?;
let name = name?;

// skip <shim> entries in python 3.12+
if filename == "<shim>" {
frame_ptr = frame.back();
continue;
}

let name = copy_string(code.name(), process).context("Failed to copy function name")?;

let line = match lineno {
LineNo::NoLine => 0,
LineNo::First => code.first_lineno(),
Expand Down

0 comments on commit 2df8edc

Please sign in to comment.