[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

String corruption problem?

From: Joe Orton <joe_at_light.plus.com>
Date: 2000-10-09 00:52:48 CEST

Am I right in saying the path corruption problem still persists even
after Greg H's recent fix: 'make check' in libsvn_wc shows corruption
for me?

(I may be way off track here, apologies for wasting your time if I am ;)

It seems that sometimes the data of a string is getting reallocated in a
different pool than it was originally allocated it. This should be safe
if the new pool is a parent of the original pool, but otherwise I think
it will cause problems, since the string will get de-allocated sooner
than it should.

The patch below stores the original pool in the string structure, and
detects when a realloc is attempted with a different pool and prints a
warning. It also forces the realloc to occur using the *original* pool;
this does actually fix the corruption problem which is encouraging.

If this isn't completely bogus analysis, the output says the strings are
getting re-allocated in a pool which is *not* a parent of the original
pool, which is probably the cause of the corruption.

todo: find the places where the wrong pool is passed to a string mutator
function. It mightn't be a bad change to actually store the original
pool in the string structure in any case, and re-allocate from there
rather than taking a pool parameter; that would prevent this kind of
problem.

Index: include/svn_string.h
===================================================================
RCS file: /cvs/subversion/subversion/include/svn_string.h,v
retrieving revision 1.35
diff -u -r1.35 svn_string.h
--- include/svn_string.h 2000/10/02 18:29:04 1.35
+++ include/svn_string.h 2000/10/08 22:06:19
@@ -55,6 +55,7 @@
 #include <apr_pools.h> /* APR memory pools for everyone. */
 #include "svn_types.h"
 
+#define SVN_STRING_DEBUG 1
 
 
 /* The svn_string_t data type. Pretty much what you expected. */
@@ -63,6 +64,9 @@
   char *data; /* pointer to the bytestring */
   apr_size_t len; /* length of bytestring */
   apr_size_t blocksize; /* total size of buffer allocated */
+#ifdef SVN_STRING_DEBUG
+ apr_pool_t *pool;
+#endif
 } svn_string_t;
 
 
Index: libsvn_string/svn_string.c
===================================================================
RCS file: /cvs/subversion/subversion/libsvn_string/svn_string.c,v
retrieving revision 1.49
diff -u -r1.49 svn_string.c
--- libsvn_string/svn_string.c 2000/10/03 22:33:37 1.49
+++ libsvn_string/svn_string.c 2000/10/08 22:06:21
@@ -97,6 +97,9 @@
   new_string->data = (char *) apr_palloc (pool, size + 1);
   new_string->len = size;
   new_string->blocksize = size + 1;
+#ifdef SVN_STRING_DEBUG
+ new_string->pool = pool;
+#endif
 
   memcpy (new_string->data, bytes, size);
 
@@ -158,7 +161,26 @@
   return (str->len == 0);
 }
 
+int svn_pool_is_ancestor(apr_pool_t *a, apr_pool_t *b)
+{
+ if (a == NULL) {
+ return 1;
+ }
+#ifdef POOL_DEBUG
+ while (a->joined) {
+ a = a->joined;
+ }
+#endif
+ while (b) {
+ if (a == b) {
+ return 1;
+ }
+ b = b->parent;
+ }
+ return 0;
+}
 
+
 void
 svn_string_ensure (svn_string_t *str,
                    apr_size_t minimum_size,
@@ -173,6 +195,20 @@
         while (str->blocksize < minimum_size)
           str->blocksize *= 2;
     }
+
+#ifdef SVN_STRING_DEBUG
+ if (pool != str->pool)
+ {
+ fprintf (stderr, "string realloc to different pool %p -> %p: ", str->pool, pool);
+ if (svn_pool_is_ancestor(pool, str->pool)) {
+ fprintf(stderr, "ancestor.\n");
+ } else {
+ fprintf(stderr, "not ancestor.\n");
+ pool = str->pool;
+ }
+ }
+#endif
+
 
   str->data = (char *) my__realloc (str->data,
                                     str->len,
Received on Sat Oct 21 14:36:10 2006

This is an archived mail posted to the Subversion Dev mailing list.