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