src/Pure/ML/exn_debugger.ML
author wenzelm
Sat, 02 Apr 2016 21:55:32 +0200
changeset 62821 48c24d0b6d85
parent 62516 5732f1c31566
child 62889 99c7f31615c2
permissions -rw-r--r--
tuned signature;
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
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    18
local
62821
48c24d0b6d85 tuned signature;
wenzelm
parents: 62516
diff changeset
    19
  val tag =
48c24d0b6d85 tuned signature;
wenzelm
parents: 62516
diff changeset
    20
    Universal.tag () : ((string * ML_Compiler0.polyml_location) * exn) list option Universal.tag;
62498
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    21
in
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    22
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    23
fun start_trace () = Thread.setLocal (tag, SOME []);
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    24
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    25
fun update_trace entry exn =
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    26
  (case Thread.getLocal tag of
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    27
    SOME (SOME trace) => Thread.setLocal (tag, SOME ((entry, exn) :: trace))
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    28
  | _ => ());
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    29
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    30
fun stop_trace () =
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    31
  let
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    32
    val trace = (case Thread.getLocal tag of SOME (SOME trace) => trace | _ => []);
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    33
    val _ = Thread.setLocal (tag, NONE);
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    34
  in trace end;
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    35
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    36
val _ = ML_Debugger.on_exit_exception (SOME update_trace);
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    37
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    38
end;
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    39
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    40
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    41
(* capture exception trace *)
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    42
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    43
local
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    44
  fun eq_exn exns =
62516
5732f1c31566 tuned signature -- clarified modules;
wenzelm
parents: 62498
diff changeset
    45
    op = (apply2 General.exnName exns) andalso op = (apply2 Exn_Properties.position exns);
62498
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    46
in
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    47
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    48
fun capture_exception_trace e =
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    49
  uninterruptible (fn restore_attributes => fn () =>
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    50
    let
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    51
      val _ = start_trace ();
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    52
      val result = Exn.interruptible_capture (restore_attributes e) ();
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    53
      val trace = stop_trace ();
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    54
      val trace' =
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    55
        (case result of
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    56
          Exn.Res _ => []
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    57
        | Exn.Exn exn =>
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    58
            trace
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    59
            |> 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
    60
            |> rev);
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    61
    in (trace', result) end) ();
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    62
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    63
end;
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    64
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    65
end;