From dc62d9e38d60752e65d0022ce984b471853ac6cd Mon Sep 17 00:00:00 2001 From: Tudor Brindus Date: Sun, 13 Nov 2022 20:46:55 -0500 Subject: [PATCH] Recognize `int3` instructions in trace parser Not quite sure why we'd be seeing this, but let's not crash when we do. For now, treat a software interrupt as a jump. Ref https://github.com/janestreet/magic-trace/issues/257 --- core/event.ml | 1 + core/event.mli | 1 + src/perf_decode.ml | 16 +++++++++++++++- src/trace_writer.ml | 14 +++++++++++--- 4 files changed, 28 insertions(+), 4 deletions(-) diff --git a/core/event.ml b/core/event.ml index b99177802..fcc9d44c2 100644 --- a/core/event.ml +++ b/core/event.ml @@ -7,6 +7,7 @@ module Kind = struct | Syscall | Sysret | Hardware_interrupt + | Interrupt | Iret | Jump [@@deriving sexp, compare, bin_io] diff --git a/core/event.mli b/core/event.mli index e9ab7f6d0..7d50acd49 100644 --- a/core/event.mli +++ b/core/event.mli @@ -7,6 +7,7 @@ module Kind : sig | Syscall | Sysret | Hardware_interrupt + | Interrupt | Iret | Jump [@@deriving sexp, compare] diff --git a/src/perf_decode.ml b/src/perf_decode.ml index 8e23f1641..de51e7c77 100644 --- a/src/perf_decode.ml +++ b/src/perf_decode.ml @@ -22,7 +22,7 @@ let perf_callstack_entry_re = Re.Perl.re "^\t *([0-9a-f]+) (.*)$" |> Re.compile let perf_branches_event_re = Re.Perl.re - {|^ *(call|return|tr strt|syscall|sysret|hw int|iret|tr end|tr strt tr end|tr end (?:call|return|syscall|sysret|iret)|jmp|jcc) +([0-9a-f]+) (.*) => +([0-9a-f]+) (.*)$|} + {|^ *(call|return|tr strt|syscall|sysret|hw int|iret|int|tr end|tr strt tr end|tr end (?:call|return|syscall|sysret|iret)|jmp|jcc) +([0-9a-f]+) (.*) => +([0-9a-f]+) (.*)$|} |> Re.compile ;; @@ -243,6 +243,7 @@ let parse_perf_branches_event ?perf_maps (thread : Event.Thread.t) time line : E match String.strip kind with | "call" -> Some Call | "return" -> Some Return + | "int" -> Some Interrupt | "jmp" -> Some Jump | "jcc" -> Some Jump | "syscall" -> Some Syscall @@ -495,6 +496,19 @@ let%test_module _ = (data (Trace (kind Call) (src 0x56234f77576b) (dst 0x56234f4bc7a0)))))) |}] ;; + let%expect_test "software interrupts" = + check + "1907478/1909463 457407.880965552: 1 \ + branches:uH: int 564aa58813d4 \ + Builtins_RunMicrotasks+0x554 (/usr/local/bin/workload) => 564aa584fa00 \ + Builtins_Call_ReceiverIsNotNullOrUndefined+0x0 (/usr/local/bin/workload)"; + [%expect + {| + ((Ok + ((thread ((pid (1907478)) (tid (1909463)))) (time 5d7h3m27.880965552s) + (data (Trace (kind Interrupt) (src 0x564aa58813d4) (dst 0x564aa584fa00)))))) |}] + ;; + let%expect_test "decode error with a timestamp" = check " instruction trace error type 1 time 47170.086912826 cpu -1 pid 293415 tid \ diff --git a/src/trace_writer.ml b/src/trace_writer.ml index 0905fad8e..2929f6d0f 100644 --- a/src/trace_writer.ml +++ b/src/trace_writer.ml @@ -1004,9 +1004,17 @@ let write_event (T t) ?events_writer event = ~time; (match kind, trace_state_change with | Some Call, (None | Some End) -> call t thread_info ~time ~location:dst - | ( Some (Call | Syscall | Return | Hardware_interrupt | Iret | Sysret | Jump) + | ( Some + ( Call + | Syscall + | Return + | Hardware_interrupt + | Iret + | Interrupt + | Sysret + | Jump ) , Some Start ) - | Some (Hardware_interrupt | Jump), Some End -> + | Some (Hardware_interrupt | Jump | Interrupt), Some End -> raise_s [%message "BUG: magic-trace devs thought this event was impossible, but you just \ @@ -1093,7 +1101,7 @@ let write_event (T t) ?events_writer event = ~addr:dst.instruction_pointer ~time; check_current_symbol t thread_info ~time dst) - | Some Jump, None -> + | Some (Jump | Interrupt), None -> Ocaml_hacks.check_current_symbol_track_entertraps t thread_info ~time dst (* (None, _) comes up when perf spews something magic-trace doesn't recognize. Instead of crashing, ignore it and keep going. *)