Here's how to reproduce my problem (I'm using SVN 1.7.10, but probably any version is affected):
Start with a simple command line, e.g. $ svn ls http://svn.apache.org/repos/asf/subversion but that requires some setting in ~/.sunversion/servers to work. E.g. if I'm behind a proxy to the internet, I have to set some http-proxy-* options, otherwise I'll get this error: svn: E175002: Unable to connect to a repository at URL ' http://svn.apache.org/repos/asf/subversion' svn: E175002: OPTIONS of 'http://svn.apache.org/repos/asf/subversion': Could not resolve hostname `svn.apache.org': Host not found ( http://svn.apache.org) So once we got the command line going, lets rephrase the command with the Perl bindings: use SVN::Core; use SVN::Client; my $client = SVN::Client->new(); my $ls = $client->ls("http://svn.apache.org/repos/asf/subversion", undef, 0); I run this script and get RA layer request failed: Unable to connect to a repository at URL ' http://svn.apache.org/repos/asf/subversion': OPTIONS of ' http://svn.apache.org/repos/asf/subversion': Could not resolve hostname ` svn.apache.org': Host not found (http://svn.apache.org) at script.pl line 4. Apparently, the SVN::Client doesn't honor the stuff in ~/.subversion/servers, though according to the docs it should. Looking at SVN/Client.pm we see that if I don't specify any parameter to SVN::Client->new() then it will do $client->config(SVN::Core::config_get_config(undef)) by default. This is the Perl equivalent of calling svn_config_get_config(apr_hash_t **cfg_hash, NULL, pool) and then assigning *cfg_hash to svn_client_ctx_t->config. Note that in the Perl version the apr_hash_t returned by svn_config_get_config is first converted to a Perl hash and immediatley converted back to an apr_hash_t by the setter function for svn_client_ctx_t->config. Using gdb I confirmed that on return from svn_config_get_config (on the C level) *cfg_hash points to an apr_hash_t with just two keys, "config" and "servers" (and correct values). The corresponding Perl hash also has keys "config" and "servers". But the apr_hash_t that is actually passed down to something like svn_ra_neon__open() (when svn_client_ls() is called in the last line of the script) is corrupted: it contains two keys, one is "config", but the other is purported to be 7 characters long, but the contents is not "servers" (in my case, it's an empty string). The value for the corrupted key is the same as for the original "servers", though. But neon will not be able to find the information for "servers", hence the request will ultimately fail. So it looks like the conversion from Perl hash to apr_hash_t is to blame. It does NOT actually copy the key strings (in Perl controlled memory) to some APR pool, but instead stores their pointers into the apr_hash_t. If Perl later garbage collects the key strings, the apr_hash_t will reference overwritten memory. Since key strings exist only once in memory (i.e. all keys "foo" in any hash in the program reference the same memory location), the can only be garbage collected if they are dropped from all existing hashes. Conversely, if I add the line my %dummy = ( "servers" => undef ); before SVN::Client->new(), this will "pin" the hash key "servers" for the rest of the execution. And indeed, this line will make the script work! Here's the proposed fix (for SVN 1.7.x) --- subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.c +++ subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.c @@ -116,7 +116,7 @@ while (cnt--) { SV* item = hv_iternextsv(h, &key, &retlen); void *val = cv(item, ctx, pool); - apr_hash_set(hash, key, APR_HASH_KEY_STRING, val); + apr_hash_set(hash, apr_pstrmemdup(pool, key, retlen), retlen, val); } return hash;