← Back to team overview

maria-developers team mailing list archive

Valgrind failure in Buildbot

 

Hi Sergey,

We briefly discussed the new valgrind error in buildbot after your push on
IRC:

https://buildbot.askmonty.org/buildbot/builders/work-amd64-valgrind/builds/6282/steps/test/logs/stdio

==13161== Conditional jump or move depends on uninitialised value(s)
==13161==    at 0x4C280AA: memcpy (mc_replace_strmem.c:115)
==13161==    by 0x723F6B: Field_varstring::get_key_image(unsigned char*, unsigned int, Field::imagetype) (field.cc:6932)
==13161==    by 0x818D5B: key_copy(unsigned char*, unsigned char*, st_key*, unsigned int, bool) (key.cc:146)
==13161==    by 0x6DD6FE: Mrr_ordered_index_reader::interrupt_read() (multi_range_read.cc:448)
==13161==    by 0x6DE605: Mrr_ordered_rndpos_reader::refill_from_index_reader() (multi_range_read.cc:688)
==13161==    by 0x6DE7D2: Mrr_ordered_rndpos_reader::refill_buffer(bool) (multi_range_read.cc:618)
==13161==    by 0x6DFB27: DsMrr_impl::dsmrr_init(handler*, st_range_seq_if*, void*, unsigned int, unsigned int, st_handler_buffer*) (multi_range_read.cc:966)
==13161==    by 0x91AAE9: ha_innobase::multi_range_read_init(st_range_seq_if*, void*, unsigned int, unsigned int, st_handler_buffer*) (ha_innodb.cc:13961)
==13161==    by 0x6DA60A: JOIN_TAB_SCAN_MRR::open() (sql_join_cache.cc:3867)
==13161==    by 0x6D7363: JOIN_CACHE::join_matching_records(bool) (sql_join_cache.cc:2249)
==13161==    by 0x6D5647: JOIN_CACHE::join_records(bool) (sql_join_cache.cc:2086)
==13161==    by 0x5F8259: sub_select_cache(JOIN*, st_join_table*, bool) (sql_select.cc:16717)
==13161==    by 0x6D71BA: JOIN_CACHE::generate_full_extensions(unsigned char*) (sql_join_cache.cc:2397)
==13161==    by 0x6D74E6: JOIN_CACHE::join_matching_records(bool) (sql_join_cache.cc:2289)
==13161==    by 0x6D5647: JOIN_CACHE::join_records(bool) (sql_join_cache.cc:2086)
==13161==    by 0x5F8219: sub_select_cache(JOIN*, st_join_table*, bool) (sql_select.cc:16697)

I took a quick look. The problem seems to be that the code is copying out the
fields of a key from table->record[0] (key_copy()), however, the first length
byte of the value is uninitialised.

I think it's the field col_varchar_key in the table, testcase is appended below.

I checked a bit back up the callstack. The field col_varchar_key is reported
as uninitialised already at the start of
Mrr_ordered_rndpos_reader::refill_from_index_reader(), but I'm not really
familiar with when and how table->record[0] is supposed to be initialised
during multi-range read.

As you said on IRC, your recent patch is related to interrupt_read(), so
probably best if you take a look and see if you can figure out something.

Incidentally, I noticed something that looks wrong in

  key_copy(to_key, from_record, key_info, key_length, with_zerofill)

The comments say that the key is copied from `from_record', however actually
the function only works if the from_record passed in is table->record[0] (or
more precisely, the same record as is installed in
key_info->key_part->field). Because it checks the null bit in from_record, but
copies the data from table->record[0]. However, this is not the problem in
this particular failure (as in this case from_record == table->record[0]),
just struck me as something that could easily cause surprises later...

Below is a reduced test case that triggers the valgrind error.
It did not trigger for me with a debug build, but _did_ trigger (in 5.5) with
this build command:

  EXTRA_FLAGS="-O3 -fno-omit-frame-pointer -Wno-uninitialized" AM_EXTRA_MAKEFLAGS="VERBOSE=1" BUILD/compile-amd64-valgrind-max

 - Kristian.

-----------------------------------------------------------------------
-- source include/have_xtradb.inc

set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
CREATE TABLE t1 (
  pk int(11) NOT NULL AUTO_INCREMENT,
  col_int_key int(11) NOT NULL,
  col_varchar_key varchar(1) NOT NULL,
  col_varchar_nokey varchar(1) NOT NULL,
  PRIMARY KEY (pk),
  KEY col_int_key (col_int_key),
  KEY col_varchar_key (col_varchar_key,col_int_key)
) ENGINE=InnoDB;
INSERT INTO t1 VALUES 
  (10,8,'v','v'),
  (11,8,'f','f'),
  (12,5,'v','v'),
  (13,8,'s','s'),
  (14,8,'a','a'),
  (15,6,'p','p'),
  (16,7,'z','z'),
  (17,2,'a','a'),
  (18,5,'h','h'),
  (19,7,'h','h'),
  (20,2,'v','v'),
  (21,9,'v','v'),
  (22,142,'b','b'),
  (23,3,'y','y'),
  (24,0,'v','v'),
  (25,3,'m','m'),
  (26,5,'z','z'),
  (27,9,'n','n'),
  (28,1,'d','d'),
  (29,107,'a','a');

CREATE TABLE t2 (
  pk int(11) NOT NULL AUTO_INCREMENT,
  col_int_key int(11) NOT NULL,
  col_varchar_key varchar(1) NOT NULL,
  col_varchar_nokey varchar(1) NOT NULL,
  PRIMARY KEY (pk),
  KEY col_int_key (col_int_key),
  KEY col_varchar_key (col_varchar_key,col_int_key)
) ENGINE=InnoDB;
INSERT INTO t2 VALUES 
  (10,3,'i','i'),
  (11,186,'x','x'),
  (12,1,'g','g'),
  (13,8,'q','q'),
  (14,226,'m','m'),
  (15,133,'p','p'),
  (16,6,'e','e'),
  (17,3,'t','t'),
  (18,8,'j','j'),
  (19,5,'h','h'),
  (20,7,'w','w');

set join_cache_level=6;
set join_buffer_size=1536;
SELECT count(*), sum(table1.col_int_key*table2.pk) 
FROM 
  t2 AS table1, t1 AS table2, t2 AS table3 
WHERE 
  table3.col_varchar_nokey = table2.col_varchar_key AND table3.pk > table2.col_varchar_nokey ;
-----------------------------------------------------------------------