GNOME Bugzilla – Bug 314153
Weak connection-points with crashes
Last modified: 2006-01-14 13:52:33 UTC
Steps to reproduce: 1. Create a empty diagram 2. Create a UML class object with 2 operations 3. Create a line and connect it to the bottom most operation 4. Open the class' properties by double-clicking the class object, and close it without doing anything NOTICE: the line isn't connected to the operation anymore 5. Do step four until dia crashes Stack trace: Other information:
It even works with class-attributes, and only one operation, or attribute.
Reproduced, stack trace is
+ Trace 63014
Created attachment 52242 [details] Test file where first change-less edit of UML object crashes Dia
Fixes have reduced this to (as far as I can tell) only being a problem when removing an attribute/operation that has a connection onto it. Took a fair amount of restructuring the way the connectionpoints are stored, but it works a lot slicker now. Not closing yet. Step to reproduce remaining crashbug: Create a UML class with two attributes. Connect a line to one attribute. Delete that attribute. Move the line.
I have been investigating this problem. I am not sure if I have found a new bug or just found the root cause of the crash. I have determined that crash is caused by the line still having a connection registered but that connection no longer being valid. This often happens when a connection exits on an operation or attribute and that operation or attribute has been remove. There must be some form of tracking on the relationship between an element and the connection because if the element is moved up and down, the connection follows it.
Further investingation indicates that there is tracking of the deleted connection points, but the objects connected at the points which have been deleted are not processed to remove their corresponding connections. I have not yet been able to determine why and am still looking. (see code in class_dialog.c)
*** Bug 319447 has been marked as a duplicate of this bug. ***
I have finally identified the root cause. When search the connection points to see if they apply to any connection, the code uses the pointer to the connection point as the identity. That is it compares the connection pointers in an object against the connection pointers in the deleted connections list. This requires that the address of a connection must remain constant from the time it is first connected to until it is either fully disconnected or deleted. In the class_dialog.c code, attributes and operations are cloned for both the state object and for insertion into the appropriate lists. When cloning an object, the connections are created new. The reason for this is that the objects on the dialog lists are treated as belonging to the dialog list and are fully destroyed when the object is deleted or when the list is destroyed. In the case of where an object, either attribute or operation, is deleted both the object on the list and the objects in the state and umlclass are also deleted. In the case where a new object is added to one of these lists, an object of the appropriate type is created for the list and then duplicated for both the state and the umlclass. My proposed solution would be to change the way the lists are treated. In the proposed approach, the objects on the dialog lists would not be destroyed when the list is destroyed. The lists would contain the umlclass instance of the object and the only time this object would be destroyed is when it has been deleted from the list. By doing this, the connections in the object would always have the same identity (pointer address) thus making it possible to compare the connection points using the existing code. This has the added advantage of reducing the number of dynamic objects that are create and destroyed. Which some would argue is a good thing. Some additional changes would need to be made to ensure that there is no leakage of memory as a result. For instance, when a connection point is placed on the disconnect list, the object should have its references to that connection point set to NULL so that the ownership of the object is transferred to the disconnect list which will destroy the connection point after processing it. This prevents the occurrences of double free’s. Also in the current code when an object (either attribute or operation) is placed on the dialog’s list, a signal is registered to destroy the object if it is deleted from the list. In my proposed solution, this would only be done if the object was created with-in the list by using the NEW action button.
It would help if you gave some pointers to code lines -- the terminology gets confusing real fast. There shouldn't be any use of the CP addresses as identity in the dialog code, the internal_id field should suffice for that. In which places is this not the case? I made the internal_id such that pointer comparison would not be required.
Apparently the state of this is even worse than the subject says. The diagram I have attached to bug #325151 ( http://bugzilla.gnome.org/attachment.cgi?id=56472&action=view ) exhibits one of the worst crashes with the UML Class dialog I've ever seen. If you dont want to restart your Linux prepare to change to a console and issue 'killall dia' or even 'killall gdb'. Anyway I'll start looking at the issue again right now.
See also: http://mail.gnome.org/archives/dia-list/2006-January/msg00019.html 2006-01-14 Hans Breuer <hans@breuer.org> * lib/debug.c : replace wrong call to vprintf() - missing file descriptor - with the more appropriate g_vprintf(). Thus dia_assert_true() does not smash the stack anymore on win32. * objects/UML/class.c objects/UML/class_dialog.c objects/UML/uml.h objects/UML/umlattribute.c objects/UML/umloperation.c : reverted the memory managment of UMLAttribute/UMLOperation's ConnectionPoint(s) back to how it was up until 0.94. This finally makes the UMLClass work again including undo/redo support. Fixes bug #314153 and en passant bug #326453.