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

[PATCH] A major mod_dav_svn memory leak

From: Tobias Ringstrom <tobias_at_ringstrom.mine.nu>
Date: 2004-01-09 19:10:45 CET

I'm not sure how to best describe the problem, so here is the recepie:

------------ gen_files.py -----------------
import sys
for i in range(int(sys.argv[1])):
     name = 'file%04d' % i
     open(name, 'w').write('%s\n' % name)
-------------------------------------------

On the server: svnadmin create repos

On the client:
1. svn co http://server/repos
2. cd repos
3. python gen_files.py 500 ; svn add file0* ; svn commit -m ""
    (Everything is OK so far)
4. svn up
    (the server is now growing to ~200 MiB)

The attached proof of concept patch plugs the leak. I'm not an
mod_dav_svn expert, so lots of review would be most welcome. :-)

/Tobias

Index: update.c
===================================================================
--- update.c (revision 8194)
+++ update.c (working copy)
@@ -1003,6 +1003,7 @@
    svn_boolean_t resource_walk = FALSE;
    svn_boolean_t ignore_ancestry = FALSE;
    struct authz_read_baton arb;
+ apr_pool_t *subpool = svn_pool_create(resource->pool);

    /* Construct the authz read check baton. */
    arb.r = resource->info->r;
@@ -1251,6 +1252,7 @@
    for (child = doc->root->first_child; child != NULL; child = child->next)
      if (child->ns == ns)
        {
+ svn_pool_clear(subpool);
          if (strcmp(child->name, "entry") == 0)
            {
              const char *path;
@@ -1284,14 +1286,14 @@
                }

              /* get cdata, stipping whitespace */
- path = dav_xml_get_cdata(child, resource->pool, 1);
+ path = dav_xml_get_cdata(child, subpool, 1);

              if (! linkpath)
                serr = svn_repos_set_path(rbaton, path, rev,
- start_empty, resource->pool);
+ start_empty, subpool);
              else
                serr = svn_repos_link_path(rbaton, path, linkpath, rev,
- start_empty, resource->pool);
+ start_empty, subpool);
              if (serr != NULL)
                {
                  svn_error_clear(svn_repos_abort_report(rbaton));
@@ -1321,9 +1323,9 @@
              const char *path;

              /* get cdata, stipping whitespace */
- path = dav_xml_get_cdata(child, resource->pool, 1);
+ path = dav_xml_get_cdata(child, subpool, 1);

- serr = svn_repos_delete_path(rbaton, path, resource->pool);
+ serr = svn_repos_delete_path(rbaton, path, subpool);
              if (serr != NULL)
                {
                  svn_error_clear(svn_repos_abort_report(rbaton));
@@ -1415,5 +1417,7 @@
                                   "report.");
      }

+ svn_pool_destroy(subpool);
+
    return NULL;
  }

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Fri Jan 9 19:11:30 2004

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