blob: 24a223e11c3d5cffbf0007d0b62b284b834b2443 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
/* -*- Mode: protobuf; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// # Core Dumps
//
// A core dump is a serialized snapshot of the heap graph. We serialize the heap
// as a series of protobuf messages with each message prefixed by its Varint32
// byte size so we can delimit individual protobuf messages (protobuf parsers
// cannot determine where a message ends on their own).
//
// The first protobuf message is an instance of the `Metadata` message. All
// subsequent messages will be instances of the `Node` message. The first of
// these `Node` messages is the root node of the serialized heap graph. Here is
// a diagram of our core dump format:
//
// +-----------------------------------------------------------------------+
// | Varint32: The size of following `Metadata` message. |
// +-----------------------------------------------------------------------+
// | message: The core dump `Metadata` message. |
// +-----------------------------------------------------------------------+
// | Varint32: The size of the following `Node` message. |
// +-----------------------------------------------------------------------+
// | message: The first `Node` message. This is the root node. |
// +-----------------------------------------------------------------------+
// | Varint32: The size of the following `Node` message. |
// +-----------------------------------------------------------------------+
// | message: A `Node` message. |
// +-----------------------------------------------------------------------+
// | Varint32: The size of the following `Node` message. |
// +-----------------------------------------------------------------------+
// | message: A `Node` message. |
// +-----------------------------------------------------------------------+
// | . |
// | . |
// | . |
// +-----------------------------------------------------------------------+
//
// Core dumps should always be written with a
// `google::protobuf::io::GzipOutputStream` and read from a
// `google::protobuf::io::GzipInputStream`.
//
// Note that all strings are de-duplicated. The first time the N^th unique
// string is encountered, the full string is serialized. Subsequent times that
// same string is encountered, it is referenced by N. This de-duplication
// happens across string properties, not on a per-property basis. For example,
// if the same K^th unique string is first used as an Edge::EdgeNameOrRef and
// then as a StackFrame::Data::FunctionDisplayNameOrRef, the first will be the
// actual string as the functionDisplayName oneof property, and the second will
// be a reference to the first as the edgeNameRef oneof property whose value is
// K.
//
// We would ordinarily abstract these de-duplicated strings with messages of
// their own, but unfortunately, the protobuf compiler does not have a way to
// inline a messsage within another message and the child message must be
// referenced by pointer. This leads to extra mallocs that we wish to avoid.
package mozilla.devtools.protobuf;
// A collection of metadata about this core dump.
message Metadata {
// Number of microseconds since midnight (00:00:00) 1 January 1970 UTC.
optional uint64 timeStamp = 1;
}
// A serialized version of `JS::ubi::StackFrame`. Older parent frame tails are
// de-duplicated to cut down on [de]serialization and size costs.
message StackFrame {
oneof StackFrameType {
// This is the first time this stack frame has been serialized, and so
// here is all of its data.
Data data = 1;
// A reference to a stack frame that has already been serialized and has
// the given number as its id.
uint64 ref = 2;
}
message Data {
optional uint64 id = 1;
optional StackFrame parent = 2;
optional uint32 line = 3;
optional uint32 column = 4;
// De-duplicated two-byte string.
oneof SourceOrRef {
bytes source = 5;
uint64 sourceRef = 6;
}
// De-duplicated two-byte string.
oneof FunctionDisplayNameOrRef {
bytes functionDisplayName = 7;
uint64 functionDisplayNameRef = 8;
}
optional bool isSystem = 9;
optional bool isSelfHosted = 10;
}
}
// A serialized version of `JS::ubi::Node` and its outgoing edges.
message Node {
optional uint64 id = 1;
// De-duplicated two-byte string.
oneof TypeNameOrRef {
bytes typeName = 2;
uint64 typeNameRef = 3;
}
optional uint64 size = 4;
repeated Edge edges = 5;
optional StackFrame allocationStack = 6;
// De-duplicated one-byte string.
oneof JSObjectClassNameOrRef {
bytes jsObjectClassName = 7;
uint64 jsObjectClassNameRef = 8;
}
// JS::ubi::CoarseType. Defaults to Other.
optional uint32 coarseType = 9 [default = 0];
// De-duplicated one-byte string.
oneof ScriptFilenameOrRef {
bytes scriptFilename = 10;
uint64 scriptFilenameRef = 11;
}
}
// A serialized edge from the heap graph.
message Edge {
optional uint64 referent = 1;
// De-duplicated two-byte string.
oneof EdgeNameOrRef {
bytes name = 2;
uint64 nameRef = 3;
}
}
|