GnuCash
Contact   Instructions
Bug 798203 - g_assert fault while reversing transaction
Summary: g_assert fault while reversing transaction
Status: RESOLVED FIXED
Alias: None
Product: GnuCash
Classification: Unclassified
Component: Engine (show other bugs)
Version: git-maint
Hardware: PC Windows
: Normal major
Target Milestone: ---
Assignee: core
QA Contact: core
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-06-02 11:16 EDT by Christopher Lam
Modified: 2021-06-12 16:40 EDT (History)
4 users (show)

See Also:


Attachments
my test datafile (382.41 KB, application/x-gnucash)
2021-06-02 11:16 EDT, Christopher Lam
no flags Details

Description Christopher Lam 2021-06-02 11:16:43 EDT
Created attachment 374083 [details]
my test datafile

From current maint:
Load my test datafile.
Open the Imbalance-USD account
Highlight the 24/11/19 split. (this has Imbalance and Trading splits).
Transaction > Add Reversing Transaction.
Complete dialog "OK" (default values are fine).
Segfaults:

* 23:13:22 ERROR <gnc.engine> xaccTransClone: assertion 'g_list_length (to->splits) == g_list_length (from->splits)' failed
./run-maint.sh: line 10: 230045 Segmentation fault      (core dumped) ./gnucash --extra --logto stdout

Seems to be caused by the f10b0339f commit merging da3c511b6 into maint.
Comment 1 John Ralls 2021-06-10 19:15:22 EDT
More to the point it has *empty* trading splits that quite reasonably get removed and not re-created when the cloned transaction is committed. How did you make a transaction with empty trading splits?

The simple work-around would be to edit, dirty, and commit the original transaction as the first step of cloning it.
Comment 2 Christopher Lam 2021-06-10 19:35:05 EDT
I seriously cannot remember... definitely created via UI. Still, anything would be better than a g_assert fault.
Comment 3 John Ralls 2021-06-10 19:55:51 EDT
Don't run with G_DEBUG=fatal-criticals or fatal-warnings if you don't want the assert--but if you do you'll get a segfault at Transaction.c:2802 instead because xaccTransReverse doesn't null check trans. Some will argue that's worse. ;-)

BTW, there's a memory leak there, do you see it?
Comment 4 Christopher Lam 2021-06-10 23:30:42 EDT
(In reply to John Ralls from comment #3)
> Don't run with G_DEBUG=fatal-criticals or fatal-warnings if you don't want
> the assert--but if you do you'll get a segfault at Transaction.c:2802

2802? Why?

> instead because xaccTransReverse doesn't null check trans. Some will argue
> that's worse. ;-)
> 
> BTW, there's a memory leak there, do you see it?

The GValue not being unset? Maybe, I'd need to re-check valgrind.
Comment 5 Christopher Lam 2021-06-11 10:26:12 EDT
(In reply to John Ralls from comment #3)
> Don't run with G_DEBUG=fatal-criticals or fatal-warnings if you don't want
> the assert--but if you do you'll get a segfault at Transaction.c:2802
> instead because xaccTransReverse doesn't null check trans. Some will argue
> that's worse. ;-)
> 
> BTW, there's a memory leak there, do you see it?

Or the GncGUID not being guid_free()d.
Comment 6 John Ralls 2021-06-11 11:40:02 EDT
> 2802? Why?

Now 2825.

I guess I was unclear: The leak is in xaccTransClone when the list lengths are unequal, not in xaccTransReverse.
Comment 7 Christopher Lam 2021-06-12 11:21:30 EDT
(In reply to John Ralls from comment #3)
> Don't run with G_DEBUG=fatal-criticals or fatal-warnings if you don't want
> the assert--but if you do you'll get a segfault at Transaction.c:2802
> instead because xaccTransReverse doesn't null check trans. Some will argue
> that's worse. ;-)

I don't actually run with these fatal-critical warnings. Here's my RUN script:

------------------------------
ninja -j 3 && ninja install
cd ../maint$1-install/bin
# gdb -ex run --args ./gnucash --logto stdout
./gnucash --extra --logto stdout
------------------------------

And here's the segfault crash:

------------------------------
* 23:20:10 ERROR <gnc.engine> xaccTransClone: assertion 'g_list_length (to->splits) == g_list_length (from->splits)' failed
./run-maint.sh: line 10:  5947 Segmentation fault      (core dumped) ./gnucash --extra --logto stdout
------------------------------

> 
> BTW, there's a memory leak there, do you see it?

I'll leave it to you how to fix it, I don't see any leak!
Comment 8 John Ralls 2021-06-12 11:59:25 EDT
> I don't actually run with these fatal-critical warnings.
G_DEBUG is an environment variable. If it's not set then the assert in g_log doesn't run and is only informational.

> ./run-maint.sh: line 10:  5947 Segmentation fault      (core dumped) ./gnucash --extra --logto stdout

That's your run script, it's not telling you anything about the actual crash location. Switch it to run the gdb line and get a stack trace of a few frames to see the actual crash information.

> I'll leave it to you how to fix it, I don't see any leak!

Transaction *
xaccTransClone (const Transaction *from)
{
    Transaction *to = xaccTransCloneNoKvp (from); // Allocates a Transaction
    GList *lfrom, *lto;

    xaccTransBeginEdit (to);
    qof_instance_copy_kvp (QOF_INSTANCE (to), QOF_INSTANCE (from));
    g_return_val_if_fail (g_list_length (to->splits) == g_list_length (from->splits),
                          NULL); // Returns nullptr without freeing `to`.
Comment 9 John Ralls 2021-06-12 16:40:49 EDT
> I'll leave it to you how to fix it

Done.

Note You need to log in before you can comment on or make changes to this bug.