On 6/29/11 3:36 AM, Ralf Hildebrandt wrote:

but, if clamav hung on the primary (like it has done twice since
upgrading to 0.97.1),
Ah, it's happening to you as well? Happened here twice or three times
already :(

I have attached a patch, for freebsd, cd ../ports/security/clamav/files
put this attached patch there (its against clamav 0.97.1)

it should remove this:

<http://git.clamav.net/gitweb?p=clamav-devel.git;a=commitdiff;h=bbfe830c935837cfc357541cb307a7b863394abb;hp=d9ff9e65080d7c70de722e174d365d3b2cb312d3>

see if that helps.


amavisd just seems to sit there till I totally kill clamd with a
sigsegv.
Yeah, same here.



--
Michael Scheidell, CTO
o: 561-999-5000
d: 561-948-2259
>*| *SECNAP Network Security Corporation

   * Best Mobile Solutions Product of 2011
   * Best Intrusion Prevention Product
   * Hot Company Finalist 2011
   * Best Email Security Product
   * Certified SNORT Integrator


______________________________________________________________________
This email has been scanned and certified safe by SpammerTrap(r). For Information please see http://www.secnap.com/products/spammertrap/
______________________________________________________________________  
--- libclamav/c++/bytecode2llvm.cpp.orig        2011-05-13 07:25:31.000000000 
-0400
+++ libclamav/c++/bytecode2llvm.cpp     2011-06-29 09:32:09.000000000 -0400
@@ -1874,119 +1874,30 @@
 INITIALIZE_PASS_END(RuntimeLimits, "rl" ,"Runtime Limits", false, false)
 #endif
 
-static pthread_mutex_t watchdog_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_cond_t watchdog_cond = PTHREAD_COND_INITIALIZER;
-static int watchdog_running = 0;
-
-struct watchdog_item {
+struct bc_watchdog {
     volatile uint8_t* timeout;
-    struct timespec abstimeout;
-    struct watchdog_item *next;
+    struct timespec * abstimeout;
+    pthread_mutex_t   mutex;
+    pthread_cond_t    cond;
+    int finished;
 };
 
-static struct watchdog_item* watchdog_head = NULL;
-static struct watchdog_item* watchdog_tail = NULL;
-
-#define WATCHDOG_IDLE 10
 static void *bytecode_watchdog(void *arg)
 {
-    struct timeval tv;
-    struct timespec out;
-
-    pthread_mutex_lock(&watchdog_mutex);
-    watchdog_running = 1;
-    if (cli_debug_flag)
-       cli_dbgmsg_internal("bytecode watchdog is running\n");
-    do {
-       struct watchdog_item *item;
-       gettimeofday(&tv, NULL);
-       out.tv_sec = tv.tv_sec + WATCHDOG_IDLE;
-       out.tv_nsec = tv.tv_usec*1000;
-       /* wait for some work, up to WATCHDOG_IDLE time */
-       while (watchdog_head == NULL &&
-              pthread_cond_timedwait(&watchdog_cond, &watchdog_mutex,
-                                     &out) != ETIMEDOUT) {}
-       if (watchdog_head == NULL)
-           break;
-       /* wait till timeout is reached on this item */
-       item = watchdog_head;
-       while (item == watchdog_head &&
-              pthread_cond_timedwait(&watchdog_cond, &watchdog_mutex,
-                                     &item->abstimeout) != ETIMEDOUT) {}
-       if (item != watchdog_head)
-           continue;/* got removed meanwhile */
-       /* timeout reached, signal it to bytecode */
-       *item->timeout = 1;
+    int ret = 0;
+    struct bc_watchdog *w = (struct bc_watchdog*)arg;
+    pthread_mutex_lock(&w->mutex);
+    while (!w->finished && ret != ETIMEDOUT) {
+       ret = pthread_cond_timedwait(&w->cond, &w->mutex, w->abstimeout);
+    }
+    pthread_mutex_unlock(&w->mutex);
+    if (ret == ETIMEDOUT) {
+       *w->timeout = 1;
        cli_warnmsg("[Bytecode JIT]: Bytecode run timed out, timeout flag 
set\n");
-       watchdog_head = item->next;
-       if (!watchdog_head)
-           watchdog_tail = NULL;
-    } while (1);
-    watchdog_running = 0;
-    if (cli_debug_flag)
-       cli_dbgmsg_internal("bytecode watchdog quiting\n");
-    pthread_mutex_unlock(&watchdog_mutex);
+    }
     return NULL;
 }
 
-extern "C" const char *cli_strerror(int errnum, char* buf, size_t len);
-static void watchdog_disarm(struct watchdog_item *item)
-{
-    struct watchdog_item *q, *p = NULL;
-    if (!item)
-       return;
-    pthread_mutex_lock(&watchdog_mutex);
-    for (q=watchdog_head;q && q != item;p = q, q = q->next) {}
-    if (q == item) {
-       if (p)
-           p->next = q->next;
-       if (q == watchdog_head)
-           watchdog_head = q->next;
-       if (q == watchdog_tail)
-           watchdog_tail = p;
-    }
-    pthread_mutex_unlock(&watchdog_mutex);
-}
-
-static int watchdog_arm(struct watchdog_item *item, int ms, volatile uint8_t 
*timeout)
-{
-    int rc = 0;
-    struct timeval tv0;
-
-    *timeout = 0;
-    item->timeout = timeout;
-    item->next = NULL;
-
-    gettimeofday(&tv0, NULL);
-    tv0.tv_usec += ms * 1000;
-    item->abstimeout.tv_sec = tv0.tv_sec + tv0.tv_usec/1000000;
-    item->abstimeout.tv_nsec = (tv0.tv_usec%1000000)*1000;
-
-    pthread_mutex_lock(&watchdog_mutex);
-    if (!watchdog_running) {
-       pthread_t thread;
-       pthread_attr_t attr;
-       pthread_attr_init(&attr);
-       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-
-       if ((rc = pthread_create(&thread, &attr, bytecode_watchdog, NULL))) {
-           char buf[256];
-           cli_errmsg("(watchdog) pthread_create failed: %s\n", 
cli_strerror(rc, buf, sizeof(buf)));
-       }
-       pthread_attr_destroy(&attr);
-    }
-    if (!rc) {
-       if (watchdog_tail)
-           watchdog_tail->next = item;
-       watchdog_tail = item;
-       if (!watchdog_head)
-           watchdog_head = item;
-    }
-    pthread_cond_signal(&watchdog_cond);
-    pthread_mutex_unlock(&watchdog_mutex);
-    return rc;
-}
-
 static int bytecode_execute(intptr_t code, struct cli_bc_ctx *ctx)
 {
     ScopedExceptionHandler handler;
@@ -2002,12 +1913,15 @@
     return CL_EBYTECODE;
 }
 
+extern "C" const char *cli_strerror(int errnum, char* buf, size_t len);
 int cli_vm_execute_jit(const struct cli_all_bc *bcs, struct cli_bc_ctx *ctx,
                       const struct cli_bc_func *func)
 {
+    char buf[1024];
     int ret;
+    pthread_t thread;
     struct timeval tv0, tv1;
-    struct watchdog_item witem;
+    uint32_t timeoutus;
     // no locks needed here, since LLVM automatically acquires a JIT lock
     // if needed.
     void *code = bcs->engine->compiledFunctions[func];
@@ -2018,20 +1932,40 @@
                        func->numArgs);
        return CL_EBYTECODE;
     }
-    if (cli_debug_flag)
        gettimeofday(&tv0, NULL);
+    struct timespec abstime;
+
+    timeoutus = (ctx->bytecode_timeout%1000)*1000 + tv0.tv_usec;
+    abstime.tv_sec = tv0.tv_sec + ctx->bytecode_timeout/1000 + 
timeoutus/1000000;
+    abstime.tv_nsec = 1000*(timeoutus%1000000);
+    ctx->timeout = 0;
+
+    struct bc_watchdog w = {
+       &ctx->timeout,
+       &abstime,
+       PTHREAD_MUTEX_INITIALIZER,
+       PTHREAD_COND_INITIALIZER,
+       0
+    };
 
     if (ctx->bytecode_timeout) {
        /* only spawn if timeout is set.
         * we don't set timeout for selfcheck (see bb #2235) */
-       if (watchdog_arm(&witem, ctx->bytecode_timeout, &ctx->timeout))
+       if ((ret = pthread_create(&thread, NULL, bytecode_watchdog, &w))) {
+           cli_warnmsg("[Bytecode JIT]: Bytecode: failed to create new thread 
:%s!\n",
+                       cli_strerror(ret, buf, sizeof(buf)));
            return CL_EBYTECODE;
     }
+    }
 
     ret = bytecode_execute((intptr_t)code, ctx);
-
-    if (ctx->bytecode_timeout)
-       watchdog_disarm(&witem);
+    pthread_mutex_lock(&w.mutex);
+    w.finished = 1;
+    pthread_cond_signal(&w.cond);
+    pthread_mutex_unlock(&w.mutex);
+    if (ctx->bytecode_timeout) {
+       pthread_join(thread, NULL);
+    }
 
     if (cli_debug_flag) {
        long diff;

Reply via email to