Skip to content

Commit 6309faa

Browse files
committed
MDEV-38410 segfault in std::function
Segfault from the standard library… only memory corruption can explain it. I have uncertain suspicions.
1 parent 37c1873 commit 6309faa

File tree

3 files changed

+24
-13
lines changed

3 files changed

+24
-13
lines changed

sql/rpl_info_file.h

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,6 @@ struct Info_file
209209
*/
210210
struct Mem_fn: std::function<Persistent &(Info_file *self)>
211211
{
212-
using List= const std::initializer_list<const Mem_fn>;
213212
/// Null Constructor
214213
Mem_fn(std::nullptr_t null= nullptr):
215214
std::function<Persistent &(Info_file *)>(null) {}
@@ -242,13 +241,19 @@ struct Info_file
242241
(either contains a `.` or is entirely empty) rather than an integer.
243242
@return `false` if the file has parsed successfully or `true` if error
244243
*/
245-
bool load_from_file(Mem_fn::List value_list, size_t default_line_count)
244+
template<size_t size> bool load_from_file(
245+
const Mem_fn (&value_list)[size],
246+
size_t default_line_count= 0
247+
) { return load_from_file(value_list, size, default_line_count); }
248+
private:
249+
bool
250+
load_from_file(const Mem_fn *values, size_t size, size_t default_line_count)
246251
{
247252
/**
248253
The first row is temporarily stored in the first value. If it is a line
249254
count and not a log name (new format), the second row will overwrite it.
250255
*/
251-
auto &line1= dynamic_cast<String_value<> &>((*(value_list.begin()))(this));
256+
auto &line1= dynamic_cast<String_value<> &>(values[0](this));
252257
if (line1.load_from(&file))
253258
return true;
254259
size_t line_count;
@@ -269,9 +274,9 @@ struct Info_file
269274
for (; i < line_count; ++i)
270275
{
271276
int c;
272-
if (i < value_list.size()) // line known in the `value_list`
277+
if (i < size) // line known in the `value_list`
273278
{
274-
const Mem_fn &pm= value_list.begin()[i];
279+
const Mem_fn &pm= values[i];
275280
if (pm)
276281
{
277282
if (pm(this).load_from(&file))
@@ -293,6 +298,7 @@ struct Info_file
293298
}
294299
return false;
295300
}
301+
protected:
296302

297303
/**
298304
Flush the MySQL line-based section to the @ref file
@@ -304,9 +310,14 @@ struct Info_file
304310
This reservation provides compatibility with MySQL,
305311
who has added more old-style lines while MariaDB innovated.
306312
*/
307-
void save_to_file(Mem_fn::List value_list, size_t total_line_count)
313+
template<size_t size> void save_to_file(
314+
const Mem_fn (&value_list)[size],
315+
size_t total_line_count= size + /* line count line */ 1
316+
) { return save_to_file(value_list, size, total_line_count); }
317+
private:
318+
void save_to_file(const Mem_fn *values, size_t size, size_t total_line_count)
308319
{
309-
DBUG_ASSERT(total_line_count > value_list.size());
320+
DBUG_ASSERT(total_line_count > size);
310321
my_b_seek(&file, 0);
311322
/*
312323
If the new contents take less space than the previous file contents,
@@ -316,8 +327,9 @@ struct Info_file
316327
*/
317328
Int_IO_CACHE::to_chars(&file, total_line_count);
318329
my_b_write_byte(&file, '\n');
319-
for (const Mem_fn &pm: value_list)
330+
for (size_t i= 0; i < size; ++i)
320331
{
332+
const Mem_fn &pm= values[i];
321333
if (pm)
322334
pm(this).save_to(&file);
323335
my_b_write_byte(&file, '\n');
@@ -327,7 +339,7 @@ struct Info_file
327339
(1 for the line count line + line count) inclusive -> max line inclusive
328340
= line count exclusive <- max line inclusive
329341
*/
330-
for (; total_line_count > value_list.size(); --total_line_count)
342+
for (; total_line_count > size; --total_line_count)
331343
my_b_write_byte(&file, '\n');
332344
}
333345

sql/rpl_master_info_file.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,7 @@ struct Master_info_file: Info_file
552552
/// }@
553553

554554

555-
inline static Mem_fn::List VALUE_LIST= {
555+
inline static const Mem_fn VALUE_LIST[] {
556556
&Master_info_file::master_log_file,
557557
&Master_info_file::master_log_pos,
558558
&Master_info_file::master_host,

sql/rpl_relay_log_info_file.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ struct Relay_log_info_file: Info_file
3636
Int_value<uint32_t> sql_delay;
3737
/// }@
3838

39-
inline static const Mem_fn::List VALUE_LIST= {
39+
inline static const Mem_fn VALUE_LIST[] {
4040
&Relay_log_info_file::relay_log_file,
4141
&Relay_log_info_file::relay_log_pos,
4242
&Relay_log_info_file::read_master_log_file,
@@ -50,8 +50,7 @@ struct Relay_log_info_file: Info_file
5050
}
5151
void save_to_file() override
5252
{
53-
return Info_file::save_to_file(VALUE_LIST,
54-
VALUE_LIST.size() + /* line count line */ 1);
53+
return Info_file::save_to_file(VALUE_LIST);
5554
}
5655
};
5756

0 commit comments

Comments
 (0)