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}