Skip to content

Commit bd61c79

Browse files
committed
Refactor tracepoint handling in eBPF code generation, switch to regular tracepoint.
1 parent f79413f commit bd61c79

File tree

3 files changed

+51
-48
lines changed

3 files changed

+51
-48
lines changed

src/ebpf_c_codegen.ml

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3347,18 +3347,11 @@ let generate_c_function ctx ir_func =
33473347
| Some Ast.StructOps -> sprintf "SEC(\"struct_ops/%s\")" ir_func.func_name (* struct_ops functions use their name in the section *)
33483348
| Some Ast.Kprobe when ir_func.is_main -> "SEC(\"kprobe\")" (* Always use kprobe section for kprobe functions *)
33493349
| Some Ast.Tracepoint when ir_func.is_main ->
3350-
(* For tracepoint functions, generate specific SEC based on function name *)
3350+
(* For tracepoint functions, generate specific SEC based on target *)
33513351
(match ir_func.func_target with
33523352
| Some target ->
3353-
(* If we have the target, convert KernelScript format to raw tracepoint format *)
3354-
if String.contains target '/' then
3355-
(* For raw tracepoints, extract just the event name (part after slash) *)
3356-
let parts = String.split_on_char '/' target in
3357-
(match parts with
3358-
| [_category; event] -> sprintf "SEC(\"raw_tracepoint/%s\")" event
3359-
| _ -> sprintf "SEC(\"raw_tracepoint/%s\")" target)
3360-
else
3361-
sprintf "SEC(\"raw_tracepoint/%s\")" target
3353+
(* Convert KernelScript "category/event" format to regular tracepoint SEC format *)
3354+
sprintf "SEC(\"tracepoint/%s\")" target
33623355
| None ->
33633356
(* This should not happen now that we properly pass targets through *)
33643357
failwith "Tracepoint function is missing target information")

