"Crashing" bug report -- MoleculeDocument?

Hi list,

I’m sure many of you saw this:

http://sourceforge.net/tracker/?func=detail&aid=3459981&group_id=165310&atid=835077

This bug report summarizes a lot of the feedback I get from my
colleagues after they use avogadro for a while – they like the
program, see potential, but it’s just not stable enough for everyday
use. I’ve noticed this myself – in fact, I always get a tad nervous
and mentally review recent changes before hitting “Undo” in case I did
anything slightly out of the ordinary that may trigger a crash.

I think that “Undo” is one area of avogadro that really needs some
attention. I’m as guilty as anyone; many of my early patches did not
implement undo at all, and even recent patches that had undo (e.g. the
crystallography extension) did so in a way that cluttered the internal
data structures and left some things inconsistent.

I’ve been thinking about how we can improve this, and my current
favorite solution would be a “MoleculeDocument” class. The key
concepts that go into this class:

  • MoleculeDocument holds a pointer to the current molecule
  • MoleculeDocument has API functions that modify the molecule
    (addAtom, removeBond, etc)
  • Each function that modifies the molecule creates an UndoCommand to
    carry out the specified changes
  • Changes can be concatenated

Concatenation can be carried out automatically behind the scenes using
QUndoStack::(begin|end)Macro() and/or QUndoCommand::mergeWith():

http://developer.qt.nokia.com/doc/qt-4.8/qundostack.html#id-288389e4-1582-4772-bda4-381569e3ada4

If all modification to the molecule is performed through the
MoleculeDocument and the class is heavily unit-tested and stable, then
undo becomes much simpler and more reliable. As an example, here are
some things I’d like to be able to do from an extension/tool/etc:

Add a methane molecule at the origin. This code would produce at least
9 individual undo commands, 5 AddAtomCommands and 4 AddBondCommands.
Depending on how the calls are made, there may be
SetBondOrderCommands, TranslateAtomCommands, etc may be produced as
well. They will all be concatenated into a single UndoCommand with the
name “Add methane”.

MoleculeDocument *doc = getCurrentMoleculeDocument();
doc->beginModify(“Add methane”);
doc->addAtom(6, 0.0, 0.0, 0.0); // Carbon at origin
doc->adjustHydrogens();
doc->endModify();

We could do something similar for crystals:

MoleculeDocument *mdoc = getCurrentMoleculeDocument();
CrystalDocument doc = qobject_cast<CrystalDocument>(mdoc);
if (!doc) return; // Not a crystal
doc->beginModify(“Construct crystal”);
doc->setCellParams(a, b, c, alpha, beta, gamma);
doc->addAtom(…); // etc
doc->setSpacegroup(“Pnma”);
doc->fillUnitCell();
doc->reduceToPrimitiveCell();
doc->endModify()

Again, each function in the Document class will produce a number of
UndoCommands that are concatenated into a single command, “Construct
crystal”.

This would be a lot of work and it might prove inefficient for some
corner cases (like extremely large-scale changes), but I think that
the reliability payoff far exceeds this, and we could always allow for
custom undo commands to be used for those “special” cases that are
problematic.

Any thoughts or opinions? This would be a large scale change, and I’m
not sure what version something like this should be slotted for. But
as evidenced by the bug report, we are turning away a lot of potential
users with a negative experience and this is a major area that needs
improvement.

Dave

On Fri, Dec 16, 2011 at 11:48 AM, David Lonie loniedavid@gmail.com wrote:

Any thoughts or opinions? This would be a large scale change, and I’m
not sure what version something like this should be slotted for. But
as evidenced by the bug report, we are turning away a lot of potential
users with a negative experience and this is a major area that needs
improvement.

We are spinning up our effort on Avogadro 2, and I honestly want to
focus our effort on that for large scale changes like this. Being able
to build up a real delta is something Geoff and I sketched out, and I
think it is the right way to go. I would like to release 1.1 to expose
much of the new functionality, but I think there are also several
other issues causing crashes.

Having a better testing framework, and actually writing tests will
help us avoid many of these issues. Infrastructure is coming online as
part of our work to facilitate this - I will try to post more about
the early MolCore work we have been doing that shows off some of this
infrastructure.

Marcus

On Fri, Dec 16, 2011 at 12:06 PM, Marcus D. Hanwell
mhanwell@gmail.com wrote:

On Fri, Dec 16, 2011 at 11:48 AM, David Lonie loniedavid@gmail.com wrote:

Any thoughts or opinions? This would be a large scale change, and I’m
not sure what version something like this should be slotted for. But
as evidenced by the bug report, we are turning away a lot of potential
users with a negative experience and this is a major area that needs
improvement.

We are spinning up our effort on Avogadro 2, and I honestly want to
focus our effort on that for large scale changes like this. Being able
to build up a real delta is something Geoff and I sketched out, and I
think it is the right way to go. I would like to release 1.1 to expose
much of the new functionality, but I think there are also several
other issues causing crashes.

Sure, only some of the crashes are related to undo. What other problem
areas have you noticed? I think this is a conversation that is
overdue, and especially if we’re really going to get a 1.1 release out
the door, we should begin cleaning these areas up.

Having a better testing framework, and actually writing tests will
help us avoid many of these issues.

Agreed!

Infrastructure is coming online as
part of our work to facilitate this - I will try to post more about
the early MolCore work we have been doing that shows off some of this
infrastructure.

Looking forward to hearing about this. Molcore-devel is rather curious
about it, too :wink:

Dave

I’ve noticed this myself – in fact, I always get a tad nervous
and mentally review recent changes before hitting “Undo” in case I did
anything slightly out of the ordinary that may trigger a crash.

If “undo” is something which commonly causes crashes for you, then I think you should try to categorize/reproduce the crashes. While I agree with your concept on a MoleculeDocument, IMHO, there isn’t a good level of “bug cleanup” and that’s critical for the reasons you mentioned.

What we probably need is:

  1. Periodic stabilization freezes to focus on bug fixing
  2. Nightly debug-enabled builds
  3. Automated GUI “fuzz testing”

Unfortunately, one of the hardest problems for me are Windows crashes. Many times, I have a hard time reproducing on Mac, and never know if it’s a Windows issue, a Qt/Windows bug, a random driver crash, etc. (For example, one of my students had issues on Win7 until he upgraded his graphics driver.)

But with Open Babel, there’s a systematic culture of strong bug-fixing throughout the development, and particularly before a release. The current development master hasn’t seen that level of QA testing. That’s point #1.

Point #2, I’d love to see if we can embed some level of send-the-crash-report code. In many apps I use, this is invaluable to the developers, and it lets our users know we’re serious about fixing crashes. I emphasize the nightly builds, because it means we can attempt to fix bugs for remote users and they can see if it works. We’d also get back-traces on Windows crashes!
Mozilla Crash Reporter - MozillaZine Knowledge Base (But other solutions probably exist.)

Point #3, I’ve used in the Avogadro Mac builds – basically it’s a program that sends mouse and key events randomly, trying to force crashes:
http://pages.cs.wisc.edu/~bart/fuzz/

The clang compiler also looks like it has some new memory and race error detection tools:

http://code.google.com/p/data-race-test/

-Geoff