changeset 174:47922c6927e1

Bug 3104: SEGV in TSnapShotContainer::mergeChildren with Oracle JDK8u92 Reviewed-by: ykubota https://github.com/HeapStats/heapstats/issues/31
author Yasumasa Suenaga <yasuenag@gmail.com>
date Sun, 31 Jul 2016 22:58:05 +0900
parents b92aa059996a
children 14c704c52409
files ChangeLog agent/src/heapstats-engines/snapShotContainer.cpp
diffstat 2 files changed, 36 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Fri Jul 01 21:59:42 2016 +0900
+++ b/ChangeLog	Sun Jul 31 22:58:05 2016 +0900
@@ -1,4 +1,8 @@
-2016-07-01  Yasumasa Suenaga <kubota.yuji@lab.ntt.co.jp>
+2016-07-31  Yasumasa Suenaga <yasuenag@gmail.com>
+
+	* Bug 3104: SEGV in TSnapShotContainer::mergeChildren with Oracle JDK8u92
+
+2016-07-01  Yasumasa Suenaga <yasuenag@gmail.com>
 
 	* Bug 3057: [JDK 9] HeapStats Analyzer could not start on JDK 9
 
--- a/agent/src/heapstats-engines/snapShotContainer.cpp	Fri Jul 01 21:59:42 2016 +0900
+++ b/agent/src/heapstats-engines/snapShotContainer.cpp	Sun Jul 31 22:58:05 2016 +0900
@@ -468,20 +468,40 @@
 
         /* Loop each children class. */
         TChildClassCounter *counter = srcClsCounter->child;
+        TChildClassCounter *prevCounter = NULL;
         while (counter != NULL) {
-          /* Search child class. */
-          TChildClassCounter *childClsData =
-              this->findChildClass(clsCounter, counter->objData->klassOop);
+          TObjectData *objData = counter->objData;
+
+          /*
+           * If the class of objData is already unloaded, we should remove
+           * reference to it from child object data.
+           */
+          if (objData->isRemoved) {
+            if (prevCounter == NULL) {
+              srcClsCounter->child = counter->next;
+            } else {
+              prevCounter->next = counter->next;
+            }
 
-          /* Register class as child class. */
-          if (unlikely(childClsData == NULL)) {
-            childClsData =
-                this->pushNewChildClass(clsCounter, counter->objData);
-          }
+            /* Deallocate TChildClassCounter. */
+            free(counter->counter);
+            free(counter);
+          } else {
+            /* Search child class. */
+            TChildClassCounter *childClsData =
+                      this->findChildClass(clsCounter, objData->klassOop);
 
-          if (likely(childClsData != NULL)) {
-            /* Marge children class heap usage. */
-            this->addInc(childClsData->counter, counter->counter);
+            /* Register class as child class. */
+            if (unlikely(childClsData == NULL)) {
+              childClsData = this->pushNewChildClass(clsCounter, objData);
+            }
+
+            if (likely(childClsData != NULL)) {
+              /* Marge children class heap usage. */
+              this->addInc(childClsData->counter, counter->counter);
+            }
+
+            prevCounter = counter;
           }
 
           counter = counter->next;