[augeas-devel] [PATCH 2/2] Fix segfault with bug_on

Francis Giraldeau francis.giraldeau at gmail.com
Thu Dec 29 20:51:01 UTC 2011


The function exn_error returns a static struct value and writing to this data
causes a segmentation fault. This patch prevents updating the static value by
adding a bool is_static field. The error can be triggered by compiling with
--enable-debug and using environment variable AUGEAS_DEBUG=bug_on
---
 src/ref.h    |    2 +-
 src/syntax.c |    6 +++++-
 src/syntax.h |    1 +
 3 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/src/ref.h b/src/ref.h
index 3314741..dfc7864 100644
--- a/src/ref.h
+++ b/src/ref.h
@@ -59,8 +59,8 @@ int ref_make_ref(void *ptrptr, size_t size, size_t ref_ofs);
                 /*memset(s, 255, sizeof(*s));*/                         \
                 free_##t(s);                                            \
             }                                                           \
+            (s) = NULL;                                                 \
         }                                                               \
-        (s) = NULL;                                                     \
     } while(0)
 
 /* Make VAR uncollectable and pin it in memory for eternity */
diff --git a/src/syntax.c b/src/syntax.c
index 320d588..85510d7 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -409,6 +409,8 @@ struct value *make_exn_value(struct info *info,
 
 void exn_add_lines(struct value *v, int nlines, ...) {
     assert(v->tag == V_EXN);
+    if (v->is_static)
+        return;
 
     va_list ap;
     if (REALLOC_N(v->exn->lines, v->exn->nlines + nlines) == -1)
@@ -442,6 +444,7 @@ struct value *exn_error(void) {
     static const struct value value = {
         .ref = REF_MAX, /* Protect against being freed */
         .info = NULL, .tag = V_EXN,
+        .is_static = 1,
         { .exn = (struct exn *) &exn } };
     return (struct value *) &value;
 }
@@ -1583,7 +1586,8 @@ static struct value *apply(struct term *app, struct ctx *ctx) {
     bind_param(&lctx.local, f->func->param, arg);
     result = compile_exp(app->info, f->func->body, &lctx);
     unref(result->info, info);
-    result->info = ref(app->info);
+    if (!result->is_static)
+        result->info = ref(app->info);
     unbind_param(&lctx.local, f->func->param);
 
  done:
diff --git a/src/syntax.h b/src/syntax.h
index 4c517de..7dd2142 100644
--- a/src/syntax.h
+++ b/src/syntax.h
@@ -155,6 +155,7 @@ struct value {
     unsigned int   ref;
     struct info   *info;
     enum value_tag tag;
+    bool is_static;
     /* Nothing in this union for V_UNIT */
     union {
         struct string  *string;  /* V_STRING */
-- 
1.7.5.4




More information about the augeas-devel mailing list