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