svn_hash_sets() was only introduced a few months ago as an optimized version
for apr_hash_set() for strings.
This could be a bug introduced during the semi-automatic conversion…
Are you on irc/im?
(I’m debugging onther perl binding problems from Windows right now and maybe we
can share some ideas)
Bert
From: Roderich Schupp [mailto:[email protected]]
Sent: woensdag 24 juli 2013 13:30
To: dev
Cc: Ben Reser
Subject: Problem with Perl bindings?
Hi,
I'm investigating a problem with the Perl bindings and it looks as if an APR
hash gets
corrupted when it's marshalled to/from Perl.
Specifically I'm looking at
/subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.c (from trunk)
and the function svn_swig_pl_to_hash. This is the universal converter from
"Perl hash of somethings"
to "APR hash of somethings (else)". The guts of this function is (comments are
mine):
apr_hash_t *hash;
HV *h;
char *key;
I32 cnt, retlen;
// create the APR hash that we're going to return
hash = apr_hash_make(pool);
// prepare to iterate over the Perl hash "source" (both keys and values,
like "each %hash" in Perl)
h = (HV *)SvRV(source);
cnt = hv_iterinit(h);
while (cnt--) {
// get the next key (into "key") and value (into "item")
SV* item = hv_iternextsv(h, &key, &retlen);
// convert value from Perl to SVN using the supplied callback cv
void *val = cv(item, ctx, pool);
// store converted value under key in APR hash
svn_hash_sets(hash, key, val);
}
IMHO the last statement is problematic: The Perl API call hv_iternextsv just
stores a pointer to the Perl internal key string into "key". And we use this
internal pointer to set the APR hash key. Shouldn't we make a copy
of the string (in some pool) and use that to set the APR hash key?
Note: if this is indeed a problem it may have gone unrecognized for a long time.
The reason is that the keys for all Perl hashes in a program are stored in
a central location, i.e. if we have hashes %foo and %bar that both
have a key "fubar", then this "fubar" is stored only once. And "fubar"
will only be garbage collected (and the bytes at its address recycled)
if no hash anywhere contains a key "fubar" anymore.
Cheers, Roderich