On Oct 17, 2011, at 11:34 AM, Christian Stimming wrote: > Am Montag, 17. Oktober 2011 schrieb John Ralls: >> On Sep 26, 2011, at 11:35 AM, Christian Stimming wrote: >>> Am Montag, 26. September 2011 schrieb John Ralls: >>>> I have a plan to rework the engine (the module which does all of >>>> the accounting and business calculations) in stages. Stage one is to >>>> write comprehensive tests for each class. Stage two (which will >>>> interleave with stage one) is to overhaul each class to be a >>>> well-behaved GObject class with all access to data (including KVP) via >>>> function calls instead of passing out pointers for other objects to >>>> modify at will. >>> >>> Out of curiosity: Which examples for "passing out pointers" do you have >>> in mind here? Surely there is plenty of access to KVP data by simply >>> accessing the KVP directly, which is bad, but is there also direct >>> pointer manipulation in that many places? >> >> Here's an example I found today, while investigating bug 661903: >> xaccTransGetSplitList() returns a GList* of the splits. The requestor can >> manipulate or delete the splits, unbalancing or even eviscerating the >> transaction without the transaction knowing. It's called in 23 places in C >> and 19 in Scheme. >> >> It doesn't help that Accounts also keep a list of splits and since we're >> not using GObject reference counting, there's no way to protect against >> one or both from having invalid pointers. > > Absolutely. All of the API functions passing out a GList* are prone to this > error. However, that's an inherent issue of any C API, because the only > alternative is to pass out a newly allocated GList* each time. You can easily > guess this will lead to plenty of memory leaks... well... thinking about it > again, this might not be as bad as it sounds. Maybe those functions should > indeed pass out a newly allocated GList instead of the internal one, i.e. > just > using g_list_copy. Then again, the data pointers will still be plain > non-const > pointers as there isn't a const variant of GList*...
That's only part of the problem. The bug (and it's 661093, not 661903, sorry) is reporting a crash caused by trying to access a split that's been freed. We have several objects holding references to splits (transactions, accounts, lots, and business entities come immediately to mind); in addition, register windows need to have active access to split lists in order to edit them. Aside from memory management, problems arise in notifying all of the holders of references to a split that the split isn't valid. I think that's supposed to be done with QofSignals and handlers, but there's at least one demonstrated hole in the process. There are a couple of approaches to handling all of the references, but I don't yet know which one will best enforce database integrity. They all involve getting everything into a clean GObject first so that reference counting and weak references can be used to manage object lifetime, so we can defer worrying about it for a while. Regards, John Ralls _______________________________________________ gnucash-devel mailing list gnucash-devel@gnucash.org https://lists.gnucash.org/mailman/listinfo/gnucash-devel