src/Pure/ML/exn_debugger.ML
author wenzelm
Wed, 22 Apr 2020 19:22:43 +0200
changeset 71787 acfe72ff00c2
parent 62937 d5e7a76ec1a6
child 78705 fde0b195cb7d
permissions -rw-r--r--
merged
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
62498
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
     1
(*  Title:      Pure/ML/exn_debugger.ML
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
     2
    Author:     Makarius
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
     3
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
     4
Detailed exception trace via ML debugger.
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
     5
*)
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
     6
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
     7
signature EXN_DEBUGGER =
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
     8
sig
62821
48c24d0b6d85 tuned signature;
wenzelm
parents: 62516
diff changeset
     9
  val capture_exception_trace:
48c24d0b6d85 tuned signature;
wenzelm
parents: 62516
diff changeset
    10
    (unit -> 'a) -> (string * ML_Compiler0.polyml_location) list * 'a Exn.result
62498
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    11
end;
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    12
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    13
structure Exn_Debugger: EXN_DEBUGGER =
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    14
struct
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    15
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    16
(* thread data *)
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    17
62889
99c7f31615c2 clarified modules;
wenzelm
parents: 62821
diff changeset
    18
val trace_var =
99c7f31615c2 clarified modules;
wenzelm
parents: 62821
diff changeset
    19
  Thread_Data.var () : ((string * ML_Compiler0.polyml_location) * exn) list Thread_Data.var;
62498
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    20
62889
99c7f31615c2 clarified modules;
wenzelm
parents: 62821
diff changeset
    21
fun start_trace () = Thread_Data.put trace_var (SOME []);
62498
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    22
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    23
fun update_trace entry exn =
62889
99c7f31615c2 clarified modules;
wenzelm
parents: 62821
diff changeset
    24
  (case Thread_Data.get trace_var of
99c7f31615c2 clarified modules;
wenzelm
parents: 62821
diff changeset
    25
    SOME trace => Thread_Data.put trace_var (SOME ((entry, exn) :: trace))
99c7f31615c2 clarified modules;
wenzelm
parents: 62821
diff changeset
    26
  | NONE => ());
62498
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    27
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    28
fun stop_trace () =
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    29
  let
62889
99c7f31615c2 clarified modules;
wenzelm
parents: 62821
diff changeset
    30
    val trace = the_default [] (Thread_Data.get trace_var);
99c7f31615c2 clarified modules;
wenzelm
parents: 62821
diff changeset
    31
    val _ = Thread_Data.put trace_var NONE;
62498
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    32
  in trace end;
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    33
62937
d5e7a76ec1a6 clarified modules;
wenzelm
parents: 62923
diff changeset
    34
val _ = PolyML.DebuggerInterface.setOnExitException (SOME update_trace);
62498
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    35
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    36
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    37
(* capture exception trace *)
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    38
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    39
local
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    40
  fun eq_exn exns =
62516
5732f1c31566 tuned signature -- clarified modules;
wenzelm
parents: 62498
diff changeset
    41
    op = (apply2 General.exnName exns) andalso op = (apply2 Exn_Properties.position exns);
62498
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    42
in
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    43
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    44
fun capture_exception_trace e =
62923
3a122e1e352a clarified bootstrap;
wenzelm
parents: 62891
diff changeset
    45
  Thread_Attributes.uninterruptible (fn restore_attributes => fn () =>
62498
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    46
    let
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    47
      val _ = start_trace ();
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    48
      val result = Exn.interruptible_capture (restore_attributes e) ();
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    49
      val trace = stop_trace ();
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    50
      val trace' =
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    51
        (case result of
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    52
          Exn.Res _ => []
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    53
        | Exn.Exn exn =>
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    54
            trace
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    55
            |> map_filter (fn (entry, e) => if eq_exn (exn, e) then SOME entry else NONE)
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    56
            |> rev);
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    57
    in (trace', result) end) ();
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    58
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    59
end;
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    60
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    61
end;