Skip to main content

stackwise_core/
report.rs

1use schemars::JsonSchema;
2use serde::{Deserialize, Serialize};
3
4pub const SCHEMA_VERSION: &str = "0.1.0";
5
6#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
7pub struct StackwiseReport {
8    pub schema_version: String,
9    pub generator: GeneratorInfo,
10    pub artifact: ArtifactInfo,
11    pub build: Option<BuildInfo>,
12    pub summary: Summary,
13    pub symbols: Vec<SymbolReport>,
14    pub edges: Vec<EdgeReport>,
15    pub groups: Vec<GroupReport>,
16    pub diagnostics: Vec<Diagnostic>,
17}
18
19#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
20pub struct GeneratorInfo {
21    pub name: String,
22    pub version: String,
23}
24
25#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
26pub struct ArtifactInfo {
27    pub path: String,
28    pub file_name: String,
29    pub format: ObjectFormat,
30    pub architecture: String,
31    pub pointer_width: Option<u8>,
32    pub size_bytes: u64,
33}
34
35#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
36pub struct BuildInfo {
37    pub workspace_root: Option<String>,
38    pub package: Option<String>,
39    pub profile: Option<String>,
40    pub target: Option<String>,
41    pub features: Vec<String>,
42    pub exact_mode: ExactMode,
43}
44
45#[derive(Debug, Clone, Copy, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
46#[serde(rename_all = "snake_case")]
47pub enum ExactMode {
48    Off,
49    Auto,
50    Required,
51}
52
53#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
54pub struct Summary {
55    pub symbol_count: usize,
56    pub edge_count: usize,
57    pub known_frame_count: usize,
58    pub unknown_frame_count: usize,
59    pub recursive_symbol_count: usize,
60    pub indirect_edge_count: usize,
61    pub max_own_frame: Option<SymbolMetric>,
62    pub max_worst_path: Option<SymbolMetric>,
63    pub confidence: Confidence,
64}
65
66#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
67pub struct SymbolMetric {
68    pub symbol_id: u32,
69    pub bytes: u64,
70    pub demangled: String,
71}
72
73#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
74pub struct SymbolReport {
75    pub id: u32,
76    pub name: String,
77    pub demangled: String,
78    pub crate_name: Option<String>,
79    pub module_path: Vec<String>,
80    pub address: u64,
81    pub size_bytes: Option<u64>,
82    pub source_location: Option<SourceLocation>,
83    pub object_format: ObjectFormat,
84    pub own_frame: FrameInfo,
85    pub worst_path: WorstPathInfo,
86    pub confidence: Confidence,
87    pub evidence: Vec<Evidence>,
88    pub unresolved_reasons: Vec<UnresolvedReason>,
89}
90
91#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
92pub struct FrameInfo {
93    pub bytes: Option<u64>,
94    pub status: FrameStatus,
95    pub evidence_source: EvidenceSource,
96}
97
98#[derive(Debug, Clone, Copy, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
99#[serde(rename_all = "snake_case")]
100pub enum FrameStatus {
101    Known,
102    Unknown,
103    Dynamic,
104}
105
106#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
107pub struct WorstPathInfo {
108    pub bytes: Option<u64>,
109    pub status: UpperBoundStatus,
110    pub path: Vec<u32>,
111}
112
113#[derive(Debug, Clone, Copy, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
114#[serde(rename_all = "snake_case")]
115pub enum UpperBoundStatus {
116    Known,
117    Unknown,
118    Recursive,
119    Dynamic,
120    Indirect,
121}
122
123#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
124pub struct Evidence {
125    pub source: EvidenceSource,
126    pub confidence: Confidence,
127    pub note: String,
128}
129
130#[derive(Debug, Clone, Copy, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
131#[serde(rename_all = "snake_case")]
132pub enum EvidenceSource {
133    ElfStackSizes,
134    PeUnwind,
135    MachOUnwind,
136    PrologueDisassembly,
137    SymbolOnly,
138    Unknown,
139}
140
141#[derive(
142    Debug, Clone, Copy, Serialize, Deserialize, JsonSchema, PartialEq, Eq, PartialOrd, Ord,
143)]
144#[serde(rename_all = "snake_case")]
145pub enum Confidence {
146    Exact,
147    High,
148    Medium,
149    Low,
150    Unknown,
151}
152
153#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
154pub struct EdgeReport {
155    pub caller: u32,
156    pub callee: Option<u32>,
157    pub target_address: Option<u64>,
158    pub kind: EdgeKind,
159    pub confidence: Confidence,
160}
161
162#[derive(
163    Debug, Clone, Copy, Serialize, Deserialize, JsonSchema, PartialEq, Eq, PartialOrd, Ord,
164)]
165#[serde(rename_all = "snake_case")]
166pub enum EdgeKind {
167    DirectCall,
168    TailCall,
169    IndirectCall,
170    ExternalCall,
171}
172
173#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
174pub struct GroupReport {
175    pub id: u32,
176    pub name: String,
177    pub parent: Option<u32>,
178    pub symbol_ids: Vec<u32>,
179    pub own_frame_sum: Option<u64>,
180    pub worst_path_max: Option<u64>,
181}
182
183#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
184pub struct SourceLocation {
185    pub file: String,
186    pub line: Option<u32>,
187    pub column: Option<u32>,
188}
189
190#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
191pub struct Diagnostic {
192    pub level: DiagnosticLevel,
193    pub code: String,
194    pub message: String,
195}
196
197#[derive(Debug, Clone, Copy, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
198#[serde(rename_all = "snake_case")]
199pub enum DiagnosticLevel {
200    Info,
201    Warning,
202    Error,
203}
204
205#[derive(Debug, Clone, Copy, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
206#[serde(rename_all = "snake_case")]
207pub enum ObjectFormat {
208    Elf,
209    PeCoff,
210    MachO,
211    Wasm,
212    Unknown,
213}
214
215#[derive(Debug, Clone, Copy, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
216#[serde(rename_all = "snake_case")]
217pub enum UnresolvedReason {
218    MissingStackEvidence,
219    DynamicStackAllocation,
220    RecursiveCycle,
221    IndirectCall,
222    ExternalCall,
223    UnsupportedObjectFormat,
224    StrippedSymbols,
225}