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

Re: Berkeley DB help needed [was Re: [PATCH] BDB error_info threading issue causing core dumps]

From: Blair Zajac <blair_at_orcaware.com>
Date: Fri, 05 Dec 2008 18:00:07 -0800

Branko Cibej wrote:
> Maybe. Like I said, I'll have to remember what I was smoking^Wthinking
> when I wrote that code. I'm sure there was a good reason that all access
> wasn't through that function.
>> The cleanup code is complicated and I'm still working on understanding it.
> You don't say. I *wrote* it and still I have trouble understanding it. :(

Michael Zhang wrote this test case that reproduces the core dump we've been
seeing in our server. I tested it on my Mac OS X box and it fails there also.

$ svnadmin create --fs-type bdb /tmp/repos
$ gcc -Wall -o svntest -g -I/opt/local/include/apr-1
-I/opt/local/include/subversion-1 svntest.c -L/opt/local/lib -lsvn_repos-1
-lsvn_subr-1 -lapr-1
$ ./svntest /tmp/repos

The code needs to switch to more APR functions to make it in our test suite, but
it shows the issues.

#include <apr.h>
#include <svn_pools.h>
#include <svn_repos.h>
#include <pthread.h>

#define NUMTHREADS 2

apr_pool_t *gpool = NULL;
apr_pool_t *secondPool = NULL;

struct cond
   pthread_mutex_t dataMutex;
   pthread_cond_t dataPresentCondition;
   pthread_cond_t cond2;

char *repos_path;

struct cond gcond = { PTHREAD_MUTEX_INITIALIZER,

void *worker(void *arg)
   int id = *(int *)arg;
   int rc = 0;
   svn_repos_t *repos;
   apr_pool_t *pool = NULL;
   if (id == 0)
       while (!secondPool)
           pthread_cond_wait(&gcond.dataPresentCondition, &gcond.dataMutex);
       pool = svn_pool_create(gpool);
       svn_repos_open(&repos, repos_path, pool);

       secondPool = NULL;


       // This sleep make dbd reference count > 1 for a period time.
       // Or else if dbd reference count = 0, the new svn_repos_open
       // will call create_env again, which will hide the bug.
     // This sleep make thread 0 execute first to reach conditional wait status.
     pool = svn_pool_create(gpool);
     svn_error_t *svn_err__temp = svn_repos_open(&repos, repos_path, pool);
     if (svn_err__temp)
         printf("There are some errors happened when trying to open repos.\n");
         return NULL;
     secondPool = pool;

     rc = pthread_cond_signal(&gcond.dataPresentCondition);

     pthread_cond_wait(&gcond.cond2, &gcond.dataMutex);
     pool = svn_pool_create(gpool);
     svn_repos_open(&repos, repos_path, pool);

   return NULL;

int main(int argc, char *argv[])
   pthread_t threads[NUMTHREADS];
   pthread_attr_t attr;
   int i;
   int param[NUMTHREADS];

   if (argc != 2)
       fprintf(stderr, "usage: %s repos_path\n", argv[0]);
       return 1;

   repos_path = argv[1];

   gpool = svn_pool_create(NULL);

   for (i = 0; i < NUMTHREADS; ++i)
     param[i] = i;
     pthread_create(&threads[i], &attr, worker, param + i);

   for (i = 0; i < NUMTHREADS; i++)
     pthread_join(threads[i], NULL);

   return 0;

Received on 2008-12-08 22:58:06 CET

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