Skip to content

Commit 9058410

Browse files
committed
update prost 0.11
Signed-off-by: Yilin Chen <[email protected]>
1 parent a280c9e commit 9058410

File tree

5 files changed

+290
-6
lines changed

5 files changed

+290
-6
lines changed

.github/workflows/rust.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ jobs:
3535
command: clippy
3636
args: --all-targets --features flamegraph,prost-codec -- -D warnings
3737

38+
- name: Check the SHA256 sum in the prost file
39+
run: head -n1 proto/perftools.profiles.rs | sed 's/^\/\/ \(.*\)$/\1/' | sha256sum --check -
40+
41+
- name: Check if the generated prost file is up-to-date
42+
run: git diff --no-ext-diff --exit-code
43+
3844
- name: Run cargo clippy protobuf
3945
uses: actions-rs/[email protected]
4046
with:

Cargo.toml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ frame-pointer = []
1717

1818
# A private feature to indicate either prost-codec or protobuf-codec is enabled.
1919
_protobuf = []
20-
prost-codec = ["prost", "prost-derive", "prost-build", "_protobuf"]
20+
prost-codec = ["prost", "prost-derive", "prost-build", "sha2", "_protobuf"]
2121
protobuf-codec = ["protobuf", "protobuf-codegen-pure", "_protobuf"]
2222

2323
[dependencies]
@@ -34,8 +34,8 @@ cfg-if = "1.0"
3434
smallvec = "1.7"
3535

3636
inferno = { version = "0.11", default-features = false, features = ["nameattr"], optional = true }
37-
prost = { version = "0.10", optional = true }
38-
prost-derive = { version = "0.10", optional = true }
37+
prost = { version = "0.11", optional = true }
38+
prost-derive = { version = "0.11", optional = true }
3939
protobuf = { version = "2.0", optional = true }
4040
criterion = {version = "0.4", optional = true}
4141

@@ -49,7 +49,8 @@ criterion = "0.4"
4949
rand = "0.8.0"
5050

5151
[build-dependencies]
52-
prost-build = { version = "0.10", optional = true }
52+
prost-build = { version = "0.11", optional = true }
53+
sha2 = { version = "0.10", optional = true }
5354
protobuf-codegen-pure = { version = "2.0", optional = true }
5455

5556
[[example]]

build.rs

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,47 @@ fn generate_protobuf() {
2222
write!(f, "pub mod profile;").unwrap();
2323
}
2424

25+
#[cfg(feature = "prost-codec")]
26+
fn generate_prost() {
27+
use sha2::{Digest, Sha256};
28+
use std::{
29+
fmt::Write,
30+
fs::{self, File},
31+
io::{self, BufRead, BufReader},
32+
};
33+
34+
const PRE_GENERATED_PATH: &str = "proto/perftools.profiles.rs";
35+
36+
// Calculate the SHA256 of the proto file
37+
let mut hasher = Sha256::new();
38+
let mut proto_file = BufReader::new(File::open("proto/profile.proto").unwrap());
39+
io::copy(&mut proto_file, &mut hasher).unwrap();
40+
let mut hex = String::new();
41+
for b in hasher.finalize() {
42+
write!(&mut hex, "{:x}", b).unwrap();
43+
}
44+
let hash_comment = format!("// {} proto/profile.proto", hex);
45+
46+
let mut pre_generated = BufReader::new(File::open(PRE_GENERATED_PATH).unwrap());
47+
let mut first_line = String::new();
48+
pre_generated.read_line(&mut first_line).unwrap();
49+
// If the hash of the proto file changes, regenerate the prost file.
50+
if first_line.trim() != hash_comment {
51+
drop(pre_generated);
52+
prost_build::Config::new()
53+
.out_dir("proto/")
54+
.compile_protos(&["proto/profile.proto"], &["proto/"])
55+
.unwrap();
56+
// Prepend the hash comment to the generated file.
57+
let generated = fs::read_to_string(PRE_GENERATED_PATH).unwrap();
58+
let with_hex = format!("{}\n\n{}", hash_comment, generated);
59+
fs::write(PRE_GENERATED_PATH, with_hex).unwrap();
60+
}
61+
}
62+
2563
fn main() {
2664
#[cfg(feature = "prost-codec")]
27-
prost_build::compile_protos(&["proto/profile.proto"], &["proto/"]).unwrap();
65+
generate_prost();
2866
#[cfg(feature = "protobuf-codec")]
2967
generate_protobuf();
3068
}

