Skip to content

Commit d89bb88

Browse files
committed
MDEV-20923:UBSAN: member access within address … which does not point to an object of type 'xid_count_per_binlog'
Problem: ------- Accessing a member within 'xid_count_per_binlog' structure results in following error when 'UBSAN' is enabled. member access within address 0xXXX which does not point to an object of type 'xid_count_per_binlog' Analysis: --------- The problem appears to be that no constructor for 'xid_count_per_binlog' is being called, and thus the vtable will not be initialized. Fix: --- Defined a parameterized constructor for 'xid_count_per_binlog' class.
1 parent 5271d43 commit d89bb88

File tree

2 files changed

+23
-17
lines changed

2 files changed

+23
-17
lines changed

sql/log.cc

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3216,7 +3216,7 @@ void MYSQL_BIN_LOG::cleanup()
32163216
DBUG_ASSERT(!binlog_xid_count_list.head());
32173217
WSREP_XID_LIST_ENTRY("MYSQL_BIN_LOG::cleanup(): Removing xid_list_entry "
32183218
"for %s (%lu)", b);
3219-
my_free(b);
3219+
delete b;
32203220
}
32213221

32223222
mysql_mutex_destroy(&LOCK_log);
@@ -3580,17 +3580,9 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
35803580
*/
35813581
uint off= dirname_length(log_file_name);
35823582
uint len= strlen(log_file_name) - off;
3583-
char *entry_mem, *name_mem;
3584-
if (!(new_xid_list_entry = (xid_count_per_binlog *)
3585-
my_multi_malloc(MYF(MY_WME),
3586-
&entry_mem, sizeof(xid_count_per_binlog),
3587-
&name_mem, len,
3588-
NULL)))
3583+
new_xid_list_entry= new xid_count_per_binlog(log_file_name+off, (int)len);
3584+
if (!new_xid_list_entry)
35893585
goto err;
3590-
memcpy(name_mem, log_file_name+off, len);
3591-
new_xid_list_entry->binlog_name= name_mem;
3592-
new_xid_list_entry->binlog_name_len= len;
3593-
new_xid_list_entry->xid_count= 0;
35943586

35953587
/*
35963588
Find the name for the Initial binlog checkpoint.
@@ -3607,7 +3599,10 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
36073599
mysql_mutex_unlock(&LOCK_xid_list);
36083600
if (!b)
36093601
b= new_xid_list_entry;
3610-
strmake(buf, b->binlog_name, b->binlog_name_len);
3602+
if (b->binlog_name)
3603+
strmake(buf, b->binlog_name, b->binlog_name_len);
3604+
else
3605+
goto err;
36113606
Binlog_checkpoint_log_event ev(buf, len);
36123607
DBUG_EXECUTE_IF("crash_before_write_checkpoint_event",
36133608
flush_io_cache(&log_file);
@@ -3711,7 +3706,7 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
37113706
{
37123707
WSREP_XID_LIST_ENTRY("MYSQL_BIN_LOG::open(): Removing xid_list_entry for "
37133708
"%s (%lu)", b);
3714-
my_free(binlog_xid_count_list.get());
3709+
delete binlog_xid_count_list.get();
37153710
}
37163711
mysql_cond_broadcast(&COND_xid_list);
37173712
WSREP_XID_LIST_ENTRY("MYSQL_BIN_LOG::open(): Adding new xid_list_entry for "
@@ -3758,7 +3753,7 @@ Turning logging off for the whole duration of the MySQL server process. \
37583753
To turn it on again: fix the cause, \
37593754
shutdown the MySQL server and restart it.", name, errno);
37603755
if (new_xid_list_entry)
3761-
my_free(new_xid_list_entry);
3756+
delete new_xid_list_entry;
37623757
if (file >= 0)
37633758
mysql_file_close(file, MYF(0));
37643759
close(LOG_CLOSE_INDEX);
@@ -4252,7 +4247,7 @@ bool MYSQL_BIN_LOG::reset_logs(THD *thd, bool create_new_log,
42524247
DBUG_ASSERT(b->xid_count == 0);
42534248
WSREP_XID_LIST_ENTRY("MYSQL_BIN_LOG::reset_logs(): Removing "
42544249
"xid_list_entry for %s (%lu)", b);
4255-
my_free(binlog_xid_count_list.get());
4250+
delete binlog_xid_count_list.get();
42564251
}
42574252
mysql_cond_broadcast(&COND_xid_list);
42584253
reset_master_pending--;
@@ -9736,7 +9731,7 @@ TC_LOG_BINLOG::mark_xid_done(ulong binlog_id, bool write_checkpoint)
97369731
break;
97379732
WSREP_XID_LIST_ENTRY("TC_LOG_BINLOG::mark_xid_done(): Removing "
97389733
"xid_list_entry for %s (%lu)", b);
9739-
my_free(binlog_xid_count_list.get());
9734+
delete binlog_xid_count_list.get();
97409735
}
97419736

97429737
mysql_mutex_unlock(&LOCK_xid_list);

sql/log.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -587,7 +587,18 @@ class MYSQL_BIN_LOG: public TC_LOG, private MYSQL_LOG
587587
long xid_count;
588588
/* For linking in requests to the binlog background thread. */
589589
xid_count_per_binlog *next_in_queue;
590-
xid_count_per_binlog(); /* Give link error if constructor used. */
590+
xid_count_per_binlog(char *log_file_name, uint log_file_name_len)
591+
:binlog_id(0), xid_count(0)
592+
{
593+
binlog_name_len= log_file_name_len;
594+
binlog_name= (char *) my_malloc(binlog_name_len, MYF(MY_ZEROFILL));
595+
if (binlog_name)
596+
memcpy(binlog_name, log_file_name, binlog_name_len);
597+
}
598+
~xid_count_per_binlog()
599+
{
600+
my_free(binlog_name);
601+
}
591602
};
592603
I_List<xid_count_per_binlog> binlog_xid_count_list;
593604
mysql_mutex_t LOCK_binlog_background_thread;

0 commit comments

Comments
 (0)