[Uml-devel] KDE/kdesdk/umbrello

Oliver Kellogg okellogg at users.sourceforge.net
Sun Feb 26 20:11:55 UTC 2012


SVN commit 1282402 by okellogg:

(In reply to comment #1)
> [...]
> you have an inheritance in the opposite direction.
> The mutual inheritance throws Umbrello off the handle and so I've removed
> the first one. (Actually I wonder why Umbrello did not disallow its
> creation.)

It turns out that
  AssocRules::allowAssociation(Uml::AssociationType,
                               UMLWidget *, UMLWidget *)
was being called twice: First in ToolBarStateAssociation::setSecondWidget()
(toolbarstateassociation.cpp:226) and again via ToolBarStateAssociation::
addAssociationInViewAndDoc() in UMLView::addAssociation().
At the time of the second call, the AssociationWidget was already created
and inserted at its role widgets.

Fixed as follows:
- In UMLView::addAssociation(), remove the call to
  AssocRules::allowAssociation()
- At ToolBarStateAssociation::addAssociationInViewAndDoc(), change return
  type to bool (true for success) and test the success at
  ToolBarStateAssociation::setSecondWidget()
- Revert the "#if 0" at the extendedCheck code at assocrules.cpp:170 ff.
  thus re-enabling the check for illegal mutual associations.

BUG:235703


 M  +1 -0      ChangeLog  
 M  +0 -33     umbrello/assocrules.cpp  
 M  +9 -6      umbrello/toolbarstateassociation.cpp  
 M  +1 -1      umbrello/toolbarstateassociation.h  
 M  +0 -7      umbrello/umlview.cpp  
 M  +25 -6     umbrello/widgets/associationwidget.cpp  


--- trunk/KDE/kdesdk/umbrello/ChangeLog #1282401:1282402
@@ -8,6 +8,7 @@
 * Generation of classes from files in folder in umbrello (197137)
 * Crash when Clicking on / Trying to Move Datatype on Simple Diagram (202410)
 * Segfault importing Java code - related to variable length parameters (230770)
+* Segmentation fault when trying to generate code (235703)
 * Can't uncheck "Show Public Only" (242545)
 * Umbrello crashed after copy/paste (243392) 
 * Crash when opening file (251094) 
--- trunk/KDE/kdesdk/umbrello/umbrello/assocrules.cpp #1282401:1282402
@@ -165,38 +165,6 @@
         }
     }
 
-    return bValid;
-
-/* TODO:
-   - Check the below code
-   - Check its callers - example: On making a Containment from a Package to a Class,
-     the assoc is already inserted in widgetB->associationWidgetList()
-     when we get here. The assoc SHOULD NOT already be there - therefore the
-     precondition of the below tests is not met, thus they fail, and
-     toolbarstateassociation.cpp:311 says "delete assoc" - but that's too late
-     because the assoc is already being referenced. Valgrind report:
-Invalid read of size 4
-   at 0x82EA890: AssociationWidget::getTextWidgetByRole(Uml::TextRole) (associationwidget.cpp:819)
-   by 0x82EE799: AssociationWidget::calculateTextPosition(Uml::TextRole) (associationwidget.cpp:2411)
-   by 0x82EEC23: AssociationWidget::saveIdealTextPositions() (associationwidget.cpp:1833)
-   by 0x832E676: UMLWidget::adjustAssocs(int, int) (umlwidget.cpp:782)
-   by 0x832CDF8: UMLWidget::updateComponentSize() (umlwidget.cpp:1240)
-   by 0x832CEC1: UMLWidget::updateWidget() (umlwidget.cpp:230)
-   by 0x832DAC2: UMLWidget::qt_metacall(QMetaObject::Call, int, void**) (umlwidget.moc:86)
-   by 0x598D863: QMetaObject::activate(QObject*, int, int, void**) (in /usr/lib/libQtCore.so.4.5.3)
-   by 0x598E584: QMetaObject::activate(QObject*, QMetaObject const*, int, void**) (in /usr/lib/libQtCore.so.4.5.3)
-   by 0x83F6168: UMLObject::modified() (umlobject.moc:122)
-   by 0x83F61FD: UMLObject::setUMLPackage(UMLPackage*) (umlobject.cpp:552)
-   by 0x83E2341: UMLListView::moveObject(std::string, UMLListViewItem::ListViewType, UMLListViewItem*) (umllistview.cpp:1772)
- Address 0x68e6e24 is 92 bytes inside a block of size 708 free'd
-   at 0x40265BD: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
-   by 0x83A6BE4: ToolBarStateAssociation::addAssociationInViewAndDoc(AssociationWidget*) (toolbarstateassociation.cpp:311)
-   by 0x83A6DA1: ToolBarStateAssociation::setSecondWidget() (toolbarstateassociation.cpp:230)
-   by 0x83A70DF: ToolBarStateAssociation::mouseReleaseWidget() (toolbarstateassociation.cpp:149)
-   by 0x83A5255: ToolBarState::mouseRelease(UMLSceneMouseEvent*) (toolbarstate.cpp:123)
- */
-
-#if 0
     if (!bValid) {
         return false;
     }
@@ -328,7 +296,6 @@
         break;
     }
     return false;
-#endif
 }
 
 /**
--- trunk/KDE/kdesdk/umbrello/umbrello/toolbarstateassociation.cpp #1282401:1282402
@@ -227,7 +227,7 @@
     }
     if (valid) {
         AssociationWidget *temp = AssociationWidget::create(m_pUMLScene, widgetA, type, widgetB);
-        addAssociationInViewAndDoc(temp);
+        if (addAssociationInViewAndDoc(temp)) {
         if (type == Uml::AssociationType::Containment) {
             UMLListView *lv = UMLApp::app()->listView();
             UMLObject *newContainer = widgetA->umlObject();
@@ -240,6 +240,7 @@
             }
         }
         UMLApp::app()->document()->setModified();
+        }
     } else {
         //TODO improve error feedback: tell the user what are the valid type of associations for
         //the second widget using the first widget
@@ -291,24 +292,26 @@
  * If the association can't be added, is deleted.
  *
  * @param assoc The AssociationWidget to add.
+ * @return      True on success
  */
-void ToolBarStateAssociation::addAssociationInViewAndDoc(AssociationWidget* assoc)
+bool ToolBarStateAssociation::addAssociationInViewAndDoc(AssociationWidget* assoc)
 {
     // append in view
     if (m_pUMLScene->addAssociation(assoc, false)) {
         // if view went ok, then append in document
         UMLAssociation *umla = assoc->getAssociation();
-        if (umla == NULL) {
-            // association without model representation in UMLDoc
-            return;
-        }
+        if (umla) {
+            // association with model representation in UMLDoc
         Uml::ModelType m = Model_Utils::convert_DT_MT(m_pUMLScene->type());
         UMLDoc *umldoc = UMLApp::app()->document();
         umla->setUMLPackage(umldoc->rootFolder(m));
         UMLApp::app()->document()->addAssociation(umla);
+        }
+        return true;
     } else {
         uError() << "cannot addAssocInViewAndDoc(), deleting";
         delete assoc;
+        return false;
     }
 }
 
--- trunk/KDE/kdesdk/umbrello/umbrello/toolbarstateassociation.h #1282401:1282402
@@ -64,7 +64,7 @@
 
     Uml::AssociationType getAssociationType();
 
-    void addAssociationInViewAndDoc(AssociationWidget* assoc);
+    bool addAssociationInViewAndDoc(AssociationWidget* assoc);
 
     void cleanAssociation();
 
--- trunk/KDE/kdesdk/umbrello/umbrello/umlview.cpp #1282401:1282402
@@ -1832,13 +1832,6 @@
         return false;
     }
 
-    //make sure valid
-    if (!isPasteOperation && !m_doc->loading() &&
-            !AssocRules::allowAssociation(assocType, pWidgetA, pWidgetB)) {
-        uWarning() << "allowAssociation returns false " << "for AssocType " << assocType;
-        return false;
-    }
-
     //make sure there isn't already the same assoc
 
     foreach(AssociationWidget* assocwidget, m_AssociationList) {
--- trunk/KDE/kdesdk/umbrello/umbrello/widgets/associationwidget.cpp #1282401:1282402
@@ -112,17 +112,36 @@
                 UMLDoc *doc = UMLApp::app()->document();
                 UMLAssociation *myAssoc = doc->findAssociation( assocType, umlRoleA, umlRoleB, &swap );
                 if (myAssoc != NULL) {
-                    if (assocType == Uml::AssociationType::Generalization) {
-                        uDebug() << " Ignoring second construction of same generalization";
-                    } else {
-                        uDebug() << " constructing a similar or exact same assoc " <<
-                        "as an already existing assoc (swap=" << swap << ")";
+                    switch (assocType) {
+                        case Uml::AssociationType::Generalization:
+                        case Uml::AssociationType::Dependency:
+                        case Uml::AssociationType::Association_Self:
+                        case Uml::AssociationType::Coll_Message_Self:
+                        case Uml::AssociationType::Seq_Message_Self:
+                        case Uml::AssociationType::Containment:
+                        case Uml::AssociationType::Realization:
+                            uDebug() << "Ignoring second construction of same assoctype "
+                                     << assocType << " between " << umlRoleA->name()
+                                     << " and " << umlRoleB->name();
+                            break;
+                        default:
+                            uDebug() << "constructing a similar or exact same assoctype "
+                                     << assocType << " between " << umlRoleA->name() << " and "
+                                     << umlRoleB->name() << "as an already existing assoc (swap="
+                                     << swap << ")";
                         // now, just create a new association anyways
                         myAssoc = NULL;
+                            break;
                     }
                 }
-                if (myAssoc == NULL)
+                if (myAssoc == NULL) {
                     myAssoc = new UMLAssociation( assocType, umlRoleA, umlRoleB );
+                    // CHECK: myAssoc is not yet inserted at any parent UMLPackage -
+                    // need to check carefully that all callers do this, lest it be
+                    // orphaned.
+                    // ToolBarStateAssociation::addAssociationInViewAndDoc() is
+                    // okay in this regard.
+                }
                 instance->setUMLAssociation(myAssoc);
             }
         }




More information about the umbrello-devel mailing list