proto/perftools.profiles.rs

Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
// f9f855b960d01b292a3c2642e263e6156d52631e78e0177fe51416ed5bbecc81 proto/profile.proto
2+
3+
#[derive(Clone, PartialEq, ::prost::Message)]
4+
pub struct Profile {
5+
/// A description of the samples associated with each Sample.value.
6+
/// For a cpu profile this might be:
7+
/// \[["cpu","nanoseconds"]\] or \[["wall","seconds"]\] or \[["syscall","count"]\]
8+
/// For a heap profile, this might be:
9+
/// \[["allocations","count"\], \["space","bytes"]\],
10+
/// If one of the values represents the number of events represented
11+
/// by the sample, by convention it should be at index 0 and use
12+
/// sample_type.unit == "count".
13+
#[prost(message, repeated, tag="1")]
14+
pub sample_type: ::prost::alloc::vec::Vec<ValueType>,
15+
/// The set of samples recorded in this profile.
16+
#[prost(message, repeated, tag="2")]
17+
pub sample: ::prost::alloc::vec::Vec<Sample>,
18+
/// Mapping from address ranges to the image/binary/library mapped
19+
/// into that address range. mapping\[0\] will be the main binary.
20+
#[prost(message, repeated, tag="3")]
21+
pub mapping: ::prost::alloc::vec::Vec<Mapping>,
22+
/// Useful program location
23+
#[prost(message, repeated, tag="4")]
24+
pub location: ::prost::alloc::vec::Vec<Location>,
25+
/// Functions referenced by locations
26+
#[prost(message, repeated, tag="5")]
27+
pub function: ::prost::alloc::vec::Vec<Function>,
28+
/// A common table for strings referenced by various messages.
29+
/// string_table\[0\] must always be "".
30+
#[prost(string, repeated, tag="6")]
31+
pub string_table: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
32+
/// frames with Function.function_name fully matching the following
33+
/// regexp will be dropped from the samples, along with their successors.
34+
///
35+
/// Index into string table.
36+
#[prost(int64, tag="7")]
37+
pub drop_frames: i64,
38+
/// frames with Function.function_name fully matching the following
39+
/// regexp will be kept, even if it matches drop_functions.
40+
///
41+
/// Index into string table.
42+
#[prost(int64, tag="8")]
43+
pub keep_frames: i64,
44+
// The following fields are informational, do not affect
45+
// interpretation of results.
46+
47+
/// Time of collection (UTC) represented as nanoseconds past the epoch.
48+
#[prost(int64, tag="9")]
49+
pub time_nanos: i64,
50+
/// Duration of the profile, if a duration makes sense.
51+
#[prost(int64, tag="10")]
52+
pub duration_nanos: i64,
53+
/// The kind of events between sampled ocurrences.
54+
/// e.g [ "cpu","cycles" ] or [ "heap","bytes" ]
55+
#[prost(message, optional, tag="11")]
56+
pub period_type: ::core::option::Option<ValueType>,
57+
/// The number of events between sampled occurrences.
58+
#[prost(int64, tag="12")]
59+
pub period: i64,
60+
/// Freeform text associated to the profile.
61+
///
62+
/// Indices into string table.
63+
#[prost(int64, repeated, tag="13")]
64+
pub comment: ::prost::alloc::vec::Vec<i64>,
65+
/// Index into the string table of the type of the preferred sample
66+
/// value. If unset, clients should default to the last sample value.
67+
#[prost(int64, tag="14")]
68+
pub default_sample_type: i64,
69+
}
70+
/// ValueType describes the semantics and measurement units of a value.
71+
#[derive(Clone, PartialEq, ::prost::Message)]
72+
pub struct ValueType {
73+
/// Rename it from type to ty to avoid using keyword in Rust.
74+
///
75+
/// Index into string table.
76+
#[prost(int64, tag="1")]
77+
pub ty: i64,
78+
/// Index into string table.
79+
#[prost(int64, tag="2")]
80+
pub unit: i64,
81+
}
82+
/// Each Sample records values encountered in some program
83+
/// context. The program context is typically a stack trace, perhaps
84+
/// augmented with auxiliary information like the thread-id, some
85+
/// indicator of a higher level request being handled etc.
86+
#[derive(Clone, PartialEq, ::prost::Message)]
87+
pub struct Sample {
88+
/// The ids recorded here correspond to a Profile.location.id.
89+
/// The leaf is at location_id\[0\].
90+
#[prost(uint64, repeated, tag="1")]
91+
pub location_id: ::prost::alloc::vec::Vec<u64>,
92+
/// The type and unit of each value is defined by the corresponding
93+
/// entry in Profile.sample_type. All samples must have the same
94+
/// number of values, the same as the length of Profile.sample_type.
95+
/// When aggregating multiple samples into a single sample, the
96+
/// result has a list of values that is the elemntwise sum of the
97+
/// lists of the originals.
98+
#[prost(int64, repeated, tag="2")]
99+
pub value: ::prost::alloc::vec::Vec<i64>,
100+
/// label includes additional context for this sample. It can include
101+
/// things like a thread id, allocation size, etc
102+
#[prost(message, repeated, tag="3")]
103+
pub label: ::prost::alloc::vec::Vec<Label>,
104+
}
105+
#[derive(Clone, PartialEq, ::prost::Message)]
106+
pub struct Label {
107+
/// Index into string table
108+
#[prost(int64, tag="1")]
109+
pub key: i64,
110+
/// At most one of the following must be present
111+
///
112+
/// Index into string table
113+
#[prost(int64, tag="2")]
114+
pub str: i64,
115+
#[prost(int64, tag="3")]
116+
pub num: i64,
117+
/// Should only be present when num is present.
118+
/// Specifies the units of num.
119+
/// Use arbitrary string (for example, "requests") as a custom count unit.
120+
/// If no unit is specified, consumer may apply heuristic to deduce the unit.
121+
/// Consumers may also interpret units like "bytes" and "kilobytes" as memory
122+
/// units and units like "seconds" and "nanoseconds" as time units,
123+
/// and apply appropriate unit conversions to these.
124+
///
125+
/// Index into string table
126+
#[prost(int64, tag="4")]
127+
pub num_unit: i64,
128+
}
129+
#[derive(Clone, PartialEq, ::prost::Message)]
130+
pub struct Mapping {
131+
/// Unique nonzero id for the mapping.
132+
#[prost(uint64, tag="1")]
133+
pub id: u64,
134+
/// Address at which the binary (or DLL) is loaded into memory.
135+
#[prost(uint64, tag="2")]
136+
pub memory_start: u64,
137+
/// The limit of the address range occupied by this mapping.
138+
#[prost(uint64, tag="3")]
139+
pub memory_limit: u64,
140+
/// Offset in the binary that corresponds to the first mapped address.
141+
#[prost(uint64, tag="4")]
142+
pub file_offset: u64,
143+
/// The object this entry is loaded from. This can be a filename on
144+
/// disk for the main binary and shared libraries, or virtual
145+
/// abstractions like "\[vdso\]".
146+
///
147+
/// Index into string table
148+
#[prost(int64, tag="5")]
149+
pub filename: i64,
150+
/// A string that uniquely identifies a particular program version
151+
/// with high probability. E.g., for binaries generated by GNU tools,
152+
/// it could be the contents of the .note.gnu.build-id field.
153+
///
154+
/// Index into string table
155+
#[prost(int64, tag="6")]
156+
pub build_id: i64,
157+
/// The following fields indicate the resolution of symbolic info.
158+
#[prost(bool, tag="7")]
159+
pub has_functions: bool,
160+
#[prost(bool, tag="8")]
161+
pub has_filenames: bool,
162+
#[prost(bool, tag="9")]
163+
pub has_line_numbers: bool,
164+
#[prost(bool, tag="10")]
165+
pub has_inline_frames: bool,
166+
}
167+
/// Describes function and line table debug information.
168+
#[derive(Clone, PartialEq, ::prost::Message)]
169+
pub struct Location {
170+
/// Unique nonzero id for the location. A profile could use
171+
/// instruction addresses or any integer sequence as ids.
172+
#[prost(uint64, tag="1")]
173+
pub id: u64,
174+
/// The id of the corresponding profile.Mapping for this location.
175+
/// It can be unset if the mapping is unknown or not applicable for
176+
/// this profile type.
177+
#[prost(uint64, tag="2")]
178+
pub mapping_id: u64,
179+
/// The instruction address for this location, if available. It
180+
/// should be within \[Mapping.memory_start...Mapping.memory_limit\]
181+
/// for the corresponding mapping. A non-leaf address may be in the
182+
/// middle of a call instruction. It is up to display tools to find
183+
/// the beginning of the instruction if necessary.
184+
#[prost(uint64, tag="3")]
185+
pub address: u64,
186+
/// Multiple line indicates this location has inlined functions,
187+
/// where the last entry represents the caller into which the
188+
/// preceding entries were inlined.
189+
///
190+
/// E.g., if memcpy() is inlined into printf:
191+
/// line\[0\].function_name == "memcpy"
192+
/// line\[1\].function_name == "printf"
193+
#[prost(message, repeated, tag="4")]
194+
pub line: ::prost::alloc::vec::Vec<Line>,
195+
/// Provides an indication that multiple symbols map to this location's
196+
/// address, for example due to identical code folding by the linker. In that
197+
/// case the line information above represents one of the multiple
198+
/// symbols. This field must be recomputed when the symbolization state of the
199+
/// profile changes.
200+
#[prost(bool, tag="5")]
201+
pub is_folded: bool,
202+
}
203+
#[derive(Clone, PartialEq, ::prost::Message)]
204+
pub struct Line {
205+
/// The id of the corresponding profile.Function for this line.
206+
#[prost(uint64, tag="1")]
207+
pub function_id: u64,
208+
/// Line number in source code.
209+
#[prost(int64, tag="2")]
210+
pub line: i64,
211+
}
212+
#[derive(Clone, PartialEq, ::prost::Message)]
213+
pub struct Function {
214+
/// Unique nonzero id for the function.
215+
#[prost(uint64, tag="1")]
216+
pub id: u64,
217+
/// Name of the function, in human-readable form if available.
218+
///
219+
/// Index into string table
220+
#[prost(int64, tag="2")]
221+
pub name: i64,
222+
/// Name of the function, as identified by the system.
223+
/// For instance, it can be a C++ mangled name.
224+
///
225+
/// Index into string table
226+
#[prost(int64, tag="3")]
227+
pub system_name: i64,
228+
/// Source file containing the function.
229+
///
230+
/// Index into string table
231+
#[prost(int64, tag="4")]
232+
pub filename: i64,
233+
/// Line number in source file.
234+
#[prost(int64, tag="5")]
235+
pub start_line: i64,
236+
}

src/lib.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,10 @@ pub use inferno::flamegraph;
7070
pub mod protos {
7171
pub use prost::Message;
7272

73-
include!(concat!(env!("OUT_DIR"), "/perftools.profiles.rs"));
73+
include!(concat!(
74+
env!("CARGO_MANIFEST_DIR"),
75+
"/proto/perftools.profiles.rs"
76+
));
7477
}
7578

7679
#[cfg(feature = "protobuf-codec")]

0 commit comments

Comments
 (0)