Jan Lindström <jplindst@xxxxxxxxxxx> 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.