functiontrace_server/function_trace.rs
1use serde::Deserialize;
2use std::borrow::Cow;
3use std::num::NonZeroU32;
4use std::time::Duration;
5
6/// A representation of the various trace messages a client thread can send us during normal
7/// tracing operation.
8///
9/// We use [`Cow`] instead of [`String`] because most strings should be zero-copy deserializable.
10#[derive(Deserialize, Debug)]
11#[serde(tag = "type")]
12pub enum FunctionTrace<'event> {
13 /// A request to register this as a new thread.
14 ///
15 /// **NOTE**: This must be sent as the first message from a new thread, and may not be sent
16 /// twice by any thread.
17 RegisterThread(ThreadRegistration),
18 Call {
19 time: Duration,
20 #[serde(borrow)]
21 func_name: Cow<'event, str>,
22 #[serde(borrow)]
23 filename: Cow<'event, str>,
24 /// This _should_ be a [`NonZeroU32`], but sometimes Python passes us things that seem like
25 /// they should be `NativeCall`s instead. It's easier to be liberal here and to handle
26 /// this later.
27 linenumber: u32,
28 },
29 Return {
30 time: Duration,
31 #[serde(borrow)]
32 func_name: Cow<'event, str>,
33 },
34 NativeCall {
35 time: Duration,
36 #[serde(borrow)]
37 func_name: Cow<'event, str>,
38 #[serde(borrow)]
39 module_name: Cow<'event, str>,
40 },
41 NativeReturn {
42 time: Duration,
43 #[serde(borrow)]
44 func_name: Cow<'event, str>,
45 },
46 Exception {
47 time: Duration,
48 #[serde(borrow)]
49 exception_type: Cow<'event, str>,
50 #[serde(borrow)]
51 exception_value: Cow<'event, str>,
52 filename: String,
53 linenumber: NonZeroU32,
54 },
55 Log {
56 time: Duration,
57 #[serde(borrow)]
58 log_type: Cow<'event, str>,
59 #[serde(borrow)]
60 log_value: Cow<'event, str>,
61 },
62 Import {
63 time: Duration,
64 #[serde(borrow)]
65 module_name: Cow<'event, str>,
66 },
67 Allocation {
68 time: Duration,
69 details: AllocationDetails,
70 },
71}
72
73/// Information about allocations.
74#[derive(Deserialize, Debug)]
75#[serde(tag = "type")]
76pub enum AllocationDetails {
77 /// The amount and location of a new allocation
78 Alloc { bytes: usize, addr: usize },
79 /// The new size of a reallocation from `old_addr` to `new_addr`.
80 Realloc {
81 bytes: usize,
82 old_addr: usize,
83 new_addr: usize,
84 },
85 /// The address that was `free()`ed.
86 Free { old_addr: usize },
87}
88
89/// Information relevant for initializing a trace.
90#[derive(Deserialize, Debug)]
91pub struct TraceInitialization {
92 /// The name (typically based off of argv) of the program initializing the trace (ex:
93 /// `hello.py world`).
94 pub program_name: String,
95 /// The version information of the `functiontrace` client talking to this server (ex:
96 /// `py-functiontrace 0.3.0`).
97 pub program_version: String,
98 /// The version for the underlying language the program is running on (ex: `Python 3.7.1`).
99 pub lang_version: String,
100 /// The general operating system platform the program is running on (ex: `darwin`).
101 pub platform: String,
102 /// An opaque system time that all other client-sent times will be relative to.
103 pub time: Duration,
104}
105
106/// This message contains information for registering threads (including a program's main thread).
107#[derive(Deserialize, Debug)]
108pub struct ThreadRegistration {
109 /// A system time for when this thread registered itself as being traced with FunctionTrace.
110 pub time: Duration,
111 /// The program name this thread corresponds to.
112 pub program_name: String,
113 /// The process this thread belongs to.
114 pub pid: usize,
115}