Changeset: 361512dd2813 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=361512dd2813
Added Files:
        sql/test/BugTracker-2019/Tests/double-free.Bug-6757.sql
        sql/test/BugTracker-2019/Tests/double-free.Bug-6757.stable.err
        sql/test/BugTracker-2019/Tests/double-free.Bug-6757.stable.out
Modified Files:
        gdk/gdk_bbp.c
        gdk/gdk_heap.c
        gdk/gdk_interprocess.c
        gdk/gdk_storage.c
        sql/backends/monet5/UDF/pyapi/pyapi.c
        sql/server/rel_optimizer.c
        sql/server/rel_semantic.c
        sql/storage/store.c
        sql/test/BugTracker-2019/Tests/All
        sql/test/BugTracker-2019/Tests/cte-union.Bug-6755.stable.err
        sql/test/BugTracker-2019/Tests/cte-union.Bug-6755.stable.out
        
sql/test/BugTracker-2019/Tests/sequence-first-next-value.Bug-6743.stable.out
        sql/test/subquery/Tests/subquery2.sql
        sql/test/testdb-reload/Tests/reload.py
        testing/process.py
        tools/merovingian/daemon/controlrunner.c
Branch: grouping-analytics
Log Message:

Merge with default branch


diffs (truncated from 2417 to 300 lines):

