Skip to content

Commit

Permalink
demangle ocaml symbols function
Browse files Browse the repository at this point in the history
Signed-off-by: Clyve Gassant <cgassant@sas.upenn.edu>
  • Loading branch information
ClyveGassant committed Jul 27, 2022
1 parent ad91ae0 commit a81352a
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 2 deletions.
48 changes: 48 additions & 0 deletions core/demangle_ocaml_symbols.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
open! Core

let decode_two_digit_hexadecimal_number first_character second_character =
let%bind.Option hex_digit_of_first_character = Char.get_hex_digit first_character in
let%bind.Option hex_digit_of_second_character = Char.get_hex_digit second_character in
let leftshift_first_character = hex_digit_of_first_character lsl 4 in
let bit_or_on_the_hexadecimals =
leftshift_first_character lor hex_digit_of_second_character
in
Char.of_int bit_or_on_the_hexadecimals
;;

let parser =
let open Angstrom in
let strip_numeric_suffix =
char '_' *> skip_while Char.is_digit *> end_of_input *> return None
in
let double_underscores = string "__" >>| fun _ -> Some '.' in
let two_digit_hexadecimal_number =
let hex_character = satisfy Char.is_hex_digit in
let hexcode =
decode_two_digit_hexadecimal_number <$> char '$' *> hex_character <*> hex_character
in
hexcode
>>= fun integer ->
match integer with
| None -> fail "invalid integer"
| Some character -> return (Some character)
in
let normal_character = any_char >>| fun character -> Some character in
let token =
choice
~failure_msg:"unrecognized token"
[ strip_numeric_suffix
; double_underscores
; two_digit_hexadecimal_number
; normal_character
]
in
string "caml" *> many1 token
;;

let demangle mangled_symbol =
let mangled_string = Angstrom.parse_string ~consume:All parser mangled_symbol in
match mangled_string with
| Ok list -> Some (String.of_char_list (List.filter_map list ~f:Fn.id))
| Error _ -> None
;;
11 changes: 11 additions & 0 deletions core/demangle_ocaml_symbols.mli
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
open! Core

(** The logic for this function is derived from perf [0].
This function is used to change the symbols in the application
executable from a mangled form to a demangled form in ocaml. Now
when running [magic-trace run -trigger] the symbols will appear in
their demangled form. Will return None if the symbol is not
recognized as an OCaml symbol.
[0]: https://github.com/torvalds/linux/blob/5bfc75d92efd494db37f5c4c173d3639d4772966/tools/perf/util/demangle-ocaml.c *)
val demangle : string -> string option
2 changes: 1 addition & 1 deletion core/dune
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
(name magic_trace_core)
(public_name magic-trace.magic_trace_core)
(libraries core async core_unix.filename_unix expect_test_helpers_core fzf
magic_trace owee re)
magic_trace owee re angstrom)
(inline_tests)
(preprocess
(pps ppx_jane)))
8 changes: 7 additions & 1 deletion core/symbol_selection.ml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,13 @@ let select_owee_symbol ~elf ~header select =
let open Deferred.Or_error.Let_syntax in
let all_symbols = Elf.all_symbols ~select elf in
let all_symbol_names = List.map all_symbols ~f:Tuple2.get1 in
match%bind Fzf.pick_one ~header (Inputs all_symbol_names) with
let demangled_symbols =
List.map all_symbol_names ~f:(fun mangled_symbol ->
match Demangle_ocaml_symbols.demangle mangled_symbol with
| None -> mangled_symbol, mangled_symbol
| Some demangled_symbol -> demangled_symbol, mangled_symbol)
in
match%bind Fzf.pick_one ~header (Assoc demangled_symbols) with
| None -> Deferred.Or_error.error_string "No symbol selected"
| Some chosen_name ->
let chosen_symbol =
Expand Down
27 changes: 27 additions & 0 deletions test/demangle_ocaml_symbols.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
open! Core
open Magic_trace_core

let demangle_symbol_test symbol =
let demangle_symbol = Demangle_ocaml_symbols.demangle symbol in
print_s [%sexp (demangle_symbol : string option)]
;;

let%expect_test "real mangled symbol" =
demangle_symbol_test "camlAsync_unix__Unix_syscalls__to_string_57255";
[%expect {| (Async_unix.Unix_syscalls.to_string) |}]
;;

let%expect_test "proper hexcode" =
demangle_symbol_test "caml$3f";
[%expect {| (?) |}]
;;

let%expect_test "improper hexcode" =
demangle_symbol_test "caml$7l";
[%expect {| ($7l) |}]
;;

let%expect_test "when the symbol is not a demangled ocaml symbol" =
demangle_symbol_test "dr__$3e$21_358";
[%expect {| () |}]
;;

0 comments on commit a81352a

Please sign in to comment.