Skip to content

Commit 0bb6564

Browse files
feat: support multi-thread python unwind with robust fallbacks
1 parent 0095d3d commit 0bb6564

File tree

11 files changed

+1780
-86
lines changed

11 files changed

+1780
-86
lines changed

agent/crates/trace-utils/cbindgen.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ include = [
6060
"LuaUnwindInfo",
6161
"LuaUnwindTable",
6262
"LuaOfs",
63-
"LjOfs"
63+
"LjOfs",
64+
"TSDInfo"
6465
]
6566
exclude = [
6667
"bpf_update_elem",
@@ -80,6 +81,7 @@ ProcessShardList = "process_shard_list_t"
8081
UnwindEntry = "unwind_entry_t"
8182
UnwindEntryShard = "unwind_entry_shard_t"
8283
UnwindTable = "unwind_table_t"
84+
TSDInfo = "tsd_info_t"
8385
PyCframe = "py_cframe_t"
8486
PyCodeObject = "py_code_object_t"
8587
PyFrameObject = "py_frame_object_t"

agent/crates/trace-utils/src/error.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ pub enum Error {
3737
InvalidPointer(u64),
3838
#[error("Invalid or corrupted data")]
3939
InvalidData,
40+
#[error("{0}")]
41+
Msg(String),
4042
}
4143

4244
pub type Result<T> = std::result::Result<T, Error>;

agent/crates/trace-utils/src/maps.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use std::path::PathBuf;
2121

2222
use log::trace;
2323

24-
#[derive(Debug)]
24+
#[derive(Debug, Clone)]
2525
pub struct MemoryArea {
2626
pub m_start: u64,
2727
pub mx_start: u64, // start address of executable section

agent/crates/trace-utils/src/trace_utils.h

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,41 @@ typedef struct {
9191
} unwind_entry_shard_t;
9292

9393
typedef struct {
94-
uint64_t thread_state_address;
94+
/**
95+
* Offset from thread pointer base (TPBASE) to TSD storage
96+
*/
97+
int16_t offset;
98+
/**
99+
* TSD key multiplier (glibc=16, musl=8)
100+
*/
101+
uint8_t multiplier;
102+
/**
103+
* Whether indirect addressing is needed (musl=1, glibc=0)
104+
*/
105+
uint8_t indirect;
106+
} tsd_info_t;
107+
108+
typedef struct {
109+
/**
110+
* Address of autoTLSkey variable in Python runtime
111+
*/
112+
uint64_t auto_tls_key_addr;
113+
/**
114+
* Python version encoded as 0xMMmm (e.g., 0x030A for 3.10)
115+
*/
116+
uint16_t version;
117+
/**
118+
* Thread Specific Data info for multi-threading support
119+
*/
120+
tsd_info_t tsd_info;
121+
/**
122+
* ID for looking up python_offsets in the offsets map
123+
*/
95124
uint8_t offsets_id;
125+
/**
126+
* Padding for alignment
127+
*/
128+
uint8_t _padding[5];
96129
} python_unwind_info_t;
97130

98131
typedef struct {
@@ -396,6 +429,12 @@ void v8_unwind_table_unload(v8_unwind_table_t *table, uint32_t pid);
396429

397430
int32_t read_offset_of_stack_in_task_struct(void);
398431

432+
/**
433+
* Read TPBASE offset from kernel functions
434+
* Returns the offset of fsbase/tpidr in task_struct, or -1 on failure
435+
*/
436+
int64_t read_tpbase_offset(void);
437+
399438
int rustc_demangle(const char *mangled, char *out, size_t out_size);
400439

401440
unwind_table_t *unwind_table_create(int32_t process_shard_list_map_fd,

agent/crates/trace-utils/src/unwind.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ pub mod elf_utils;
1919
pub mod lua;
2020
pub mod php;
2121
pub mod python;
22+
pub mod tpbase;
23+
pub mod tsd;
2224
pub mod v8;
2325

2426
use std::alloc::{alloc, dealloc, handle_alloc_error, Layout};

0 commit comments

Comments
 (0)