Bug #26021 valgrind warning handle_trailing_share/ndbcluster_free_share invalid read
Submitted: 1 Feb 2007 17:07 Modified: 8 Feb 2007 7:48
Reporter: Tomas Ulin Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Cluster: Cluster (NDB) storage engine Severity:S3 (Non-critical)
Version:5.1 OS:
Assigned to: Tomas Ulin CPU Architecture:Any

[1 Feb 2007 17:07] Tomas Ulin
Description:
VALGRIND: 'Invalid read of size 4'
    COUNT: 2
    FUNCTION: ndbcluster_free_share(st_ndbcluster_share**,    FILES:    master.err
    TESTS:    ndb_binlog_discover
    STACK: at 0x719715: ndbcluster_free_share(st_ndbcluster_share**, bool) (ha_ndbcluster.cc:7710)
             by 0x71A9AB: ha_ndbcluster::close() (ha_ndbcluster_binlog.h:208)
             by 0x665CBA: closefrm(st_table*, bool) (table.cc:1639)
             by 0x65FCEB: intern_close_table(st_table*) (sql_base.cc:760)
             by 0x65FD87: free_cache_entry(st_table*) (sql_base.cc:779)
             by 0x9B2E34: hash_delete (hash.c:519)
             by 0x658B4B: close_thread_table(THD*, st_table**) (sql_base.cc:1144)
             by 0x65B52B: close_thread_tables(THD*, bool, bool) (sql_base.cc:1100)
             by 0x69A595: Prepared_statement::cleanup_stmt() (sql_prepare.cc:2754)
             by 0x69CD5B: Prepared_statement::prepare(char const*, unsigned) (sql_prepare.cc:2879)
             by 0x69DBA0: mysql_stmt_prepare(THD*, char const*, unsigned) (sql_prepare.cc:1907)
             by 0x637037: dispatch_command(enum_server_command, THD*, char*, unsigned) (sql_parse.cc:1831)
             by 0x637D3C: do_command(THD*) (sql_parse.cc:1626)
             by 0x63897C: handle_one_connection (sql_parse.cc:1232)
             by 0x4D44192: start_thread (in /lib64/libpthread-2.4.so)
             by 0x52B745C: clone (in /lib64/libc-2.4.so)
           Address 0x6AE5C38 is 424 bytes inside a block of size 560 free'd
             at 0x4A2046E: free (vg_replace_malloc.c:233)
             by 0x9A960A: my_no_flags_free (my_malloc.c:59)
             by 0x714681: ndbcluster_real_free_share(st_ndbcluster_share**) (ha_ndbcluster.cc:7696)
             by 0x719ACC: handle_trailing_share(st_ndbcluster_share*) (ha_ndbcluster_binlog.h:213)
             by 0x7437EA: ndbcluster_create_binlog_setup(Ndb*, char const*, unsigned, char const*, char const*, char) (ha_ndbcluster_binlog.cc:2414)
             by 0x72F734: ndbcluster_find_all_files(THD*) (ha_ndbcluster.cc:6375)
             by 0x73E8D6: ndbcluster_setup_binlog_table_shares(THD*) (ha_ndbcluster_binlog.cc:851)
             by 0x72D43A: ndb_util_thread_func (ha_ndbcluster.cc:8479)
             by 0x4D44192: start_thread (in /lib64/libpthread-2.4.so)
             by 0x52B745C: clone (in /lib64/libc-2.4.so)

VALGRIND: 'Invalid read of size 8'
    COUNT: 1
    FUNCTION: ndbcluster_free_share(st_ndbcluster_share**,    FILES:    master.err
    TESTS:    ndb_binlog_discover
    STACK: at 0x7196FC: ndbcluster_free_share(st_ndbcluster_share**, bool) (ha_ndbcluster.cc:7708)
             by 0x71A9AB: ha_ndbcluster::close() (ha_ndbcluster_binlog.h:208)
             by 0x665CBA: closefrm(st_table*, bool) (table.cc:1639)
             by 0x65FCEB: intern_close_table(st_table*) (sql_base.cc:760)
             by 0x65FD87: free_cache_entry(st_table*) (sql_base.cc:779)
             by 0x9B2E34: hash_delete (hash.c:519)
             by 0x658B4B: close_thread_table(THD*, st_table**) (sql_base.cc:1144)
             by 0x65B52B: close_thread_tables(THD*, bool, bool) (sql_base.cc:1100)
             by 0x69A595: Prepared_statement::cleanup_stmt() (sql_prepare.cc:2754)
             by 0x69CD5B: Prepared_statement::prepare(char const*, unsigned) (sql_prepare.cc:2879)
             by 0x69DBA0: mysql_stmt_prepare(THD*, char const*, unsigned) (sql_prepare.cc:1907)
             by 0x637037: dispatch_command(enum_server_command, THD*, char*, unsigned) (sql_parse.cc:1831)
             by 0x637D3C: do_command(THD*) (sql_parse.cc:1626)
             by 0x63897C: handle_one_connection (sql_parse.cc:1232)
             by 0x4D44192: start_thread (in /lib64/libpthread-2.4.so)
             by 0x52B745C: clone (in /lib64/libc-2.4.so)
           Address 0x6AE5C30 is 416 bytes inside a block of size 560 free'd
             at 0x4A2046E: free (vg_replace_malloc.c:233)
             by 0x9A960A: my_no_flags_free (my_malloc.c:59)
             by 0x714681: ndbcluster_real_free_share(st_ndbcluster_share**) (ha_ndbcluster.cc:7696)
             by 0x719ACC: handle_trailing_share(st_ndbcluster_share*) (ha_ndbcluster_binlog.h:213)
             by 0x7437EA: ndbcluster_create_binlog_setup(Ndb*, char const*, unsigned, char const*, char const*, char) (ha_ndbcluster_binlog.cc:2414)
             by 0x72F734: ndbcluster_find_all_files(THD*) (ha_ndbcluster.cc:6375)
             by 0x73E8D6: ndbcluster_setup_binlog_table_shares(THD*) (ha_ndbcluster_binlog.cc:851)
             by 0x72D43A: ndb_util_thread_func (ha_ndbcluster.cc:8479)
             by 0x4D44192: start_thread (in /lib64/libpthread-2.4.so)
             by 0x52B745C: clone (in /lib64/libc-2.4.so)

How to repeat:
happens occationally on pb valgrind
[5 Feb 2007 3:55] Tomas Ulin
===== sql/ha_ndbcluster.cc 1.397 vs edited =====
--- 1.397/sql/ha_ndbcluster.cc	2007-01-25 04:48:06 +07:00
+++ edited/sql/ha_ndbcluster.cc	2007-02-05 10:20:33 +07:00
@@ -6837,7 +6837,7 @@
       fprintf(stderr, "NDB: table share %s with use_count %d not freed\n",
               share->key, share->use_count);
 #endif
-      real_free_share(&share);
+      ndbcluster_real_free_share(&share);
     }
     pthread_mutex_unlock(&ndbcluster_mutex);
   }
