Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 19 additions & 6 deletions src/coredump.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@ use crate::python_bindings::{
};
use crate::python_data_access::format_variable;
use crate::python_interpreters::InterpreterState;
use crate::python_interpreters::InterpreterStateOffsets;
use crate::python_process_info::{
get_interpreter_address, get_python_version, get_threadstate_address, is_python_lib,
get_interpreter_info, get_python_version, get_threadstate_address_with_offsets, is_python_lib,
ContainsAddr, PythonProcessInfo,
};
use crate::python_threading::thread_names_from_interpreter;
use crate::stack_trace::{get_stack_traces, StackTrace};
use crate::stack_trace::{get_stack_traces_with_offsets, StackTrace};
use crate::version::Version;

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -181,6 +182,7 @@ pub struct PythonCoreDump {
core: CoreDump,
version: Version,
interpreter_address: usize,
interpreter_state_offsets: Option<InterpreterStateOffsets>,
threadstate_address: usize,
}

Expand Down Expand Up @@ -242,19 +244,27 @@ impl PythonCoreDump {
get_python_version(&python_info, &core).context("failed to get python version")?;
info!("Got python version {}", version);

let interpreter_address = get_interpreter_address(&python_info, &core, &version)?;
let interpreter_info = get_interpreter_info(&python_info, &core, &version)?;
let interpreter_address = interpreter_info.address;
info!("Found interpreter at 0x{:016x}", interpreter_address);

// lets us figure out which thread has the GIL
let config = Config::default();
let threadstate_address =
get_threadstate_address(interpreter_address, &python_info, &core, &version, &config)?;
let threadstate_address = get_threadstate_address_with_offsets(
interpreter_address,
&python_info,
&core,
&version,
&config,
interpreter_info.offsets,
)?;
info!("found threadstate at 0x{:016x}", threadstate_address);

Ok(PythonCoreDump {
core,
version,
interpreter_address,
interpreter_state_offsets: interpreter_info.offsets,
threadstate_address,
})
}
Expand Down Expand Up @@ -332,14 +342,16 @@ impl PythonCoreDump {
}

fn _get_stack<I: InterpreterState>(&self, config: &Config) -> Result<Vec<StackTrace>, Error> {
let mut traces = get_stack_traces::<I, CoreDump>(
let mut traces = get_stack_traces_with_offsets::<I, CoreDump>(
self.interpreter_address,
self.interpreter_state_offsets,
&self.core,
self.threadstate_address,
Some(config),
)?;
let thread_names = thread_names_from_interpreter::<I, CoreDump>(
self.interpreter_address,
self.interpreter_state_offsets,
&self.core,
&self.version,
)
Expand Down Expand Up @@ -475,6 +487,7 @@ mod test {
core,
version,
interpreter_address: 0x000055a8293dbe20,
interpreter_state_offsets: None,
threadstate_address: 0x000055a82745fe18,
};

Expand Down
48 changes: 48 additions & 0 deletions src/python_interpreters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,35 @@ pub trait InterpreterState: Copy {
fn modules_ptr_ptr(interpreter_address: usize) -> *const *const Self::Object;
}

#[derive(Debug, Clone, Copy)]
pub struct InterpreterStateOffsets {
pub threads_head: usize,
pub imports_modules: usize,
pub ceval_gil: usize,
}

pub fn threadstate_ptr_ptr<I: InterpreterState>(
interpreter_address: usize,
offsets: Option<InterpreterStateOffsets>,
) -> *const *const I::ThreadState {
match offsets {
Some(offsets) => {
(interpreter_address + offsets.threads_head) as *const *const I::ThreadState
}
None => I::threadstate_ptr_ptr(interpreter_address),
}
}

pub fn modules_ptr_ptr<I: InterpreterState>(
interpreter_address: usize,
offsets: Option<InterpreterStateOffsets>,
) -> *const *const I::Object {
match offsets {
Some(offsets) => (interpreter_address + offsets.imports_modules) as *const *const I::Object,
None => I::modules_ptr_ptr(interpreter_address),
}
}

pub trait ThreadState: Copy {
type FrameObject: FrameObject;
type InterpreterState: InterpreterState;
Expand Down Expand Up @@ -917,6 +946,25 @@ impl TupleObject for v2_7_15::PyTupleObject {
mod tests {
use super::*;

#[test]
fn test_runtime_interpreter_state_offsets() {
let interpreter_address = 0x1000;
let offsets = InterpreterStateOffsets {
threads_head: 7600,
imports_modules: 7688,
ceval_gil: 7720,
};

let threads = threadstate_ptr_ptr::<v3_14_0::_is>(interpreter_address, Some(offsets));
let modules = modules_ptr_ptr::<v3_14_0::_is>(interpreter_address, Some(offsets));

assert_eq!(threads as usize, interpreter_address + offsets.threads_head);
assert_eq!(
modules as usize,
interpreter_address + offsets.imports_modules
);
}

#[test]
fn test_py3_11_line_numbers() {
use crate::python_bindings::v3_11_0::PyCodeObject;
Expand Down
Loading