Warn the user if data for a certain GC is incomplete
authorAndrey Kvochko <a.kvochko@samsung.com>
Mon, 25 Sep 2017 19:01:15 +0000 (22:01 +0300)
committerAndrey Kvochko/SRR-Compiler Lab/./삼성전자 <a.kvochko@samsung.com>
Fri, 27 Oct 2017 10:46:13 +0000 (13:46 +0300)
src/analyze/gui/parser.cpp
src/track/objectgraph.h

index 107ec10..3e8e194 100644 (file)
@@ -22,6 +22,8 @@
 #include <ThreadWeaver/ThreadWeaver>
 
 #include <QDebug>
+#include <QMessageBox>
+#include <QString>
 
 #include "analyze/accumulatedtracedata.h"
 
@@ -730,8 +732,12 @@ ObjectRowData objectRowDataFromTypeTree(ParserData& data, TypeTree* tree) {
     return rowData;
 }
 
-ObjectNode buildObjectGraph(ParserData& data, size_t &nodeIndex) {
+ObjectNode buildObjectGraph(ParserData& data, size_t &nodeIndex, bool &success) {
     ObjectNode node;
+    if (nodeIndex >= data.objectTreeNodes.size()) {
+        success = false;
+        return node;
+    }
     ObjectTreeNode &dataNode = data.objectTreeNodes[nodeIndex];
     node.m_classIndex = dataNode.classIndex;
     node.m_objectPtr = dataNode.objectPtr;
@@ -742,9 +748,11 @@ ObjectNode buildObjectGraph(ParserData& data, size_t &nodeIndex) {
         node.m_objectSize = 0;
     nodeIndex++;
     for (size_t i = 0; i < dataNode.numChildren; ++i) {
-        if (node.gcNum != data.objectTreeNodes[nodeIndex].gcNum)
+        if (node.gcNum != data.objectTreeNodes[nodeIndex].gcNum) {
+            success = false;
             break;
-        node.m_children.push_back(buildObjectGraph(data, nodeIndex));
+        }
+        node.m_children.push_back(buildObjectGraph(data, nodeIndex, success));
     }
     return node;
 }
@@ -756,7 +764,14 @@ ObjectTreeData buildObjectTree(ParserData& data)
     size_t nodeIndex = 0;
     std::vector<ObjectNode> nodes;
     while (nodeIndex < data.objectTreeNodes.size()) {
-        nodes.push_back(buildObjectGraph(data, nodeIndex));
+        bool success = true;
+        ObjectNode node = buildObjectGraph(data, nodeIndex, success);
+        if (success)
+            nodes.push_back(node);
+        else {
+            QMessageBox::warning(nullptr, QString::fromStdString("Bad data"),
+                                 QString::fromStdString("Heap snapshot for GC #%1 is incomplete").arg(node.gcNum));
+        }
     }
 
     for (auto& node: nodes) {
index 4ddabd0..ba8e2a7 100644 (file)
@@ -78,6 +78,12 @@ public:
         m_graph.clear();
     }
 
+    /* m_graph is in fact a flat collection of ObjectNodes. The graph structure
+       is provided by ObjectNode::children which point to ObjectNode instances
+       living inside m_graph. All instances of ObjectNode are residing
+       in m_graph, regardless of their position in the actual graph.
+       NULL key is somewhat special - the ObjectNode corresponding to it is a fake
+       ObjectNode whose children are GC roots. */
     static std::unordered_map<void*, ObjectNode> m_graph;
 };