@@ -7449,14 +7449,20 @@
   bzero((char*) &table_list,sizeof(table_list));
   table_list.db= share->db;
   table_list.alias= table_list.table_name= share->table_name;
-  close_cached_tables(thd, 0, &table_list, TRUE);
+  safe_mutex_assert_owner(&LOCK_open);
+  close_cached_tables(thd, 1 /* if_wait_for_refresh */, &table_list, TRUE);
 
   pthread_mutex_lock(&ndbcluster_mutex);
   if (!--share->use_count)
   {
-    DBUG_PRINT("info", ("NDB_SHARE: close_cashed_tables %s freed share.",
-               share->key)); 
-    real_free_share(&share);
+    if (ndb_extra_logging)
+      sql_print_information("NDB_SHARE: trailing share %s(connect_count: %u) "
+                            "released by close_cached_tables at "
+                            "connect_count: %u",
+                            share->key,
+                            share->connect_count,
+                            g_ndb_cluster_connection->get_connect_count());
+    ndbcluster_real_free_share(&share);
     DBUG_RETURN(0);
   }
 
@@ -7466,10 +7472,14 @@
   */
   if (share->state != NSS_DROPPED && !--share->use_count)
   {
-    DBUG_PRINT("info", ("NDB_SHARE: %s already exists, "
-                        "use_count=%d  state != NSS_DROPPED.",
-                        share->key, share->use_count)); 
-    real_free_share(&share);
+    if (ndb_extra_logging)
+      sql_print_information("NDB_SHARE: trailing share %s(connect_count: %u) "
+                            "released after NSS_DROPPED check "
+                            "at connect_count: %u",
+                            share->key,
+                            share->connect_count,
+                            g_ndb_cluster_connection->get_connect_count());
+    ndbcluster_real_free_share(&share);
     DBUG_RETURN(0);
   }
   DBUG_PRINT("error", ("NDB_SHARE: %s already exists  use_count=%d.",
@@ -7736,7 +7746,7 @@
     (*share)->util_lock= 0;
   if (!--(*share)->use_count)
   {
-    real_free_share(share);
+    ndbcluster_real_free_share(share);
   }
   else
   {
===== sql/ha_ndbcluster.h 1.165 vs edited =====
--- 1.165/sql/ha_ndbcluster.h	2007-01-23 20:27:13 +07:00
+++ edited/sql/ha_ndbcluster.h	2007-02-05 10:02:06 +07:00
@@ -108,6 +108,7 @@
   char *table_name;
   Ndb::TupleIdRange tuple_id_range;
 #ifdef HAVE_NDB_BINLOG
+  uint32 connect_count;
   uint32 flags;
   NdbEventOperation *op;
   NdbEventOperation *op_old; // for rename table
===== sql/ha_ndbcluster_binlog.cc 1.95 vs edited =====
--- 1.95/sql/ha_ndbcluster_binlog.cc	2006-12-31 07:04:56 +07:00
+++ edited/sql/ha_ndbcluster_binlog.cc	2007-02-05 10:39:27 +07:00
@@ -361,6 +362,8 @@
   int do_event_op= ndb_binlog_running;
   DBUG_ENTER("ndbcluster_binlog_init_share");
 
+  share->connect_count= g_ndb_cluster_connection->get_connect_count();
+
   share->op= 0;
   share->table= 0;
 
@@ -604,8 +607,8 @@
                    ("table->s->db.table_name: %s.%s",
                     share->table->s->db.str, share->table->s->table_name.str));
       if (share->state != NSS_DROPPED && !--share->use_count)
-        real_free_share(&share);
+        ndbcluster_real_free_share(&share);
       else
       {
         DBUG_PRINT("share",
@@ -2411,12 +2445,21 @@
       pthread_mutex_unlock(&ndbcluster_mutex);
       DBUG_RETURN(1);
     }
-    handle_trailing_share(share);
+    if (share->connect_count != 
+        g_ndb_cluster_connection->get_connect_count())
+    {
+      handle_trailing_share(share);
+      share= NULL;
+    }
   }
 
   /* Create share which is needed to hold replication information */
-  if (!(share= get_share(key, 0, TRUE, TRUE)))
+  if (share)
+  {
+    ++share->use_count;
+  }
+  else if (!(share= get_share(key, 0, TRUE, TRUE)))
   {
     sql_print_error("NDB Binlog: "
                     "allocating table share for %s failed", key);
===== sql/ha_ndbcluster_binlog.h 1.21 vs edited =====
--- 1.21/sql/ha_ndbcluster_binlog.h	2006-12-24 02:33:28 +07:00
+++ edited/sql/ha_ndbcluster_binlog.h	2007-02-04 20:16:13 +07:00
@@ -208,12 +208,7 @@
   ndbcluster_free_share(share, have_lock);
 }
 
-inline void real_free_share(NDB_SHARE **share)
-{
-  ndbcluster_real_free_share(share);
-}
-
 inline
 Thd_ndb *
 get_thd_ndb(THD *thd) { return (Thd_ndb *) thd->ha_data[ndbcluster_hton->slot]; }
[5 Feb 2007 6:56] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/19312
[5 Feb 2007 17:13] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/19330
[6 Feb 2007 7:20] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/19362
[7 Feb 2007 16:52] Tomas Ulin
pushed to 5.1.16
[8 Feb 2007 7:48] Jon Stephens
Thank you for your bug report. This issue has been committed to our source repository of that product and will be incorporated into the next release.

If necessary, you can access the source repository and build the latest available version, including the bug fix. More information about accessing the source trees is available at

    http://dev.mysql.com/doc/en/installing-source.html

No change visible to users; closed without further action.