src/userspace_codegen.ml

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3297,15 +3297,25 @@ static int add_attachment(int prog_fd, const char *target, uint32_t flags,
32973297
32983298
return 0;
32993299
}
3300-
case BPF_PROG_TYPE_RAW_TRACEPOINT: {
3301-
// For raw tracepoint programs, target should be just the event name (e.g., "sched_switch")
3302-
// Extract event name from "category:event" format if needed
3300+
case BPF_PROG_TYPE_TRACEPOINT: {
3301+
// For regular tracepoint programs, target should be in "category:event" format (e.g., "sched:sched_switch")
3302+
// Split into category and event name for attachment
33033303
3304-
char *event_name = target;
3305-
char *colon_pos = strchr(target, ':');
3304+
// Make a copy of target since we need to modify it
3305+
char target_copy[256];
3306+
strncpy(target_copy, target, sizeof(target_copy) - 1);
3307+
target_copy[sizeof(target_copy) - 1] = '\0';
3308+
3309+
char *category = target_copy;
3310+
char *event_name = NULL;
3311+
char *colon_pos = strchr(target_copy, ':');
33063312
if (colon_pos) {
3307-
// Skip past the colon to get just the event name
3313+
// Null-terminate category and get event name
3314+
*colon_pos = '\0';
33083315
event_name = colon_pos + 1;
3316+
} else {
3317+
fprintf(stderr, "Invalid tracepoint target format: '%s'. Expected 'category:event'\n", target);
3318+
return -1;
33093319
}
33103320
33113321
// Get the bpf_program struct from the object and file descriptor
@@ -3314,7 +3324,7 @@ static int add_attachment(int prog_fd, const char *target, uint32_t flags,
33143324
// Find the program object corresponding to this fd
33153325
// We need to get the program from the skeleton object
33163326
if (!obj) {
3317-
fprintf(stderr, "eBPF skeleton not loaded for raw tracepoint attachment\n");
3327+
fprintf(stderr, "eBPF skeleton not loaded for tracepoint attachment\n");
33183328
return -1;
33193329
}
33203330
@@ -3329,21 +3339,21 @@ static int add_attachment(int prog_fd, const char *target, uint32_t flags,
33293339
return -1;
33303340
}
33313341
3332-
// Use libbpf's high-level raw tracepoint attachment API with just the event name
3333-
struct bpf_link *link = bpf_program__attach_raw_tracepoint(prog, event_name);
3342+
// Use libbpf's high-level tracepoint attachment API with category and event name
3343+
struct bpf_link *link = bpf_program__attach_tracepoint(prog, category, event_name);
33343344
if (!link) {
3335-
fprintf(stderr, "Failed to attach raw tracepoint to '%s': %s\n", event_name, strerror(errno));
3345+
fprintf(stderr, "Failed to attach tracepoint to '%s:%s': %s\n", category, event_name, strerror(errno));
33363346
return -1;
33373347
}
33383348
3339-
// Store raw tracepoint attachment for later cleanup
3340-
if (add_attachment(prog_fd, target, flags, link, 0, BPF_PROG_TYPE_RAW_TRACEPOINT) != 0) {
3349+
// Store tracepoint attachment for later cleanup
3350+
if (add_attachment(prog_fd, target, flags, link, 0, BPF_PROG_TYPE_TRACEPOINT) != 0) {
33413351
// If storage fails, destroy link and return error
33423352
bpf_link__destroy(link);
33433353
return -1;
33443354
}
33453355
3346-
printf("Raw tracepoint attached to: %s\n", event_name);
3356+
printf("Tracepoint attached to: %s:%s\n", category, event_name);
33473357
33483358
return 0;
33493359
}
@@ -3388,12 +3398,12 @@ static int add_attachment(int prog_fd, const char *target, uint32_t flags,
33883398
}
33893399
break;
33903400
}
3391-
case BPF_PROG_TYPE_RAW_TRACEPOINT: {
3401+
case BPF_PROG_TYPE_TRACEPOINT: {
33923402
if (entry->link) {
33933403
bpf_link__destroy(entry->link);
3394-
printf("Raw tracepoint detached from: %s\n", entry->target);
3404+
printf("Tracepoint detached from: %s\n", entry->target);
33953405
} else {
3396-
fprintf(stderr, "Invalid raw tracepoint link for program fd %d\n", prog_fd);
3406+
fprintf(stderr, "Invalid tracepoint link for program fd %d\n", prog_fd);
33973407
}
33983408
break;
33993409
}

tests/test_tracepoint.ml

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -220,11 +220,11 @@ fn sched_switch_handler(ctx: *trace_event_raw_sched_switch) -> i32 {
220220
let test_multiple_tracepoint_targets _ =
221221
(* Test various tracepoint targets to ensure they all work correctly *)
222222
let test_cases = [
223-
("sched/sched_switch", "SEC(\"raw_tracepoint/sched_switch\")");
224-
("net/netif_rx", "SEC(\"raw_tracepoint/netif_rx\")");
225-
("syscalls/sys_enter_read", "SEC(\"raw_tracepoint/sys_enter_read\")");
226-
("syscalls/sys_exit_write", "SEC(\"raw_tracepoint/sys_exit_write\")");
227-
("irq/irq_handler_entry", "SEC(\"raw_tracepoint/irq_handler_entry\")");
223+
("sched/sched_switch", "SEC(\"tracepoint/sched/sched_switch\")");
224+
("net/netif_rx", "SEC(\"tracepoint/net/netif_rx\")");
225+
("syscalls/sys_enter_read", "SEC(\"tracepoint/syscalls/sys_enter_read\")");
226+
("syscalls/sys_exit_write", "SEC(\"tracepoint/syscalls/sys_exit_write\")");
227+
("irq/irq_handler_entry", "SEC(\"tracepoint/irq/irq_handler_entry\")");
228228
] in
229229

230230
List.iter (fun (target, expected_sec) ->
@@ -255,34 +255,34 @@ fn sched_switch_handler(ctx: *trace_event_raw_sched_switch) -> i32 {
255255
let c_code = generate_c_multi_program ir_multi_prog in
256256

257257
(* Ensure correct SEC() is generated *)
258-
check bool "Should generate correct SEC(raw_tracepoint/sched_switch)" true
259-
(Str.search_forward (Str.regexp_string "SEC(\"raw_tracepoint/sched_switch\")") c_code 0 >= 0);
258+
check bool "Should generate correct SEC(tracepoint/sched/sched_switch)" true
259+
(Str.search_forward (Str.regexp_string "SEC(\"tracepoint/sched/sched_switch\")") c_code 0 >= 0);
260260

261261
(* Ensure buggy SEC() is NOT generated *)
262-
check bool "Should NOT generate buggy SEC(raw_tracepoint/sched_sched)" true
262+
check bool "Should NOT generate any raw_tracepoint SEC format" true
263263
(try
264-
let _ = Str.search_forward (Str.regexp_string "SEC(\"raw_tracepoint/sched_sched\")") c_code 0 in
265-
false (* Found the buggy pattern - test should fail *)
264+
let _ = Str.search_forward (Str.regexp_string "SEC(\"raw_tracepoint/") c_code 0 in
265+
false (* Found raw_tracepoint - test should fail *)
266266
with Not_found ->
267-
true (* Didn't find the buggy pattern - test should pass *)
267+
true (* No raw_tracepoint found - test should pass *)
268268
)
269269

270270
(* 4. Code Generation Tests *)
271-
let test_raw_tracepoint_section_name_generation _ =
272-
(* Test correct raw tracepoint section name generation *)
271+
let test_tracepoint_section_name_generation _ =
272+
(* Test correct tracepoint section name generation *)
273273
let source = "@tracepoint(\"sched/sched_switch\")
274274
fn sched_switch_handler(ctx: *trace_event_raw_sched_switch) -> i32 {
275275
return 0
276276
}" in
277277
let ast = parse_string source in
278278
let typed_ast = type_check_ast ast in
279279
let symbol_table = Kernelscript.Symbol_table.build_symbol_table typed_ast in
280-
let ir_multi_prog = generate_ir typed_ast symbol_table "test_raw_tracepoint" in
280+
let ir_multi_prog = generate_ir typed_ast symbol_table "test_tracepoint" in
281281
let c_code = generate_c_multi_program ir_multi_prog in
282282

283-
(* Check that the correct SEC() is generated with just the event name *)
284-
check bool "Should contain correct raw_tracepoint/sched_switch section" true
285-
(Str.search_forward (Str.regexp_string "SEC(\"raw_tracepoint/sched_switch\")") c_code 0 >= 0)
283+
(* Check that the correct SEC() is generated with the full path *)
284+
check bool "Should contain correct tracepoint/sched/sched_switch section" true
285+
(Str.search_forward (Str.regexp_string "SEC(\"tracepoint/sched/sched_switch\")") c_code 0 >= 0)
286286

287287
let test_tracepoint_ebpf_codegen _ =
288288
let source = "@tracepoint(\"sched/sched_switch\")
@@ -296,8 +296,8 @@ fn sched_switch_handler(ctx: *trace_event_raw_sched_switch) -> i32 {
296296
let c_code = generate_c_multi_program ir_multi_prog in
297297

298298
(* Check for tracepoint-specific C code elements *)
299-
check bool "Should contain correct raw_tracepoint SEC" true
300-
(Str.search_forward (Str.regexp_string "SEC(\"raw_tracepoint/sched_switch\")") c_code 0 >= 0);
299+
check bool "Should contain correct tracepoint SEC" true
300+
(Str.search_forward (Str.regexp_string "SEC(\"tracepoint/sched/sched_switch\")") c_code 0 >= 0);
301301
check bool "Should contain function definition" true
302302
(String.contains c_code (String.get "sched_switch_handler" 0));
303303
check bool "Should contain struct parameter" true
@@ -408,8 +408,8 @@ fn sys_enter_open_handler(ctx: *trace_event_raw_sys_enter) -> i32 {
408408
let c_code = generate_c_multi_program ir_multi_prog in
409409

410410
(* Comprehensive end-to-end validation *)
411-
check bool "Contains correct raw_tracepoint section" true
412-
(Str.search_forward (Str.regexp_string "SEC(\"raw_tracepoint/sys_enter_open\")") c_code 0 >= 0);
411+
check bool "Contains correct tracepoint section" true
412+
(Str.search_forward (Str.regexp_string "SEC(\"tracepoint/syscalls/sys_enter_open\")") c_code 0 >= 0);
413413
check bool "Contains function name" true
414414
(String.contains c_code (String.get "sys_enter_open_handler" 0));
415415
check bool "Contains context struct" true
@@ -453,7 +453,7 @@ let ir_generation_tests = [
453453
]
454454

455455
let code_generation_tests = [
456-
"raw tracepoint section name generation", `Quick, test_raw_tracepoint_section_name_generation;
456+
"tracepoint section name generation", `Quick, test_tracepoint_section_name_generation;
457457
"tracepoint eBPF code generation", `Quick, test_tracepoint_ebpf_codegen;
458458
"tracepoint includes generation", `Quick, test_tracepoint_includes_generation;
459459
]

0 commit comments

Comments
 (0)