Daizu development has been held up for the last few weeks due to a serious bug which I just couldn't track down. I've finally found it in the Subversion Perl bindings.
The symptoms were that sometimes, in specific circumstances which
I couldn't at first identify, the
DBI
method selectrow_array was returning an undefined value when
it shouldn't have been. The SQL query was right,
and there was definitely a record in the database it should have been
returning. I eventually found that the value being returned wasn't
quite a normal ‘undef’ value, because if you printed it out with
Data::Dumper
it would magically turn in to the correct value.
A lot of hard debugging later (just try debugging Perl
XS libraries with gdb—you can't
print any of the values of variables without manually expanding endless
C macros) I found that
the DBD::Pg driver
was actually getting the right value from the
database, but it was being corrupted somehow on its way back to
Perl space. I suspected that there might be something wrong with
the DBI's method dispatcher, which is huge and hard to understand.
Eventually, after printing out information about the Perl argument stack, I found that it was getting bigger when it shouldn't have been. Turns out that this problem, which only happens in Perl methods which are part of a Subversion ‘editor’ (a class which receives information about changes in the repository), was caused by the Subversion Perl API incorrectly invoking the methods. It wasn't properly adjusting the stack to take return values off. Or rather, it was only adjusting the local copy of the stack and not updating the global stack with the changes.
So you only get this problem if you're doing certain things in a Subversion editor written in Perl, and if the update you're processing is complicated enough that the editor's methods get called a sufficient number of times.
After all that debugging work my patch is annoyingly small:
Index: swigutil_pl.c ========================================= --- swigutil_pl.c (revision 22317) +++ swigutil_pl.c (working copy) @@ -426,6 +426,7 @@ SvREFCNT_inc(*result); } + PUTBACK ; FREETMPS ; LEAVE ;
This has been committed and I expect it to turn up in Subversion 1.4.3.