From df87ec5f716820284802233d2e7f811013008528 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 | 11 ++++++++++- src/trace_writer.ml | 6 +++--- 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/core/event.ml b/core/event.ml index b99177802a..fcc9d44c2c 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 e9ab7f6d0e..7d50acd495 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 8e23f16417..2db0ad21a9 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]+) (.*)$|} + {|^ *(int|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]+) (.*)$|} |> 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,14 @@ let%test_module _ = (data (Trace (kind Call) (src 0x56234f77576b) (dst 0x56234f4bc7a0)))))) |}] ;; + let%expect_test "257" = + 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 0905fad8e2..88ac50f9a4 100644 --- a/src/trace_writer.ml +++ b/src/trace_writer.ml @@ -1004,9 +1004,9 @@ 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 +1093,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. *)