maria-developers team mailing list archive
-
maria-developers team
-
Mailing list archive
-
Message #12071
778e96749bc: MDEV-20923:UBSAN: member access within address … which does not point to an object of type 'xid_count_per_binlog'
revision-id: 778e96749bcadc5528bb7f214a711272f7413b96 (mariadb-10.1.43-66-g778e96749bc)
parent(s): 982294ac1680938ac9223fb64a64e21f0cbc322a
author: Sujatha
committer: Sujatha
timestamp: 2020-01-23 16:17:55 +0530
message:
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.
---
sql/log.cc | 27 +++++++++++----------------
sql/log.h | 13 ++++++++++++-
2 files changed, 23 insertions(+), 17 deletions(-)
diff --git a/sql/log.cc b/sql/log.cc
index acf1f8f8a9c..0efef6d1e29 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -3216,7 +3216,7 @@ void MYSQL_BIN_LOG::cleanup()
DBUG_ASSERT(!binlog_xid_count_list.head());
WSREP_XID_LIST_ENTRY("MYSQL_BIN_LOG::cleanup(): Removing xid_list_entry "
"for %s (%lu)", b);
- my_free(b);
+ delete b;
}
mysql_mutex_destroy(&LOCK_log);
@@ -3580,17 +3580,9 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
*/
uint off= dirname_length(log_file_name);
uint len= strlen(log_file_name) - off;
- char *entry_mem, *name_mem;
- if (!(new_xid_list_entry = (xid_count_per_binlog *)
- my_multi_malloc(MYF(MY_WME),
- &entry_mem, sizeof(xid_count_per_binlog),
- &name_mem, len,
- NULL)))
+ new_xid_list_entry= new xid_count_per_binlog(log_file_name+off, (int)len);
+ if (!new_xid_list_entry)
goto err;
- memcpy(name_mem, log_file_name+off, len);
- new_xid_list_entry->binlog_name= name_mem;
- new_xid_list_entry->binlog_name_len= len;
- new_xid_list_entry->xid_count= 0;
/*
Find the name for the Initial binlog checkpoint.
@@ -3607,7 +3599,10 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
mysql_mutex_unlock(&LOCK_xid_list);
if (!b)
b= new_xid_list_entry;
- strmake(buf, b->binlog_name, b->binlog_name_len);
+ if (b->binlog_name)
+ strmake(buf, b->binlog_name, b->binlog_name_len);
+ else
+ goto err;
Binlog_checkpoint_log_event ev(buf, len);
DBUG_EXECUTE_IF("crash_before_write_checkpoint_event",
flush_io_cache(&log_file);
@@ -3711,7 +3706,7 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
{
WSREP_XID_LIST_ENTRY("MYSQL_BIN_LOG::open(): Removing xid_list_entry for "
"%s (%lu)", b);
- my_free(binlog_xid_count_list.get());
+ delete binlog_xid_count_list.get();
}
mysql_cond_broadcast(&COND_xid_list);
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. \
To turn it on again: fix the cause, \
shutdown the MySQL server and restart it.", name, errno);
if (new_xid_list_entry)
- my_free(new_xid_list_entry);
+ delete new_xid_list_entry;
if (file >= 0)
mysql_file_close(file, MYF(0));
close(LOG_CLOSE_INDEX);
@@ -4252,7 +4247,7 @@ bool MYSQL_BIN_LOG::reset_logs(THD *thd, bool create_new_log,
DBUG_ASSERT(b->xid_count == 0);
WSREP_XID_LIST_ENTRY("MYSQL_BIN_LOG::reset_logs(): Removing "
"xid_list_entry for %s (%lu)", b);
- my_free(binlog_xid_count_list.get());
+ delete binlog_xid_count_list.get();
}
mysql_cond_broadcast(&COND_xid_list);
reset_master_pending--;
@@ -9736,7 +9731,7 @@ TC_LOG_BINLOG::mark_xid_done(ulong binlog_id, bool write_checkpoint)
break;
WSREP_XID_LIST_ENTRY("TC_LOG_BINLOG::mark_xid_done(): Removing "
"xid_list_entry for %s (%lu)", b);
- my_free(binlog_xid_count_list.get());
+ delete binlog_xid_count_list.get();
}
mysql_mutex_unlock(&LOCK_xid_list);
diff --git a/sql/log.h b/sql/log.h
index b4c9b24a3a9..277e5c6f69c 100644
--- a/sql/log.h
+++ b/sql/log.h
@@ -587,7 +587,18 @@ class MYSQL_BIN_LOG: public TC_LOG, private MYSQL_LOG
long xid_count;
/* For linking in requests to the binlog background thread. */
xid_count_per_binlog *next_in_queue;
- xid_count_per_binlog(); /* Give link error if constructor used. */
+ xid_count_per_binlog(char *log_file_name, uint log_file_name_len)
+ :binlog_id(0), xid_count(0)
+ {
+ binlog_name_len= log_file_name_len;
+ binlog_name= (char *) my_malloc(binlog_name_len, MYF(MY_ZEROFILL));
+ if (binlog_name)
+ memcpy(binlog_name, log_file_name, binlog_name_len);
+ }
+ ~xid_count_per_binlog()
+ {
+ my_free(binlog_name);
+ }
};
I_List<xid_count_per_binlog> binlog_xid_count_list;
mysql_mutex_t LOCK_binlog_background_thread;