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
34 changes: 0 additions & 34 deletions agent/crates/trace-utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -575,15 +575,6 @@ extern "C" {
pub fn is_v8_process(pid: u32) -> bool;

pub fn lua_detect(pid: u32, out: *mut LuaRuntimeInfo) -> i32;
pub fn lua_format_folded_stack_trace(
tracer: *mut libc::c_void,
pid: u32,
frames: *const u64,
frame_count: u32,
new_cache: bool,
info_p: *mut libc::c_void,
err_tag: *const libc::c_char,
) -> *mut libc::c_char;
pub fn lua_set_map_fds(
lang_flags_fd: i32,
unwind_info_fd: i32,
Expand Down Expand Up @@ -622,31 +613,6 @@ extern "C" {
pub fn v8_unwind_table_load(table: *mut V8UnwindTable, pid: u32);
pub fn v8_unwind_table_unload(table: *mut V8UnwindTable, pid: u32);

pub fn merge_lua_stacks(
trace_str: *mut libc::c_void,
len: usize,
u_trace: *const libc::c_void,
i_trace: *const libc::c_void,
) -> usize;
pub fn merge_python_stacks(
trace_str: *mut libc::c_void,
len: usize,
i_trace: *const libc::c_void,
u_trace: *const libc::c_void,
) -> usize;
pub fn merge_php_stacks(
trace_str: *mut libc::c_void,
len: usize,
i_trace: *const libc::c_void,
u_trace: *const libc::c_void,
) -> usize;
pub fn merge_v8_stacks(
trace_str: *mut libc::c_void,
len: usize,
i_trace: *const libc::c_void,
u_trace: *const libc::c_void,
) -> usize;

pub fn resolve_php_frame(
pid: u32,
zend_function_ptr: u64,
Expand Down
38 changes: 0 additions & 38 deletions agent/crates/trace-utils/src/trace_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -608,16 +608,6 @@ extern bool is_v8_process(uint32_t pid);
extern int32_t lua_detect(uint32_t pid, lua_runtime_info_t *out);
#endif

#if defined(DF_ENTERPRISE)
extern char *lua_format_folded_stack_trace(void *tracer,
uint32_t pid,
const uint64_t *frames,
uint32_t frame_count,
bool new_cache,
void *info_p,
const char *err_tag);
#endif

#if defined(DF_ENTERPRISE)
extern void lua_set_map_fds(int32_t lang_flags_fd,
int32_t unwind_info_fd,
Expand All @@ -644,34 +634,6 @@ extern void lua_unwind_table_load(lua_unwind_table_t *table, uint32_t pid);
extern void lua_unwind_table_unload(lua_unwind_table_t *table, uint32_t pid);
#endif

#if defined(DF_ENTERPRISE)
extern size_t merge_lua_stacks(void *trace_str,
size_t len,
const void *u_trace,
const void *i_trace);
#endif

#if defined(DF_ENTERPRISE)
extern size_t merge_php_stacks(void *trace_str,
size_t len,
const void *i_trace,
const void *u_trace);
#endif

#if defined(DF_ENTERPRISE)
extern size_t merge_python_stacks(void *trace_str,
size_t len,
const void *i_trace,
const void *u_trace);
#endif

#if defined(DF_ENTERPRISE)
extern size_t merge_v8_stacks(void *trace_str,
size_t len,
const void *i_trace,
const void *u_trace);
#endif

#if defined(DF_ENTERPRISE)
extern php_unwind_table_t *php_unwind_table_create(int32_t unwind_info_map_fd,
int32_t offsets_map_fd);
Expand Down
19 changes: 19 additions & 0 deletions agent/src/ebpf/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,9 @@ pub struct stack_profile_data {
pub comm: [u8; PACKET_KNAME_MAX_PADDING + 1],
pub process_name: [u8; PACKET_KNAME_MAX_PADDING + 1], // process name
pub container_id: [u8; CONTAINER_ID_SIZE], // container id
pub interp_frame_count: u32, // number of structured interpreter frames
pub interp_frames_ptr: u64, // pointer to CSymbolInfo array
pub raw_interpreter_data: u8, // 1 = has structured interpreter data
pub stack_data_len: u32, // stack data length

/*
Expand All @@ -558,6 +561,22 @@ pub struct stack_profile_data {
pub stack_data: *mut c_char,
}

/// C-compatible interpreter frame info struct.
/// Must match the C `interp_symbol_info_t` layout defined in extended.h.
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct CInterpreterFrameInfo {
pub frame_type: u32,
pub function_name: *mut c_char,
pub class_name: *mut c_char,
pub lineno: u32,
pub file_name: *mut c_char,
pub sub_type: u32,
pub is_jit: u8,
pub raw_addr: u64,
pub resolve_failed: u8,
}

extern "C" {
/*
* Set maximum amount of data passed to the agent by eBPF program.
Expand Down
29 changes: 21 additions & 8 deletions agent/src/ebpf/user/extended/extended.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "../tracer.h"
#include "../socket.h"
#include "../proc.h"
#include "extended.h"

int __attribute__ ((weak)) extended_reader_create(struct bpf_tracer *tracer)
{
Expand Down Expand Up @@ -91,19 +92,31 @@ int __attribute__ ((weak)) print_extra_pkt_info(bool datadump_enable,
return 0;
}

char * __attribute__ ((weak)) extended_resolve_frame(int pid, u64 addr, u8 frame_type, u64 extra_a, u64 extra_b)
int __attribute__ ((weak)) extended_extract_interpreter_frames(int pid,
const u8 *frame_types,
const u64 *addrs,
const u64 *extra_data_a,
const u64 *extra_data_b,
int frame_count,
void *tracer,
bool new_cache,
void *info_p,
interp_symbol_info_t *out_frames,
int max_out)
{
return NULL;
return 0;
}

int __attribute__ ((weak)) extended_merge_stacks(char *dst, int len, const char *i_trace, const char *u_trace, int pid)
void __attribute__ ((weak)) extended_free_interp_frames(interp_symbol_info_t *frames, int count)
{
return 0;
}

char * __attribute__ ((weak)) extended_format_lua_stack(void *tracer, int pid, int stack_id,
const char *stack_map_name, void *h,
bool new_cache, void *info_p)
int __attribute__ ((weak)) extended_extract_structured_frames(void *tracer, int tgid,
int user_stack_id, int interp_stack_id,
const char *custom_stack_map_name,
bool new_cache, void *info_p,
interp_symbol_info_t *out_frames,
int max_out)
{
return NULL;
return 0;
}
90 changes: 65 additions & 25 deletions agent/src/ebpf/user/extended/extended.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,40 +110,80 @@ int print_extra_pkt_info(bool datadump_enable, const char *pkt_data, int len,
char *buf, int buf_len, u8 direction);

/**
* @brief **extended_resolve_frame()** Resolve a custom/interpreter frame
* @param pid Process ID
* @param addr Frame address/ID
* @param frame_type Frame type identifier
* @param extra_a Extra data A from stack map
* @param extra_b Extra data B from stack map
* @return Resolved symbol string (must be freed) or NULL
* @brief Structured interpreter symbol info for per-frame extraction.
* Matches the Rust CSymbolInfo layout (#[repr(C)]).
*/
char *extended_resolve_frame(int pid, u64 addr, u8 frame_type, u64 extra_a, u64 extra_b);
#ifndef INTERP_SYMBOL_INFO_DEFINED
#define INTERP_SYMBOL_INFO_DEFINED
typedef struct {
u32 frame_type; // FRAME_TYPE_PHP/V8/LUA/PYTHON
char *function_name; // allocated via clib_mem_alloc
char *class_name; // allocated via clib_mem_alloc (or NULL)
u32 lineno;
char *file_name; // allocated via clib_mem_alloc (or NULL)
u32 sub_type; // language-specific sub-type
u8 is_jit; // 1 = JIT-compiled frame
u64 raw_addr; // original address
u8 resolve_failed; // 1 = resolution failed
} interp_symbol_info_t;
#endif

/**
* @brief **extended_merge_stacks()** Merge interpreter and user stacks
* @param dst Destination buffer
* @param len Buffer length
* @param i_trace Interpreter stack string
* @param u_trace User stack string
* @brief **extended_extract_interpreter_frames()** Extract structured interpreter frames
* @param pid Process ID
* @return Bytes written
* @param frame_types Array of frame types from BPF map
* @param addrs Array of frame addresses
* @param extra_data_a Array of extra data A values
* @param extra_data_b Array of extra data B values
* @param frame_count Number of frames in arrays
* @param tracer BPF tracer handle (for Lua)
* @param new_cache Whether this is a new cache entry (for Lua)
* @param info_p Process info pointer (for Lua)
* @param out_frames Output array of interp_symbol_info_t (caller-allocated)
* @param max_out Maximum output frames
* @return Number of frames written to out_frames
*/
int extended_extract_interpreter_frames(int pid,
const u8 *frame_types,
const u64 *addrs,
const u64 *extra_data_a,
const u64 *extra_data_b,
int frame_count,
void *tracer,
bool new_cache,
void *info_p,
interp_symbol_info_t *out_frames,
int max_out);

/**
* @brief **extended_free_interp_frames()** Free memory owned by interp_symbol_info_t array
* @param frames Array of interp_symbol_info_t
* @param count Number of entries
*/
int extended_merge_stacks(char *dst, int len, const char *i_trace, const char *u_trace, int pid);
void extended_free_interp_frames(interp_symbol_info_t *frames, int count);

/**
* @brief **extended_format_lua_stack()** Format Lua interpreter stack frames
* @brief **extended_extract_structured_frames()** High-level extraction for a stack trace
*
* Reads user and interpreter BPF stack maps, extracts structured interpreter
* frame symbols via per-symbol cache + extract functions.
*
* @param tracer BPF tracer handle
* @param pid Process ID
* @param stack_id Interpreter stack ID from BPF map
* @param stack_map_name Name of the stack map
* @param h Stack string hash table
* @param new_cache Whether to create new cache entry
* @param tgid Process ID (for cache lookup and process type detection)
* @param user_stack_id User stack ID from BPF map (-1 if none)
* @param interp_stack_id Interpreter stack ID from BPF map (-1 if none)
* @param custom_stack_map_name Name of the custom stack map
* @param new_cache Whether cache entry is new
* @param info_p Process info pointer
* @return Formatted stack string (caller must free) or NULL
* @param out_frames Caller-allocated output array
* @param max_out Maximum output frame count
* @return Number of frames written to out_frames
*/
char *extended_format_lua_stack(void *tracer, int pid, int stack_id,
const char *stack_map_name, void *h,
bool new_cache, void *info_p);
int extended_extract_structured_frames(void *tracer, int tgid,
int user_stack_id, int interp_stack_id,
const char *custom_stack_map_name,
bool new_cache, void *info_p,
interp_symbol_info_t *out_frames,
int max_out);

#endif /* DF_EXTENDED_H */
8 changes: 1 addition & 7 deletions agent/src/ebpf/user/profile/perf_profiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,14 +257,8 @@ static void oncpu_reader_work(void *arg)
exit:
print_cp_tracer_status();

print_hash_stack_str(&oncpu_ctx.stack_str_hash);
/* free stack_str_hash */
if (likely(oncpu_ctx.stack_str_hash.buckets != NULL)) {
release_stack_str_hash(&oncpu_ctx.stack_str_hash);
}

print_hash_stack_trace_msg(&oncpu_ctx.msg_hash);
/* free stack_str_hash */
/* free msg_hash */
if (likely(oncpu_ctx.msg_hash.buckets != NULL)) {
/* Ensure that all elements are released properly/cleanly */
push_and_release_stack_trace_msg(&oncpu_ctx,
Expand Down
3 changes: 3 additions & 0 deletions agent/src/ebpf/user/profile/perf_profiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,9 @@ typedef struct {
u8 comm[TASK_COMM_LEN];
u8 process_name[TASK_COMM_LEN];
u8 container_id[CONTAINER_ID_SIZE];
u32 interp_frame_count; // number of structured interpreter frames
u64 interp_frames_ptr; // pointer to interp_symbol_info_t array
u8 raw_interpreter_data; // 1 = has structured interpreter data
u32 data_len;
u64 data_ptr;
u8 data[0];
Expand Down
Loading
Loading