Jan Lindström <jplindst@mariadb.org> writes:
The point I do not understant is at ha_savepoint
we have again:
if ((err= ht->savepoint_set(ht, thd, (uchar *)(sv+1)+ht->savepoint_offset)))
(gdb) p *sv $3 = {prev = 0xa5a5a5a5a5a5a5a5, name = 0x7f505c007390 "A", length = 1, ha_list = 0xa5a5a5a5a5a5a5a5, mdl_savepoint = {m_stmt_ticket = 0xa5a5a5a5a5a5a5a5, m_trans_ticket = 0xa5a5a5a5a5a5a5a5}} (gdb) p *(sv+1) $2 = {prev = 0xa5a5a5a5a5a5a5a5, name = 0xa5a5a5a5a5a5a5a5 <Address 0xa5a5a5a5a5a5a5a5 out of bounds>, length = 2779096485, ha_list = 0xa5a5a5a5a5a5a5a5, mdl_savepoint = {m_stmt_ticket = 0xa5a5a5a5a5a5a5a5, m_trans_ticket = 0xa5a5a5a5a5a5a5a5}}
Again access to unitialized memory, sv is ok but sv+1 not
Note that it is not "sv+1". It is ((uchar *)sv+1) + ht->savepoint_offset. I suppose that sv points to a memory block containing first a SAVEPOINT object, and after that some extra bytes allocated per storage engine. Then when SAVEPOINT is executed, we call into each storage engine ht->savepoint_set() to ask it to execute the savepoint and store engine-specific data in the allocated extra bytes at (uchar *)(sv+1)+ht->savepoint_offset. And later when ROLLBACK TO SAVEPOINT is executed, we ask the engine to execute the (partial) rollback using whatever values it put into (uchar *)(sv+1)+ht->savepoint_offset itself before. So it is normal that the data is unitialised in ha_savepoint() - because this is where we are calling into each engine to initialise it. But the bug is that the WSREP patch disables this initialisation. So that when we get to ha_rollback_to_savepoint(), the binlog code gets uninitialised data. If you are wondering about the 0xa5a5a5a5a5a5a5a5 in *sv, isn't the most likely that those fields are just not used anywhere in the code? Disclaimer: This is the first time I'm looking at this code, but it seems clear enough ... - Kristian.