diff --git a/gdk/gdk_bbp.c b/gdk/gdk_bbp.c
--- a/gdk/gdk_bbp.c
+++ b/gdk/gdk_bbp.c
@@ -1737,7 +1737,7 @@ BBPdir_subcommit(int cnt, bat *subcommit
                assert(subcommit[n - 1] < subcommit[n]);
 #endif
 
-       if ((nbbpf = GDKfilelocate(0, "BBP", "w", "dir")) == NULL)
+       if ((nbbpf = GDKfilelocate(0, "BBP", "wx", "dir")) == NULL)
                return GDK_FAIL;
 
        n = (bat) ATOMIC_GET(&BBPsize);
@@ -1849,7 +1849,7 @@ BBPdir(int cnt, bat *subcommit)
                return BBPdir_subcommit(cnt, subcommit);
 
        IODEBUG fprintf(stderr, "#BBPdir: writing BBP.dir (%d bats).\n", (int) 
(bat) ATOMIC_GET(&BBPsize));
-       if ((fp = GDKfilelocate(0, "BBP", "w", "dir")) == NULL) {
+       if ((fp = GDKfilelocate(0, "BBP", "wx", "dir")) == NULL) {
                goto bailout;
        }
 
diff --git a/gdk/gdk_heap.c b/gdk/gdk_heap.c
--- a/gdk/gdk_heap.c
+++ b/gdk/gdk_heap.c
@@ -61,7 +61,7 @@ HEAPcreatefile(int farmid, size_t *maxsz
                fn = path;
        }
        /* round up to mulitple of GDK_mmap_pagesize */
-       fd = GDKfdlocate(NOFARM, fn, "wb", NULL);
+       fd = GDKfdlocate(NOFARM, fn, "wxb", NULL);
        if (fd >= 0) {
                close(fd);
                base = GDKload(NOFARM, fn, NULL, *maxsz, maxsz, STORE_MMAP);
@@ -119,36 +119,12 @@ HEAPalloc(Heap *h, size_t nitems, size_t
        }
        if (!GDKinmemory() && h->base == NULL) {
                char *nme;
-               struct stat st;
 
-               if(!(nme = GDKfilepath(h->farmid, BATDIR, h->filename, NULL))) {
-                       GDKerror("HEAPalloc: malloc failure");
+               nme = GDKfilepath(h->farmid, BATDIR, h->filename, NULL);
+               if (nme == NULL)
                        return GDK_FAIL;
-               }
-               if (stat(nme, &st) < 0) {
-                       h->storage = STORE_MMAP;
-                       h->base = HEAPcreatefile(NOFARM, &h->size, nme);
-               } else {
-                       int fd;
-
-                       fd = GDKfdlocate(NOFARM, nme, "wb", NULL);
-                       if (fd >= 0) {
-                               char of[sizeof(h->filename)];
-                               char *ext;
-                               close(fd);
-                               strncpy(of, h->filename, sizeof(of));
-#ifdef STATIC_CODE_ANALYSIS
-                               /* help coverity */
-                               of[sizeof(h->filename) - 1] = 0;
-#endif
-                               ext = decompose_filename(of);
-                               h->newstorage = STORE_MMAP;
-                               if (HEAPload(h, of, ext, false) != GDK_SUCCEED)
-                                       h->base = NULL; /* superfluous */
-                               /* success checked by looking at
-                                * h->base below */
-                       }
-               }
+               h->storage = STORE_MMAP;
+               h->base = HEAPcreatefile(NOFARM, &h->size, nme);
                GDKfree(nme);
        }
        if (h->base == NULL) {
@@ -270,6 +246,7 @@ HEAPextend(Heap *h, size_t size, bool ma
                                        HEAPfree(&bak, false);
                                        return GDK_SUCCEED;
                                }
+                               GDKclrerr();
                        }
                        fd = GDKfdlocate(h->farmid, nme, "wb", ext);
                        if (fd >= 0) {
@@ -445,7 +422,7 @@ GDKupgradevarheap(BAT *b, var_t v, bool 
                const char *base = b->theap.base;
 
                /* first save heap in file with extra .tmp extension */
-               if ((fd = GDKfdlocate(b->theap.farmid, b->theap.filename, "wb", 
"tmp")) < 0)
+               if ((fd = GDKfdlocate(b->theap.farmid, b->theap.filename, 
"wxb", "tmp")) < 0)
                        return GDK_FAIL;
                while (size > 0) {
                        ret = write(fd, base, (unsigned) MIN(1 << 30, size));
diff --git a/gdk/gdk_interprocess.c b/gdk/gdk_interprocess.c
--- a/gdk/gdk_interprocess.c
+++ b/gdk/gdk_interprocess.c
@@ -28,7 +28,7 @@
 #include <sys/sem.h>
 #include <time.h>
 
-static size_t interprocess_unique_id = 1;
+static ATOMIC_TYPE interprocess_unique_id = ATOMIC_VAR_INIT(1);
 static key_t base_key = 800000000;
 
 // Regular ftok produces too many collisions
@@ -46,12 +46,7 @@ ftok_enhanced(int id, key_t * return_key
 size_t
 GDKuniqueid(size_t offset)
 {
-       // TODO: lock this here instead of in pyapi
-       size_t id;
-
-       id = interprocess_unique_id;
-       interprocess_unique_id += offset;
-       return id;
+       return (size_t) ATOMIC_ADD(&interprocess_unique_id, (ATOMIC_BASE_TYPE) 
offset);
 }
 
 //! Create a memory mapped file if it does not exist and open it
@@ -75,19 +70,21 @@ GDKinitmmap(size_t id, size_t size, size
         size = (maxsize + GDK_mmap_pagesize - 1) & ~(GDK_mmap_pagesize - 1);
         if (size == 0)
         size = GDK_mmap_pagesize; */
-       fd = GDKfdlocate(0, address, "wb", "tmp");
-       if (fd < 0) {
-               return NULL;
-       }
        path = GDKfilepath(0, BATDIR, address, "tmp");
        if (path == NULL) {
                return NULL;
        }
-       close(fd);
-       if (GDKextend(path, size) != GDK_SUCCEED) {
+       fd = GDKfdlocate(NOFARM, path, "wb", NULL);
+       if (fd < 0) {
                GDKfree(path);
                return NULL;
        }
+       if (GDKextendf(fd, size, path) != GDK_SUCCEED) {
+               close(fd);
+               GDKfree(path);
+               return NULL;
+       }
+       close(fd);
        ptr = GDKmmap(path, mod, size);
        GDKfree(path);
        if (ptr == NULL) {
diff --git a/gdk/gdk_storage.c b/gdk/gdk_storage.c
--- a/gdk/gdk_storage.c
+++ b/gdk/gdk_storage.c
@@ -194,7 +194,7 @@ int
 GDKfdlocate(int farmid, const char *nme, const char *mode, const char 
*extension)
 {
        char *path = NULL;
-       int fd, flags = 0;
+       int fd, flags = O_CLOEXEC;
 
        assert(!GDKinmemory());
        if (nme == NULL || *nme == 0)
@@ -212,12 +212,14 @@ GDKfdlocate(int farmid, const char *nme,
                mode++;
 #ifdef _CYGNUS_H_
        } else {
-               flags = _FRDSEQ;        /* WIN32 
CreateFile(FILE_FLAG_SEQUENTIAL_SCAN) */
+               flags |= _FRDSEQ;       /* WIN32 
CreateFile(FILE_FLAG_SEQUENTIAL_SCAN) */
 #endif
        }
 
        if (strchr(mode, 'w')) {
                flags |= O_WRONLY | O_CREAT;
+               if (strchr(mode, 'x'))
+                       flags |= O_EXCL;
        } else if (!strchr(mode, '+')) {
                flags |= O_RDONLY;
        } else {
@@ -226,11 +228,11 @@ GDKfdlocate(int farmid, const char *nme,
 #ifdef WIN32
        flags |= strchr(mode, 'b') ? O_BINARY : O_TEXT;
 #endif
-       fd = open(nme, flags | O_CLOEXEC, MONETDB_MODE);
+       fd = open(nme, flags, MONETDB_MODE);
        if (fd < 0 && *mode == 'w') {
                /* try to create the directory, in case that was the problem */
                if (GDKcreatedir(nme) == GDK_SUCCEED) {
-                       fd = open(nme, flags | O_CLOEXEC, MONETDB_MODE);
+                       fd = open(nme, flags, MONETDB_MODE);
                        if (fd < 0)
                                GDKsyserror("GDKfdlocate: cannot open file 
%s\n", nme);
                }
@@ -584,10 +586,12 @@ GDKload(int farmid, const char *nme, con
                        nme = path;
                }
                if (nme != NULL && GDKextend(nme, size) == GDK_SUCCEED) {
-                       int mod = MMAP_READ | MMAP_WRITE | MMAP_SEQUENTIAL | 
MMAP_SYNC;
+                       int mod = MMAP_READ | MMAP_WRITE | MMAP_SEQUENTIAL;
 
                        if (mode == STORE_PRIV)
                                mod |= MMAP_COPY;
+                       else
+                               mod |= MMAP_SYNC;
                        ret = GDKmmap(nme, mod, size);
                        if (ret != NULL) {
                                /* success: update allocated size */
diff --git a/sql/backends/monet5/UDF/pyapi/pyapi.c 
b/sql/backends/monet5/UDF/pyapi/pyapi.c
--- a/sql/backends/monet5/UDF/pyapi/pyapi.c
+++ b/sql/backends/monet5/UDF/pyapi/pyapi.c
@@ -329,9 +329,7 @@ static str PyAPIeval(Client cntxt, MalBl
                int mmap_count = 4 + pci->retc * 2;
 
                // create initial shared memory
-               MT_lock_set(&pyapiLock);
                mmap_id = GDKuniqueid(mmap_count);
-               MT_lock_unset(&pyapiLock);
 
                mmap_ptrs = GDKzalloc(mmap_count * sizeof(void *));
                mmap_sizes = GDKzalloc(mmap_count * sizeof(size_t));
diff --git a/sql/server/rel_semantic.c b/sql/server/rel_semantic.c
--- a/sql/server/rel_semantic.c
+++ b/sql/server/rel_semantic.c
@@ -88,6 +88,8 @@ rel_parse(mvc *m, sql_schema *s, char *q
        bstream_destroy(m->scanner.rs);
 
        m->sym = NULL;
+       o.vars = m->vars;       /* may have been realloc'ed */
+       o.sizevars = m->sizevars;
        if (m->session->status || m->errstr[0]) {
                int status = m->session->status;
                char errstr[ERRSIZE];
diff --git a/sql/storage/store.c b/sql/storage/store.c
--- a/sql/storage/store.c
+++ b/sql/storage/store.c
@@ -2122,13 +2122,16 @@ flusher_should_run(void)
 {
        // We will flush if we have a reason to and no reason not to.
        char *reason_to = NULL, *reason_not_to = NULL;
+       int changes;
 
        if (flusher.countdown_ms <= 0)
                reason_to = "timer expired";
 
        int many_changes = GDKdebug & FORCEMITOMASK ? 100 : 1000000;
-       if (logger_funcs.changes() >= many_changes)
+       if ((changes = logger_funcs.changes()) >= many_changes)
                reason_to = "many changes";
+       else if (changes == 0)
+               reason_not_to = "no changes";
 
        // Read and clear flush_now. If we decide not to flush
        // we'll put it back.
diff --git a/sql/test/BugTracker-2019/Tests/All 
b/sql/test/BugTracker-2019/Tests/All
--- a/sql/test/BugTracker-2019/Tests/All
+++ b/sql/test/BugTracker-2019/Tests/All
@@ -33,4 +33,5 @@ alter_table_drop_column.Bug-6749
 HAVE_PYMONETDB?remote-table-non-existent-column.Bug-6750
 cte-union.Bug-6755
 merge-table-limit.Bug-6756
+double-free.Bug-6757
 HAVE_LIBPY3?python-loader-string.Bug-6759
diff --git a/sql/test/BugTracker-2019/Tests/double-free.Bug-6757.sql 
b/sql/test/BugTracker-2019/Tests/double-free.Bug-6757.sql
new file mode 100644
--- /dev/null
+++ b/sql/test/BugTracker-2019/Tests/double-free.Bug-6757.sql
@@ -0,0 +1,976 @@
+start transaction;
+
+CREATE TABLE "sys"."params_str" (
+       "paramname" CHARACTER LARGE OBJECT,
+       "value"     CHARACTER LARGE OBJECT,
+       "prob"      DOUBLE
+);
+CREATE TABLE "sys"."bm_0_obj_dict" (
+       "id"    INTEGER       NOT NULL,
+       "idstr" CHARACTER LARGE OBJECT NOT NULL,
+       "prob"  FLOAT(51)     NOT NULL,
+       CONSTRAINT "bm_0_obj_dict_id_pkey" PRIMARY KEY ("id"),
+       CONSTRAINT "bm_0_obj_dict_idstr_unique" UNIQUE ("idstr")
+);
+CREATE TABLE "sys"."bm_0_obj_type" (
+       "id"      INTEGER       NOT NULL,
+       "type"    INTEGER       NOT NULL,
+       "typestr" CHARACTER LARGE OBJECT NOT NULL,
+       "prob"    DOUBLE        NOT NULL,
+       CONSTRAINT "bm_0_obj_type_id_fkey" FOREIGN KEY ("id") REFERENCES 
"sys"."bm_0_obj_dict" ("id"),
+       CONSTRAINT "bm_0_obj_type_type_fkey" FOREIGN KEY ("type") REFERENCES 
"sys"."bm_0_obj_dict" ("id")
+);
+CREATE TABLE "sys"."tr_0_obj_dict" (
+       "id"    INTEGER       NOT NULL,
+       "idstr" CHARACTER LARGE OBJECT NOT NULL,
+       "prob"  FLOAT(51)     NOT NULL,
+       CONSTRAINT "tr_0_obj_dict_id_pkey" PRIMARY KEY ("id"),
+       CONSTRAINT "tr_0_obj_dict_idstr_unique" UNIQUE ("idstr")
+);
+CREATE TABLE "sys"."tr_0_obj_type" (
+       "id"      INTEGER       NOT NULL,
+       "type"    INTEGER       NOT NULL,
+       "typestr" CHARACTER LARGE OBJECT NOT NULL,
+       "prob"    DOUBLE        NOT NULL,
+       CONSTRAINT "tr_0_obj_type_id_fkey" FOREIGN KEY ("id") REFERENCES 
"sys"."tr_0_obj_dict" ("id"),
+       CONSTRAINT "tr_0_obj_type_type_fkey" FOREIGN KEY ("type") REFERENCES 
"sys"."tr_0_obj_dict" ("id")
+);
+
+CREATE TABLE "sys"."_cachedrel_4" (
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to