Skip to content
Merged
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
55 changes: 25 additions & 30 deletions ghostscope-compiler/src/ebpf/codegen/expr_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ impl<'ctx, 'dw> EbpfContext<'ctx, 'dw> {
// Reserve space in accumulation buffer for this instruction
let inst_buffer = self
.reserve_instruction_region_or_return_zero(
(std::mem::size_of::<InstructionHeader>()
+ std::mem::size_of::<ghostscope_protocol::trace_event::ExprErrorData>())
as u64,
(INSTRUCTION_HEADER_SIZE + EXPR_ERROR_DATA_SIZE) as u64,
)?
.into_value_after_runtime_returns();

Expand All @@ -35,10 +33,10 @@ impl<'ctx, 'dw> EbpfContext<'ctx, 'dw> {
.build_gep(
self.context.i8_type(),
inst_buffer,
&[self.context.i32_type().const_int(
std::mem::offset_of!(InstructionHeader, data_length) as u64,
false,
)],
&[self
.context
.i32_type()
.const_int(INSTRUCTION_HEADER_DATA_LENGTH_OFFSET as u64, false)],
"exprerr_data_length_ptr",
)
.map_err(|e| {
Expand All @@ -53,27 +51,26 @@ impl<'ctx, 'dw> EbpfContext<'ctx, 'dw> {
"exprerr_data_length_i16_ptr",
)
.map_err(|e| CodeGenError::LLVMError(format!("Failed to cast data_length ptr: {e}")))?;
let data_length_val = self.context.i16_type().const_int(
std::mem::size_of::<ghostscope_protocol::trace_event::ExprErrorData>() as u64,
false,
);
let data_length_val = self
.context
.i16_type()
.const_int(EXPR_ERROR_DATA_SIZE as u64, false);
self.builder
.build_store(data_length_i16_ptr, data_length_val)
.map_err(|e| CodeGenError::LLVMError(format!("Failed to store data_length: {e}")))?;

// Payload fields after header
// string_index at offset sizeof(InstructionHeader) + 0 (u16)
// SAFETY: the payload immediately follows InstructionHeader in the
// reserved ExprError instruction region.
let si_ptr = unsafe {
self.builder
.build_gep(
self.context.i8_type(),
inst_buffer,
&[self
.context
.i32_type()
.const_int(std::mem::size_of::<InstructionHeader>() as u64, false)],
&[self.context.i32_type().const_int(
(INSTRUCTION_HEADER_SIZE + EXPR_ERROR_DATA_STRING_INDEX_OFFSET) as u64,
false,
)],
"exprerr_si_ptr",
)
.map_err(|e| {
Expand All @@ -98,17 +95,16 @@ impl<'ctx, 'dw> EbpfContext<'ctx, 'dw> {
.build_store(si_i16_ptr, si_val)
.map_err(|e| CodeGenError::LLVMError(format!("Failed to store string_index: {e}")))?;

// error_code at +2, flags at +3
// SAFETY: error_code offset is within ExprErrorData in the reserved payload.
let ec_ptr = unsafe {
self.builder
.build_gep(
self.context.i8_type(),
inst_buffer,
&[self
.context
.i32_type()
.const_int((std::mem::size_of::<InstructionHeader>() + 2) as u64, false)],
&[self.context.i32_type().const_int(
(INSTRUCTION_HEADER_SIZE + EXPR_ERROR_DATA_ERROR_CODE_OFFSET) as u64,
false,
)],
"exprerr_ec_ptr",
)
.map_err(|e| {
Expand Down Expand Up @@ -136,10 +132,10 @@ impl<'ctx, 'dw> EbpfContext<'ctx, 'dw> {
.build_gep(
self.context.i8_type(),
inst_buffer,
&[self
.context
.i32_type()
.const_int((std::mem::size_of::<InstructionHeader>() + 3) as u64, false)],
&[self.context.i32_type().const_int(
(INSTRUCTION_HEADER_SIZE + EXPR_ERROR_DATA_FLAGS_OFFSET) as u64,
false,
)],
"exprerr_flags_ptr",
)
.map_err(|e| CodeGenError::LLVMError(format!("Failed to get flags GEP: {e}")))?
Expand All @@ -160,17 +156,16 @@ impl<'ctx, 'dw> EbpfContext<'ctx, 'dw> {
.build_store(fl_ptr, fl_i8)
.map_err(|e| CodeGenError::LLVMError(format!("Failed to store flags: {e}")))?;

// failing_addr at +4 (u64)
// SAFETY: failing_addr offset is within ExprErrorData in the reserved payload.
let addr_ptr = unsafe {
self.builder
.build_gep(
self.context.i8_type(),
inst_buffer,
&[self
.context
.i32_type()
.const_int((std::mem::size_of::<InstructionHeader>() + 4) as u64, false)],
&[self.context.i32_type().const_int(
(INSTRUCTION_HEADER_SIZE + EXPR_ERROR_DATA_FAILING_ADDR_OFFSET) as u64,
false,
)],
"exprerr_addr_ptr",
)
.map_err(|e| CodeGenError::LLVMError(format!("Failed to get addr GEP: {e}")))?
Expand Down
2 changes: 2 additions & 0 deletions ghostscope-compiler/src/ebpf/codegen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ use aya_ebpf_bindings::bindings::bpf_func_id::BPF_FUNC_probe_read_user;
use ghostscope_protocol::trace_event::{
BacktraceData, EndInstructionData, InstructionHeader, PrintComplexFormatData,
PrintComplexVariableData, PrintStringIndexData, PrintVariableIndexData, VariableStatus,
EXPR_ERROR_DATA_ERROR_CODE_OFFSET, EXPR_ERROR_DATA_FAILING_ADDR_OFFSET,
EXPR_ERROR_DATA_FLAGS_OFFSET, EXPR_ERROR_DATA_SIZE, EXPR_ERROR_DATA_STRING_INDEX_OFFSET,
INSTRUCTION_HEADER_DATA_LENGTH_OFFSET, INSTRUCTION_HEADER_SIZE,
PRINT_COMPLEX_FORMAT_ARG_ACCESS_PATH_LEN_OFFSET, PRINT_COMPLEX_FORMAT_ARG_ACCESS_PATH_OFFSET,
PRINT_COMPLEX_FORMAT_ARG_FIXED_HEADER_LEN, PRINT_COMPLEX_FORMAT_ARG_STATUS_OFFSET,
Expand Down
14 changes: 9 additions & 5 deletions ghostscope-protocol/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,22 @@ pub mod type_info;
pub use type_kind::{consts, TypeKind};

pub use trace_event::{
EndInstructionData, InstructionHeader, InstructionType, PrintComplexFormatArgPrefix,
PrintStringIndexData, PrintVariableIndexData, TraceEventHeader, TraceEventMessage,
VariableReadErrorPayload, VariableStatus, END_INSTRUCTION_DATA_OFFSET,
EndInstructionData, ExprErrorData, InstructionHeader, InstructionType,
PrintComplexFormatArgPrefix, PrintStringIndexData, PrintVariableIndexData, TraceEventHeader,
TraceEventMessage, VariableReadErrorPayload, VariableStatus, END_INSTRUCTION_DATA_OFFSET,
END_INSTRUCTION_EXECUTION_STATUS_OFFSET, END_INSTRUCTION_TOTAL_INSTRUCTIONS_OFFSET,
EXPR_ERROR_DATA_ERROR_CODE_OFFSET, EXPR_ERROR_DATA_FAILING_ADDR_OFFSET,
EXPR_ERROR_DATA_FLAGS_OFFSET, EXPR_ERROR_DATA_SIZE, EXPR_ERROR_DATA_STRING_INDEX_OFFSET,
INSTRUCTION_HEADER_DATA_LENGTH_OFFSET, INSTRUCTION_HEADER_INST_TYPE_OFFSET,
INSTRUCTION_HEADER_RESERVED_OFFSET, INSTRUCTION_HEADER_SIZE,
PRINT_COMPLEX_FORMAT_ARG_ACCESS_PATH_LEN_OFFSET, PRINT_COMPLEX_FORMAT_ARG_ACCESS_PATH_OFFSET,
PRINT_COMPLEX_FORMAT_ARG_DATA_LEN_SIZE, PRINT_COMPLEX_FORMAT_ARG_FIXED_HEADER_LEN,
PRINT_COMPLEX_FORMAT_ARG_STATUS_OFFSET, PRINT_COMPLEX_FORMAT_ARG_TYPE_INDEX_OFFSET,
PRINT_COMPLEX_FORMAT_ARG_VAR_NAME_INDEX_OFFSET, PRINT_COMPLEX_FORMAT_DATA_ARG_COUNT_OFFSET,
VARIABLE_READ_ERROR_PAYLOAD_ADDR_OFFSET, VARIABLE_READ_ERROR_PAYLOAD_ERRNO_OFFSET,
VARIABLE_READ_ERROR_PAYLOAD_LEN,
TRACE_EVENT_HEADER_MAGIC_OFFSET, TRACE_EVENT_HEADER_SIZE, TRACE_EVENT_MESSAGE_PID_OFFSET,
TRACE_EVENT_MESSAGE_SIZE, TRACE_EVENT_MESSAGE_TID_OFFSET, TRACE_EVENT_MESSAGE_TIMESTAMP_OFFSET,
TRACE_EVENT_MESSAGE_TRACE_ID_OFFSET, VARIABLE_READ_ERROR_PAYLOAD_ADDR_OFFSET,
VARIABLE_READ_ERROR_PAYLOAD_ERRNO_OFFSET, VARIABLE_READ_ERROR_PAYLOAD_LEN,
};

pub use trace_context::TraceContext;
Expand Down
32 changes: 32 additions & 0 deletions ghostscope-protocol/src/trace_event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ pub struct TraceEventHeader {
pub magic: u32,
}

pub const TRACE_EVENT_HEADER_SIZE: usize = std::mem::size_of::<TraceEventHeader>();
pub const TRACE_EVENT_HEADER_MAGIC_OFFSET: usize = std::mem::offset_of!(TraceEventHeader, magic);

#[repr(C, packed)]
#[derive(Debug, Clone, Copy, FromBytes, IntoBytes, KnownLayout, Immutable, Unaligned)]
pub struct TraceEventMessage {
Expand All @@ -19,6 +22,14 @@ pub struct TraceEventMessage {
// Followed by variable-length instruction sequence ending with EndInstruction
}

pub const TRACE_EVENT_MESSAGE_SIZE: usize = std::mem::size_of::<TraceEventMessage>();
pub const TRACE_EVENT_MESSAGE_TRACE_ID_OFFSET: usize =
std::mem::offset_of!(TraceEventMessage, trace_id);
pub const TRACE_EVENT_MESSAGE_TIMESTAMP_OFFSET: usize =
std::mem::offset_of!(TraceEventMessage, timestamp);
pub const TRACE_EVENT_MESSAGE_PID_OFFSET: usize = std::mem::offset_of!(TraceEventMessage, pid);
pub const TRACE_EVENT_MESSAGE_TID_OFFSET: usize = std::mem::offset_of!(TraceEventMessage, tid);

/// Instruction types for trace events
#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
Expand Down Expand Up @@ -178,6 +189,15 @@ pub struct ExprErrorData {
pub failing_addr: u64, // Optional: address involved in failure (0 if unknown)
}

pub const EXPR_ERROR_DATA_SIZE: usize = std::mem::size_of::<ExprErrorData>();
pub const EXPR_ERROR_DATA_STRING_INDEX_OFFSET: usize =
std::mem::offset_of!(ExprErrorData, string_index);
pub const EXPR_ERROR_DATA_ERROR_CODE_OFFSET: usize =
std::mem::offset_of!(ExprErrorData, error_code);
pub const EXPR_ERROR_DATA_FLAGS_OFFSET: usize = std::mem::offset_of!(ExprErrorData, flags);
pub const EXPR_ERROR_DATA_FAILING_ADDR_OFFSET: usize =
std::mem::offset_of!(ExprErrorData, failing_addr);

/// End instruction data - marks the end of instruction sequence
#[repr(C, packed)]
#[derive(Debug, Clone, Copy, FromBytes, KnownLayout, Immutable, Unaligned)]
Expand Down Expand Up @@ -257,6 +277,13 @@ mod tests {

#[test]
fn protocol_layout_constants_match_wire_format() {
assert_eq!(TRACE_EVENT_HEADER_SIZE, 4);
assert_eq!(TRACE_EVENT_HEADER_MAGIC_OFFSET, 0);
assert_eq!(TRACE_EVENT_MESSAGE_SIZE, 24);
assert_eq!(TRACE_EVENT_MESSAGE_TRACE_ID_OFFSET, 0);
assert_eq!(TRACE_EVENT_MESSAGE_TIMESTAMP_OFFSET, 8);
assert_eq!(TRACE_EVENT_MESSAGE_PID_OFFSET, 16);
assert_eq!(TRACE_EVENT_MESSAGE_TID_OFFSET, 20);
assert_eq!(INSTRUCTION_HEADER_SIZE, 4);
assert_eq!(INSTRUCTION_HEADER_INST_TYPE_OFFSET, 0);
assert_eq!(INSTRUCTION_HEADER_DATA_LENGTH_OFFSET, 1);
Expand All @@ -267,6 +294,11 @@ mod tests {
assert_eq!(VARIABLE_READ_ERROR_PAYLOAD_LEN, 12);
assert_eq!(VARIABLE_READ_ERROR_PAYLOAD_ERRNO_OFFSET, 0);
assert_eq!(VARIABLE_READ_ERROR_PAYLOAD_ADDR_OFFSET, 4);
assert_eq!(EXPR_ERROR_DATA_SIZE, 12);
assert_eq!(EXPR_ERROR_DATA_STRING_INDEX_OFFSET, 0);
assert_eq!(EXPR_ERROR_DATA_ERROR_CODE_OFFSET, 2);
assert_eq!(EXPR_ERROR_DATA_FLAGS_OFFSET, 3);
assert_eq!(EXPR_ERROR_DATA_FAILING_ADDR_OFFSET, 4);
assert_eq!(PRINT_COMPLEX_FORMAT_DATA_ARG_COUNT_OFFSET, 2);
assert_eq!(PRINT_COMPLEX_FORMAT_ARG_VAR_NAME_INDEX_OFFSET, 0);
assert_eq!(PRINT_COMPLEX_FORMAT_ARG_TYPE_INDEX_OFFSET, 2);
Expand Down
18 changes: 10 additions & 8 deletions ghostscope-protocol/src/type_kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,12 +151,10 @@ pub mod consts {
pub const MAX_TRACE_EVENT_SIZE: u16 = 8192;

/// Trace event message size
pub const TRACE_EVENT_MESSAGE_SIZE: usize =
std::mem::size_of::<crate::trace_event::TraceEventMessage>();
pub const TRACE_EVENT_MESSAGE_SIZE: usize = crate::trace_event::TRACE_EVENT_MESSAGE_SIZE;

/// Trace event header size
pub const TRACE_EVENT_HEADER_SIZE: usize =
std::mem::size_of::<crate::trace_event::TraceEventHeader>();
pub const TRACE_EVENT_HEADER_SIZE: usize = crate::trace_event::TRACE_EVENT_HEADER_SIZE;

/// Instruction header size
pub const INSTRUCTION_HEADER_SIZE: usize = crate::trace_event::INSTRUCTION_HEADER_SIZE;
Expand All @@ -166,10 +164,14 @@ pub mod consts {
std::mem::size_of::<crate::trace_event::PrintVariableIndexData>();

// TraceEventMessage field offsets
pub const TRACE_EVENT_MESSAGE_TRACE_ID_OFFSET: usize = 0;
pub const TRACE_EVENT_MESSAGE_TIMESTAMP_OFFSET: usize = 8;
pub const TRACE_EVENT_MESSAGE_PID_OFFSET: usize = 16;
pub const TRACE_EVENT_MESSAGE_TID_OFFSET: usize = 20;
pub const TRACE_EVENT_MESSAGE_TRACE_ID_OFFSET: usize =
crate::trace_event::TRACE_EVENT_MESSAGE_TRACE_ID_OFFSET;
pub const TRACE_EVENT_MESSAGE_TIMESTAMP_OFFSET: usize =
crate::trace_event::TRACE_EVENT_MESSAGE_TIMESTAMP_OFFSET;
pub const TRACE_EVENT_MESSAGE_PID_OFFSET: usize =
crate::trace_event::TRACE_EVENT_MESSAGE_PID_OFFSET;
pub const TRACE_EVENT_MESSAGE_TID_OFFSET: usize =
crate::trace_event::TRACE_EVENT_MESSAGE_TID_OFFSET;

// InstructionHeader field offsets
pub const INSTRUCTION_HEADER_INST_TYPE_OFFSET: usize =
Expand Down
Loading