accre / lstore

LStore - A fault-tolerant, performant distributed data storage framework.
http://www.lstore.org
Apache License 2.0
4 stars 5 forks source link

Segfault in lio_ls #107

Closed PerilousApricot closed 8 years ago

PerilousApricot commented 8 years ago

Against ef08ece51b8b8d798f3fbbf7d4c057fb5669d785:

./src/lio/lio_ls --help
ASAN:SIGSEGV
=================================================================
==77915==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000068 (pc 0x7fff920c0c5f bp 0x7fff51a43150 sp 0x7fff51a43150 T0)
    #0 0x7fff920c0c5e in flockfile (/usr/lib/system/libsystem_c.dylib+0x3bc5e)
    #1 0x7fff920c41cd in getdelim (/usr/lib/system/libsystem_c.dylib+0x3f1cd)
    #2 0x10ef3c3ce in lio_find_lfs_mounts lio_config.c:271
    #3 0x10ef4b88d in lio_init lio_config.c:1393
    #4 0x10e1bf065 in main lio_ls.c:152
    #5 0x7fff915415c8 in start (/usr/lib/system/libdyld.dylib+0x35c8)
    #6 0x1  (<unknown module>)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV ??:0 flockfile
==77915==ABORTING
Abort trap: 6
PerilousApricot commented 8 years ago

fixing one minor error in lio_find_lfs_mounts leads to another error in lio_init where lio_gc is silently set to NULL.

Output

[mi=196 tid=0 file=:153 fn=main] Fatal Error in main at /Users/meloam/projects/lstore/src/lio/bin/lio_ls.c:153

Change:

diff --git a/src/lio/bin/lio_ls.c b/src/lio/bin/lio_ls.c
index 364676c..0c50b13 100644
--- a/src/lio/bin/lio_ls.c
+++ b/src/lio/bin/lio_ls.c
@@ -150,6 +150,7 @@ int main(int argc, char **argv)
     }

     lio_init(&argc, &argv);
+    FATAL_UNLESS(lio_gc != NULL);

     //*** Parse the args
     rp_single = ro_single = NULL;
diff --git a/src/lio/lio_config.c b/src/lio/lio_config.c
index 8eb1302..0fc83f7 100644
--- a/src/lio/lio_config.c
+++ b/src/lio/lio_config.c
@@ -267,28 +267,28 @@ void lio_find_lfs_mounts()
     stack = tbx_stack_new();

     fd = fopen("/proc/mounts", "r");
-    text = NULL;
-    while (getline(&text, &ns, fd) != -1) {
-        log_printf(5, "getline=%s", text);
-        if (strncmp(text, "lfs:", 4) == 0) { //** Found a match
-            tbx_stk_string_token(text, " ", &bstate, &fin);
-            prefix = tbx_stk_string_token(NULL, " ", &bstate, &fin);
-            if (prefix != NULL) { //** Add it
-                tbx_type_malloc_clear(entry, lfs_mount_t, 1);
-                entry->prefix = strdup(prefix);
-                entry->len = strlen(entry->prefix);
-                tbx_stack_push(stack, entry);
-                log_printf(5, "mount prefix=%s len=%d\n", entry->prefix, entry->len);
+    if (fd) {
+        text = NULL;
+        while (getline(&text, &ns, fd) != -1) {
+            log_printf(5, "getline=%s", text);
+            if (strncmp(text, "lfs:", 4) == 0) { //** Found a match
+                tbx_stk_string_token(text, " ", &bstate, &fin);
+                prefix = tbx_stk_string_token(NULL, " ", &bstate, &fin);
+                if (prefix != NULL) { //** Add it
+                    tbx_type_malloc_clear(entry, lfs_mount_t, 1);
+                    entry->prefix = strdup(prefix);
+                    entry->len = strlen(entry->prefix);
+                    tbx_stack_push(stack, entry);
+                    log_printf(5, "mount prefix=%s len=%d\n", entry->prefix, entry->len);
+                }
             }
-        }

-        free(text);
-        text = NULL;
+            free(text);
+            text = NULL;
+        }
+        if (text != NULL)
+            free(text);  //** Getline() always returns something
     }
-    if (fd != NULL) fclose(fd);
-
-    if (text != NULL) free(text);  //** Getline() always returns something
-
     //** Convert it to a simple array
     _lfs_mount_count = tbx_stack_count(stack);
     tbx_type_malloc(lfs_mount, lfs_mount_t, _lfs_mount_count);
PerilousApricot commented 8 years ago

Oh, turns out, the error handling ... doesn't work. And then the logging doesn't work on top of it.

    if (cfg_name != NULL) { 
        tbx_mlog_load(cfg_name, out_override, ll_override);
        lio_gc = lio_create(cfg_name, section_name, userid, name);
        lio_gc->ref_cnt = 1;
        if (auto_mode != -1) lio_gc->auto_translate = auto_mode;
    } else {
        log_printf(0, "Error missing config file!\n");
    }

But that log_printf() doesn't hit the console unless you change the log level to -1 on it...