Commit bd5f334b authored by knielsen@mysql.com's avatar knielsen@mysql.com

BUG#20549: Fix missing memory initialization.

Some values were not initialized, causing Valgrind errors (and potential
random bugs):

 - NDB binlog thread thd->variables.pseudo_thread_id.
 - Table null bits.
 - Field bytes for columns with NULL values.
parent 1b7fe109
...@@ -311,8 +311,10 @@ ndbcluster_binlog_open_table(THD *thd, NDB_SHARE *share, ...@@ -311,8 +311,10 @@ ndbcluster_binlog_open_table(THD *thd, NDB_SHARE *share,
if (!reopen) if (!reopen)
{ {
// allocate memory on ndb share so it can be reused after online alter table // allocate memory on ndb share so it can be reused after online alter table
share->record[0]= (byte*) alloc_root(&share->mem_root, table->s->rec_buff_length); (void)multi_alloc_root(&share->mem_root,
share->record[1]= (byte*) alloc_root(&share->mem_root, table->s->rec_buff_length); &(share->record[0]), table->s->rec_buff_length,
&(share->record[1]), table->s->rec_buff_length,
NULL);
} }
{ {
my_ptrdiff_t row_offset= share->record[0] - table->record[0]; my_ptrdiff_t row_offset= share->record[0] - table->record[0];
...@@ -2159,6 +2161,9 @@ int ndb_add_binlog_index(THD *thd, void *_row) ...@@ -2159,6 +2161,9 @@ int ndb_add_binlog_index(THD *thd, void *_row)
break; break;
} }
// Set all fields non-null.
if(binlog_index->s->null_bytes > 0)
bzero(binlog_index->record[0], binlog_index->s->null_bytes);
binlog_index->field[0]->store(row.master_log_pos); binlog_index->field[0]->store(row.master_log_pos);
binlog_index->field[1]->store(row.master_log_file, binlog_index->field[1]->store(row.master_log_file,
strlen(row.master_log_file), strlen(row.master_log_file),
...@@ -3275,6 +3280,13 @@ pthread_handler_t ndb_binlog_thread_func(void *arg) ...@@ -3275,6 +3280,13 @@ pthread_handler_t ndb_binlog_thread_func(void *arg)
thd= new THD; /* note that contructor of THD uses DBUG_ */ thd= new THD; /* note that contructor of THD uses DBUG_ */
THD_CHECK_SENTRY(thd); THD_CHECK_SENTRY(thd);
/* We need to set thd->thread_id before thd->store_globals, or it will
set an invalid value for thd->variables.pseudo_thread_id.
*/
pthread_mutex_lock(&LOCK_thread_count);
thd->thread_id= thread_id++;
pthread_mutex_unlock(&LOCK_thread_count);
thd->thread_stack= (char*) &thd; /* remember where our stack is */ thd->thread_stack= (char*) &thd; /* remember where our stack is */
if (thd->store_globals()) if (thd->store_globals())
{ {
...@@ -3307,7 +3319,6 @@ pthread_handler_t ndb_binlog_thread_func(void *arg) ...@@ -3307,7 +3319,6 @@ pthread_handler_t ndb_binlog_thread_func(void *arg)
pthread_detach_this_thread(); pthread_detach_this_thread();
thd->real_id= pthread_self(); thd->real_id= pthread_self();
pthread_mutex_lock(&LOCK_thread_count); pthread_mutex_lock(&LOCK_thread_count);
thd->thread_id= thread_id++;
threads.append(thd); threads.append(thd);
pthread_mutex_unlock(&LOCK_thread_count); pthread_mutex_unlock(&LOCK_thread_count);
thd->lex->start_transaction_opt= 0; thd->lex->start_transaction_opt= 0;
...@@ -3641,6 +3652,10 @@ pthread_handler_t ndb_binlog_thread_func(void *arg) ...@@ -3641,6 +3652,10 @@ pthread_handler_t ndb_binlog_thread_func(void *arg)
injector::transaction::table tbl(table, TRUE); injector::transaction::table tbl(table, TRUE);
int ret= trans.use_table(::server_id, tbl); int ret= trans.use_table(::server_id, tbl);
DBUG_ASSERT(ret == 0); DBUG_ASSERT(ret == 0);
// Set all fields non-null.
if(table->s->null_bytes > 0)
bzero(table->record[0], table->s->null_bytes);
table->field[0]->store((longlong)::server_id); table->field[0]->store((longlong)::server_id);
table->field[1]->store((longlong)gci); table->field[1]->store((longlong)gci);
trans.write_row(::server_id, trans.write_row(::server_id,
......
...@@ -2475,15 +2475,19 @@ my_size_t THD::pack_row(TABLE *table, MY_BITMAP const* cols, byte *row_data, ...@@ -2475,15 +2475,19 @@ my_size_t THD::pack_row(TABLE *table, MY_BITMAP const* cols, byte *row_data,
int n_null_bytes= table->s->null_bytes; int n_null_bytes= table->s->null_bytes;
byte *ptr; byte *ptr;
uint i; uint i;
my_ptrdiff_t const offset= (my_ptrdiff_t) (record - (byte*) my_ptrdiff_t const rec_offset= record - table->record[0];
table->record[0]); my_ptrdiff_t const def_offset= table->s->default_values - table->record[0];
memcpy(row_data, record, n_null_bytes); memcpy(row_data, record, n_null_bytes);
ptr= row_data+n_null_bytes; ptr= row_data+n_null_bytes;
for (i= 0 ; (field= *p_field) ; i++, p_field++) for (i= 0 ; (field= *p_field) ; i++, p_field++)
{ {
if (bitmap_is_set(cols,i)) if (bitmap_is_set(cols,i))
{
my_ptrdiff_t const offset=
field->is_null(rec_offset) ? def_offset : rec_offset;
ptr= (byte*)field->pack((char *) ptr, field->ptr + offset); ptr= (byte*)field->pack((char *) ptr, field->ptr + offset);
}
} }
return (static_cast<my_size_t>(ptr - row_data)); return (static_cast<my_size_t>(ptr - row_data));
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment