Skip to content

Commit de6715b

Browse files
more tracing, use local store key for trace nameing
1 parent 874ddd6 commit de6715b

File tree

10 files changed

+156
-52
lines changed

10 files changed

+156
-52
lines changed

src/core/lwt.ml

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1671,6 +1671,10 @@ include Pending_promises
16711671

16721672

16731673

1674+
let tracing_context = new_key ()
1675+
let tracing_counter = ref 0
1676+
let tracing_counter () = incr tracing_counter; !tracing_counter
1677+
16741678
module Sequential_composition :
16751679
sig
16761680
(* Main interface (public) *)
@@ -1903,6 +1907,8 @@ struct
19031907
p''
19041908

19051909
let backtrace_bind (loc_f, loc_l, _, _) add_loc p f =
1910+
let trace_context = Sequence_associated_storage.get tracing_context in
1911+
let trace_counter = tracing_counter () in
19061912
let Internal p = to_internal_promise p in
19071913
let p = underlying p in
19081914

@@ -1912,7 +1918,7 @@ struct
19121918
let saved_storage = !current_storage in
19131919

19141920
let callback p_result =
1915-
Lwt_rte.emit_trace End loc_f loc_l;
1921+
Lwt_rte.emit_trace End trace_context trace_counter loc_f loc_l;
19161922
match p_result with
19171923
| Fulfilled v ->
19181924
current_storage := saved_storage;
@@ -1956,7 +1962,7 @@ struct
19561962
to_public_promise {state = Rejected (add_loc exn)}
19571963

19581964
| Pending p_callbacks ->
1959-
Lwt_rte.emit_trace Begin loc_f loc_l;
1965+
Lwt_rte.emit_trace Begin trace_context trace_counter loc_f loc_l;
19601966
let (p'', callback) = create_result_promise_and_callback_if_deferred () in
19611967
add_implicitly_removed_callback p_callbacks callback;
19621968
p''
@@ -2085,6 +2091,8 @@ struct
20852091
p''
20862092

20872093
let backtrace_catch (loc_f, loc_l, _, _) add_loc f h =
2094+
let trace_context = Sequence_associated_storage.get tracing_context in
2095+
let trace_counter = tracing_counter () in
20882096
let p =
20892097
try f ()
20902098
with exn when Exception_filter.run exn -> fail exn
@@ -2098,7 +2106,7 @@ struct
20982106
let saved_storage = !current_storage in
20992107

21002108
let callback p_result =
2101-
Lwt_rte.emit_trace End loc_f loc_l;
2109+
Lwt_rte.emit_trace End trace_context trace_counter loc_f loc_l;
21022110
match p_result with
21032111
| Fulfilled _ as p_result ->
21042112
let State_may_now_be_pending_proxy p'' = may_now_be_proxy p'' in
@@ -2143,7 +2151,7 @@ struct
21432151
(p'', callback, p.state))
21442152

21452153
| Pending p_callbacks ->
2146-
Lwt_rte.emit_trace Begin loc_f loc_l;
2154+
Lwt_rte.emit_trace Begin trace_context trace_counter loc_f loc_l;
21472155
let (p'', callback) = create_result_promise_and_callback_if_deferred () in
21482156
add_implicitly_removed_callback p_callbacks callback;
21492157
p''
@@ -2224,6 +2232,8 @@ struct
22242232
p''
22252233

22262234
let backtrace_try_bind (loc_f, loc_l, _, _) add_loc f f' h =
2235+
let trace_context = Sequence_associated_storage.get tracing_context in
2236+
let trace_counter = tracing_counter () in
22272237
let p =
22282238
try f ()
22292239
with exn when Exception_filter.run exn -> fail exn
@@ -2237,7 +2247,7 @@ struct
22372247
let saved_storage = !current_storage in
22382248

22392249
let callback p_result =
2240-
Lwt_rte.emit_trace End loc_f loc_l;
2250+
Lwt_rte.emit_trace End trace_context trace_counter loc_f loc_l;
22412251
match p_result with
22422252
| Fulfilled v ->
22432253
current_storage := saved_storage;
@@ -2297,7 +2307,7 @@ struct
22972307
(p'', callback, p.state))
22982308

22992309
| Pending p_callbacks ->
2300-
Lwt_rte.emit_trace Begin loc_f loc_l;
2310+
Lwt_rte.emit_trace Begin trace_context trace_counter loc_f loc_l;
23012311
let (p'', callback) = create_result_promise_and_callback_if_deferred () in
23022312
add_implicitly_removed_callback p_callbacks callback;
23032313
p''

