bool HeapSnapshot::init(JSContext* cx, const uint8_t* buffer, uint32_t size) { if (!nodes.init() || !frames.init()) return false; ArrayInputStream stream(buffer, size); GzipInputStream gzipStream(&stream); // First is the metadata. protobuf::Metadata metadata; if (!parseMessage(gzipStream, metadata)) return false; if (metadata.has_timestamp()) timestamp.emplace(metadata.timestamp()); // Next is the root node. protobuf::Node root; if (!parseMessage(gzipStream, root)) return false; // Although the id is optional in the protobuf format for future proofing, we // can't currently do anything without it. if (NS_WARN_IF(!root.has_id())) return false; rootId = root.id(); // The set of all node ids we've found edges pointing to. NodeIdSet edgeReferents(cx); if (NS_WARN_IF(!edgeReferents.init())) return false; if (NS_WARN_IF(!saveNode(root, edgeReferents))) return false; // Finally, the rest of the nodes in the core dump. while (StreamHasData(gzipStream)) { protobuf::Node node; if (!parseMessage(gzipStream, node)) return false; if (NS_WARN_IF(!saveNode(node, edgeReferents))) return false; } // Check the set of node ids referred to by edges we found and ensure that we // have the node corresponding to each id. If we don't have all of them, it is // unsafe to perform analyses of this heap snapshot. for (auto range = edgeReferents.all(); !range.empty(); range.popFront()) { if (NS_WARN_IF(!nodes.has(range.front()))) return false; } return true; }
bool HeapSnapshot::init(const uint8_t* buffer, uint32_t size) { if (!nodes.init() || !frames.init() || !strings.init()) return false; ArrayInputStream stream(buffer, size); GzipInputStream gzipStream(&stream); // First is the metadata. protobuf::Metadata metadata; if (!parseMessage(gzipStream, metadata)) return false; if (metadata.has_timestamp()) timestamp.emplace(metadata.timestamp()); // Next is the root node. protobuf::Node root; if (!parseMessage(gzipStream, root)) return false; // Although the id is optional in the protobuf format for future proofing, we // can't currently do anything without it. if (NS_WARN_IF(!root.has_id())) return false; rootId = root.id(); if (NS_WARN_IF(!saveNode(root))) return false; // Finally, the rest of the nodes in the core dump. while (StreamHasData(gzipStream)) { protobuf::Node node; if (!parseMessage(gzipStream, node)) return false; if (NS_WARN_IF(!saveNode(node))) return false; } return true; }