src/Pure/ML/exn_debugger.ML
author wenzelm
Sat, 05 Mar 2016 13:51:21 +0100
changeset 62516 5732f1c31566
parent 62498 5dfcc9697f29
child 62821 48c24d0b6d85
permissions -rw-r--r--
tuned signature -- clarified modules;
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
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
     9
  val capture_exception_trace: (unit -> 'a) -> (string * ML_Debugger.location) list * 'a Exn.result
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    10
end;
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    11
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    12
structure Exn_Debugger: EXN_DEBUGGER =
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    13
struct
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    14
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    15
(* thread data *)
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    16
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    17
local
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    18
  val tag = Universal.tag () : ((string * ML_Debugger.location) * exn) list option Universal.tag;
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    19
in
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    20
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    21
fun start_trace () = Thread.setLocal (tag, SOME []);
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 =
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    24
  (case Thread.getLocal tag of
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    25
    SOME (SOME trace) => Thread.setLocal (tag, SOME ((entry, exn) :: trace))
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    26
  | _ => ());
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
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    30
    val trace = (case Thread.getLocal tag of SOME (SOME trace) => trace | _ => []);
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    31
    val _ = Thread.setLocal (tag, NONE);
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
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    34
val _ = ML_Debugger.on_exit_exception (SOME update_trace);
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    35
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    36
end;
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    37
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    38
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    39
(* capture exception trace *)
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    40
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    41
local
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    42
  fun eq_exn exns =
62516
5732f1c31566 tuned signature -- clarified modules;
wenzelm
parents: 62498
diff changeset
    43
    op = (apply2 General.exnName exns) andalso op = (apply2 Exn_Properties.position exns);
62498
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    44
in
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    45
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    46
fun capture_exception_trace e =
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    47
  uninterruptible (fn restore_attributes => fn () =>
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    48
    let
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    49
      val _ = start_trace ();
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    50
      val result = Exn.interruptible_capture (restore_attributes e) ();
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    51
      val trace = stop_trace ();
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    52
      val trace' =
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    53
        (case result of
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    54
          Exn.Res _ => []
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    55
        | Exn.Exn exn =>
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    56
            trace
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    57
            |> 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
    58
            |> rev);
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    59
    in (trace', result) end) ();
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    60
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    61
end;
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    62
5dfcc9697f29 support for ML_exception_debugger;
wenzelm
parents:
diff changeset
    63
end;