src/core/lwt.mli

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2076,3 +2076,5 @@ module Private : sig
20762076
val current_storage : storage ref
20772077
end
20782078
end [@@alert trespassing "for internal use only, keep away"]
2079+
2080+
val tracing_context : string key

src/core/lwt_rte.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ val emit_sch_call_end : unit -> unit
44
val emit_sch_lap : unit -> unit
55
val emit_job_count : int -> unit
66
type span = Begin | End
7-
val emit_trace : span -> string -> int -> unit
7+
val emit_trace : span -> string option -> int -> string -> int -> unit

src/core/lwt_rte.with.ml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,4 @@ let emit_sch_call_end () = Lwt_runtime_events.emit_sch_call_end ()
44
let emit_sch_lap v = Lwt_runtime_events.emit_sch_lap v
55
let emit_job_count v = Lwt_runtime_events.emit_job_count v
66
type span = Runtime_events.Type.span = Begin | End
7-
let emit_trace k f l =
8-
let s = Printf.sprintf "%s:%d" f l in
9-
Lwt_runtime_events.Trace.emit_span (k, s)
7+
let emit_trace kind context count filename line = Lwt_runtime_events.Trace.emit {kind; context; count; filename; line}

src/core/lwt_rte.without.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ let emit_sch_call_end () = ()
44
let emit_sch_lap _v = ()
55
let emit_job_count _v = ()
66
type span = Begin | End
7-
let emit_trace _k _f _l = ()
7+
let emit_trace _ _ _ _ _ = ()

src/runtime_events/lwt_runtime_events.ml

Lines changed: 60 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -17,29 +17,65 @@ let emit_job_count v = Runtime_events.User.write unix_job_count v
1717

1818
module Trace = struct
1919

20-
type labelled_span = Runtime_events.Type.span * string
21-
let labelled_span : labelled_span Runtime_events.Type.t =
22-
Runtime_events.Type.register
23-
~encode:(fun b (k, s) ->
24-
let () = match k with
25-
| Runtime_events.Type.Begin -> Bytes.set b 0 'B'
26-
| End -> Bytes.set b 0 'E'
27-
in
28-
let l = min (String.length s) (Bytes.length b - 1) in
29-
Bytes.blit_string s 0 b 1 l;
30-
(l + 1))
31-
~decode:(fun b i ->
32-
if i < 1 then failwith "unreadable tag for labelled_span";
33-
let k = match Bytes.get b 0 with
34-
| 'B' -> Runtime_events.Type.Begin
35-
| 'E' -> End
36-
| _ -> failwith "unreadable tag for labelled_span";
37-
in
38-
let s = Bytes.sub_string b 1 (i - 1) in
39-
(k, s))
40-
41-
type Runtime_events.User.tag += LabelledSpan
42-
let span = Runtime_events.User.register "lwt-trace" LabelledSpan labelled_span
43-
let emit_span labelled_span = Runtime_events.User.write span labelled_span
20+
type t =
21+
{ kind: Runtime_events.Type.span;
22+
context: string option;
23+
count: int;
24+
filename: string;
25+
line: int; }
26+
27+
let decode b i =
28+
let offset = 0 in
29+
let kind = match Bytes.get b offset with
30+
| 'B' -> Runtime_events.Type.Begin
31+
| 'E' -> End
32+
| _ -> failwith "unreadable tag for labelled_span";
33+
in
34+
let offset = offset + 1 in
35+
let context_size = Bytes.get_uint8 b offset in
36+
let offset = offset + 1 in
37+
let context = if context_size = 0 then None else Some (Bytes.sub_string b offset context_size) in
38+
let offset = offset + context_size in
39+
let count = BytesLabels.get_uint16_be b offset in
40+
let offset = offset + 2 in
41+
let line = Bytes.get_uint16_be b offset in
42+
let offset = offset + 2 in
43+
let filename_size = Bytes.get_uint8 b offset in
44+
let offset = offset + 1 in
45+
let filename = Bytes.sub_string b offset filename_size in
46+
let offset = offset + filename_size in
47+
assert (offset = i);
48+
{ kind; context; count; filename; line }
49+
50+
let encode b { kind; context; count; filename; line } =
51+
let offset = 0 in
52+
Bytes.set b offset (match kind with Begin -> 'B' | End -> 'E');
53+
let offset = offset + 1 in
54+
let offset =
55+
match context with
56+
| None -> Bytes.set_uint8 b offset 0; offset + 1
57+
| Some context ->
58+
Bytes.set_uint8 b offset (String.length context);
59+
let offset = offset + 1 in
60+
Bytes.blit_string context 0 b offset (String.length context);
61+
offset + String.length context
62+
in
63+
Bytes.set_uint16_be b offset count;
64+
let offset = offset + 2 in
65+
Bytes.set_uint16_be b offset line;
66+
let offset = offset + 2 in
67+
let filename_truncated_length = min (String.length filename) (Bytes.length b - offset) in
68+
Bytes.set_uint8 b offset filename_truncated_length;
69+
let offset = offset + 1 in
70+
Bytes.blit_string filename 0 b offset filename_truncated_length;
71+
let offset = offset + filename_truncated_length in
72+
assert (offset <= Bytes.length b);
73+
offset
74+
75+
let t : t Runtime_events.Type.t = Runtime_events.Type.register ~encode ~decode
76+
77+
type Runtime_events.User.tag += T
78+
let span = Runtime_events.User.register "lwt-trace" T t
79+
let emit t = Runtime_events.User.write span t
4480

