Skip to content

Commit e309201

Browse files
kylewanginchinarvql
authored andcommitted
feat: add TPBASE and TSD extraction for multi-thread Python unwind
1 parent 4eece78 commit e309201

10 files changed

Lines changed: 912 additions & 6 deletions

File tree

agent/crates/trace-utils/cbindgen.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ include = [
7171
"PhpUnwindTable",
7272
"V8UnwindInfo",
7373
"V8Offsets",
74-
"V8UnwindTable"
74+
"V8UnwindTable",
75+
"TSDInfo"
7576
]
7677
exclude = [
7778
"bpf_update_elem",
@@ -91,6 +92,7 @@ ProcessShardList = "process_shard_list_t"
9192
UnwindEntry = "unwind_entry_t"
9293
UnwindEntryShard = "unwind_entry_shard_t"
9394
UnwindTable = "unwind_table_t"
95+
TSDInfo = "tsd_info_t"
9496
PyCframe = "py_cframe_t"
9597
PyCodeObject = "py_code_object_t"
9698
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/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ pub mod btf;
1818
pub mod error;
1919
pub mod maps;
2020
pub mod remote_memory;
21+
pub mod tsd;
2122
pub mod unwind;
2223
pub mod utils;
2324
pub use utils::protect_cpu_affinity;
@@ -29,6 +30,7 @@ use std::io::Write;
2930
use log::info;
3031

3132
// Crate internal modules
33+
pub use tsd::TSDInfo;
3234
use unwind::UnwindTable;
3335

3436
// ============================================================================

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
@@ -173,8 +173,41 @@ typedef struct {
173173

174174
#if defined(DF_ENTERPRISE)
175175
typedef struct {
176-
uint64_t thread_state_address;
176+
/**
177+
* Offset from thread pointer base (TPBASE) to TSD storage
178+
*/
179+
int16_t offset;
180+
/**
181+
* TSD key multiplier (glibc=16, musl=8)
182+
*/
183+
uint8_t multiplier;
184+
/**
185+
* Whether indirect addressing is needed (musl=1, glibc=0)
186+
*/
187+
uint8_t indirect;
188+
} tsd_info_t;
189+
190+
typedef struct {
191+
/**
192+
* Address of autoTLSkey variable in Python runtime
193+
*/
194+
uint64_t auto_tls_key_addr;
195+
/**
196+
* Python version encoded as 0xMMmm (e.g., 0x030A for 3.10)
197+
*/
198+
uint16_t version;
199+
/**
200+
* Thread Specific Data info for multi-threading support
201+
*/
202+
tsd_info_t tsd_info;
203+
/**
204+
* ID for looking up python_offsets in the offsets map
205+
*/
177206
uint8_t offsets_id;
207+
/**
208+
* Padding for alignment
209+
*/
210+
uint8_t _padding[5];
178211
} python_unwind_info_t;
179212
#endif
180213

@@ -709,6 +742,12 @@ void rust_log_wrapper(LogLevel level,
709742
const char *file_path,
710743
int line_number);
711744

745+
/**
746+
* Read TPBASE offset from kernel functions
747+
* Returns the offset of fsbase/tpidr in task_struct, or -1 on failure
748+
*/
749+
int64_t read_tpbase_offset(void);
750+
712751
int rustc_demangle(const char *mangled, char *out, size_t out_size);
713752

714753
unwind_table_t *unwind_table_create(int32_t process_shard_list_map_fd,
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright (c) 2024 Yunshan Networks
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
/// Thread Specific Data info for accessing per-thread PyThreadState.
18+
#[repr(C)]
19+
#[derive(Debug, Clone, Copy, Default)]
20+
pub struct TSDInfo {
21+
/// Offset from thread pointer base (TPBASE) to TSD storage
22+
pub offset: i16,
23+
/// TSD key multiplier (glibc=16, musl=8)
24+
pub multiplier: u8,
25+
/// Whether indirect addressing is needed (musl=1, glibc=0)
26+
pub indirect: u8,
27+
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
pub mod dwarf;
1818
pub mod elf_utils;
19+
pub mod tpbase;
1920

2021
use std::alloc::{alloc, dealloc, handle_alloc_error, Layout};
2122
use std::collections::{hash_map::Entry, HashMap, HashSet};

0 commit comments

Comments
 (0)