guile-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 6/12] Guile-DBI: Fix crash, avoid recursive free


From: Linas Vepstas
Subject: [PATCH 6/12] Guile-DBI: Fix crash, avoid recursive free
Date: Fri, 19 Sep 2008 09:11:45 -0500
User-agent: Mutt/1.5.15+20070412 (2007-04-11)


There is a particularly nasty crash scenario invloving the 
garbage collector. The problem is that the dbi free routine
calls the dbi close routine, which tries to alloc new SCM
nodes. This is bad, because one should not alloc while 
the garbage collector is running. So add a flag, incidating
that a free is in progress. 

The DBD layers will have to honour this flag.

(also fixes one more mem leak).

Signed-off-by: Linas Vepstas <address@hidden>

---
 include/guile-dbi/guile-dbi.h |    1 +
 src/guile-dbi.c               |   14 ++++++++++++--
 2 files changed, 13 insertions(+), 2 deletions(-)

Index: guile-dbi-2.0.0/include/guile-dbi/guile-dbi.h
===================================================================
--- guile-dbi-2.0.0.orig/include/guile-dbi/guile-dbi.h  2008-09-16 
21:36:22.000000000 -0500
+++ guile-dbi-2.0.0/include/guile-dbi/guile-dbi.h       2008-09-16 
21:40:30.000000000 -0500
@@ -34,6 +34,7 @@ typedef struct g_db_handle
   SCM closed;  /* boolean, TRUE if closed otherwise FALSE */
   void* handle;
   void* db_info;
+  int in_free;
 } gdbi_db_handle_t;
 /* end guile smob struct */
 
Index: guile-dbi-2.0.0/src/guile-dbi.c
===================================================================
--- guile-dbi-2.0.0.orig/src/guile-dbi.c        2008-09-16 21:40:24.000000000 
-0500
+++ guile-dbi-2.0.0/src/guile-dbi.c     2008-09-16 21:40:30.000000000 -0500
@@ -53,6 +53,8 @@ SCM_DEFINE (make_g_db_handle, "dbi-open"
   g_db_handle->bcknd   = bcknd;
   g_db_handle->constr  = conn_string;
   g_db_handle->handle  = NULL;
+  g_db_handle->closed  = SCM_BOOL_T;
+  g_db_handle->in_free = 0;
   g_db_handle->db_info = NULL;
 
   bcknd_str = scm_to_locale_string (bcknd);
@@ -189,6 +191,9 @@ free_db_handle (SCM g_db_handle_smob)
   struct g_db_handle *g_db_handle = NULL;
 
   g_db_handle = (struct g_db_handle*)SCM_SMOB_DATA(g_db_handle_smob);
+  if (g_db_handle->in_free) return 0;
+  g_db_handle->in_free = 1;
+
   close_g_db_handle(g_db_handle_smob);
 
   if (g_db_handle != NULL)
@@ -325,7 +330,8 @@ __gdbi_dbd_wrap(gdbi_db_handle_t* dbh, c
                  20))) == NULL)
     {
       free(bcknd);
-      dbh->status = (SCM) scm_cons(scm_from_int(errno),
+      if (dbh->in_free) return; /* do not SCM anything while in GC */
+      dbh->status = scm_cons(scm_from_int(errno),
                                   scm_makfrom0str(strerror(errno)));
       return;
     }
@@ -335,6 +341,8 @@ __gdbi_dbd_wrap(gdbi_db_handle_t* dbh, c
   if((ret = dlerror()) != NULL)
     {
       free(bcknd);
+      free(func);
+      if (dbh->in_free) return; /* do not SCM anything while in GC */
       dbh->status = (SCM) scm_cons(scm_from_int(1),
                                   scm_makfrom0str(ret));
       return;
@@ -345,8 +353,10 @@ __gdbi_dbd_wrap(gdbi_db_handle_t* dbh, c
     {
       free(bcknd);
     }
+
+  if (dbh->in_free) return; /* do not SCM anything while in GC */
   /* todo: error msg to be translated */
-  dbh->status = (SCM) scm_cons(scm_from_int(0),
+  dbh->status = scm_cons(scm_from_int(0),
                           scm_makfrom0str("symbol loaded"));
   return;
 }

Attachment: signature.asc
Description: Digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]