4581
end

src/runtime_events/lwt_runtime_events.mli

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ val unix_job_count : int Runtime_events.User.t
1616
val emit_job_count : int -> unit
1717

1818
module Trace : sig
19-
type labelled_span = Runtime_events.Type.span * string
20-
val labelled_span : labelled_span Runtime_events.Type.t
19+
type t = { kind: Runtime_events.Type.span; context: string option; count: int; filename: string; line: int; }
20+
val t : t Runtime_events.Type.t
2121

22-
type Runtime_events.User.tag += LabelledSpan
23-
val span : labelled_span Runtime_events.User.t
24-
val emit_span : labelled_span -> unit
22+
type Runtime_events.User.tag += T
23+
val span : t Runtime_events.User.t
24+
val emit : t -> unit
2525
end

test/ppx/main.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ open Lwt
1010
let%lwt structure_let_result = Lwt.return_true
1111
[@@@ocaml.warning "+22"]
1212

13+
let __trace_ctxt = "test" (* TODO: figure out how to make this implicit *)
14+
1315
let suite = suite "ppx" [
1416
test "let"
1517
(fun () ->

test/tracing/tailgate.ml

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,27 @@ let cursor =
1919

2020
let (_, _) = Unix.waitpid [WUNTRACED] pid
2121

22+
let simplify_fname fname =
23+
String.split_on_char '/' fname
24+
|> List.rev
25+
|> function
26+
| [] -> assert false
27+
| hd :: tl ->
28+
(hd :: "/" :: List.map (fun s -> String.make 1 s.[0]) tl)
29+
|> List.rev
30+
|> String.concat ""
31+
32+
let name_of { Lwt_runtime_events.Trace.context; count; filename; line; kind=_ } =
33+
let base =
34+
match context with
35+
| None -> simplify_fname filename ^ ":" ^ string_of_int line
36+
| Some c -> c
37+
in
38+
base ^ string_of_int count
39+
2240
let () = Printf.printf "crash! writing trace file %s/%d.tail\n" tmpdir pid
2341
let () =
24-
let buf_pool = Trace_fuchsia.Buf_pool.create () in
42+
let buf_pool = Trace_fuchsia.Buf_pool.create ~max_size:1024 () in
2543
let buf = Trace_fuchsia.Buf_chain.create ~sharded:false ~buf_pool () in
2644
let oc = open_out_bin (Printf.sprintf "%s/%d.tail" tmpdir pid) in
2745
let { Trace_fuchsia.Exporter.write_bufs; flush; close } as exporter = Trace_fuchsia.Exporter.of_out_channel ~close_channel:true oc in
@@ -30,25 +48,36 @@ let () =
3048
let cb =
3149
Runtime_events.Callbacks.create ()
3250
|> Runtime_events.Callbacks.add_user_event
33-
Lwt_runtime_events.Trace.labelled_span
51+
Lwt_runtime_events.Trace.t
3452
(fun _ t u x ->
3553
match Runtime_events.User.tag u with
36-
| Lwt_runtime_events.Trace.LabelledSpan -> begin
54+
| Lwt_runtime_events.Trace.T -> begin
3755
match x with
38-
| Begin, s ->
39-
Trace_fuchsia.Writer.Event.Duration_begin.encode buf ~name:s
56+
| { kind = Begin; context=_; count=_; filename; line } ->
57+
Trace_fuchsia.Writer.Event.Duration_begin.encode buf
58+
~name:(name_of x)
4059
~t_ref:(Ref 1)
4160
~time_ns:(Runtime_events.Timestamp.to_int64 t)
42-
~args:[]
61+
~args:["file", A_string filename; "line", A_int line]
4362
()
44-
| End, s ->
45-
Trace_fuchsia.Writer.Event.Duration_end.encode buf ~name:s
63+
| { kind = End; context=_; count=_; filename; line } ->
64+
Trace_fuchsia.Writer.Event.Duration_end.encode buf
65+
~name:(name_of x)
4666
~t_ref:(Ref 1)
4767
~time_ns:(Runtime_events.Timestamp.to_int64 t)
48-
~args:[]
68+
~args:["file", A_string filename; "line", A_int line]
4969
()
5070
end
5171
| _ -> ())
72+
|> Runtime_events.Callbacks.add_user_event
73+
Runtime_events.Type.unit
74+
(fun _ t e () ->
75+
match Runtime_events.User.tag e with
76+
| Lwt_runtime_events.Scheduler_lap ->
77+
Trace_fuchsia.Writer.Event.Instant.encode buf ~name:"lap"
78+
~t_ref:(Ref 1) ~time_ns:(Runtime_events.Timestamp.to_int64 t)
79+
~args:[] ()
80+
| _ -> ())
5281
|> Runtime_events.Callbacks.add_user_event
5382
Runtime_events.Type.int
5483
(fun _ t u x ->

test/tracing/work_and_crash.ml

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,52 @@ let () = Runtime_events.start ()
22

33
let rec ping () =
44
let p = Lwt.pause () in
5-
let%lwt _ping = Lwt_unix.sleep 0.01 in
5+
let%lwt _ping = Lwt_unix.sleep 0.01
6+
and _ping2 = Lwt_unix.sleep 0.01 in
67
pong p
78
and pong p =
89
let%lwt _ = p in
910
let%lwt _pong = Lwt_unix.sleep 0.01 in
1011
ping ()
1112
;;
1213

14+
let fibobo () =
15+
let rec fibobo n =
16+
if n <= 0 then Lwt.return 1 else
17+
let%lwt left =
18+
Lwt.with_value Lwt.tracing_context (Some "left") (fun () ->
19+
Lwt.bind (Lwt_unix.sleep 0.001) (fun () -> Lwt.bind (Lwt.pause ()) (fun () -> fibobo (n - 1))))
20+
and right =
21+
Lwt.with_value Lwt.tracing_context (Some "right") (fun () ->
22+
Lwt.bind (Lwt_unix.sleep 0.002) (fun () -> Lwt.bind (Lwt.pause ()) (fun () -> fibobo (n - 2))))
23+
in
24+
Lwt.return (left + right)
25+
in
26+
let%lwt () = Lwt_unix.sleep 0.02 in
27+
let%lwt _ = Lwt_list.map_s fibobo (List.init 6 (fun x -> x+2)) in
28+
fst (Lwt.task ()) (* never resolve *)
29+
;;
30+
1331
let rec eventually_crash n =
1432
if n < 0 then raise Exit else
1533
let%lwt do_some_work = Lwt_unix.sleep 0.004 in
1634
ignore do_some_work;
1735
eventually_crash (n - 1)
1836
;;
1937

38+
let eventually_crash n =
39+
Lwt.with_value Lwt.tracing_context (Some "crrrrash") (fun () -> eventually_crash n)
40+
2041
let protek f =
21-
try%lwt f () with Exit -> exit 1
42+
try%lwt
43+
Lwt.with_value Lwt.tracing_context (Some "protekted") f
44+
with Exit -> exit 1
2245

2346
let () = Lwt_main.run begin
2447
let%lwt () = Lwt.pause () in
25-
Lwt.pick [ping (); protek (fun () -> eventually_crash 20)]
48+
Lwt.pick [
49+
(Lwt.with_value Lwt.tracing_context (Some "pingpong") ping);
50+
(Lwt.with_value Lwt.tracing_context (Some "fib") fibobo);
51+
protek (fun () -> eventually_crash 20)
52+
]
2653
end

0 commit comments

Comments
 (0)