Comment 7 for bug 1384568

Revision history for this message
George Ormond Lorch III (gl-az) wrote : Re: EXPLAIN crashes server

I can finally reproduce this in debug and valgrind.

I can eliminate the EXPLAIN and just use this sequence shortened from Roels test above:
DROP DATABASE IF EXISTS test; CREATE DATABASE test; USE test; CREATE TABLE t1(a INT KEY,B TEXT)ENGINE=InnoDB; select * FROM t1 x,t1 y where(x.a=2 or (x.a,x.b)in ((0,0),(5,0),(4,3))) and y.a=x.d and y.b=x.b;

Look at the last two expressions of the where:
and y.a=x.d and y.b=x.b;

"and y.a=x.d and"

There is no 'd' in the table definition, this is causing the crash. Ideally the server shouldn't crash but return an error instead.

Valgrind+vgdb is giving me this:
==26044== Conditional jump or move depends on uninitialised value(s)
==26044== at 0x65206F: Item_field::val_str(String*) (item.cc:2673)
==26044== by 0x6864DD: cmp_item_sort_string::store_value(Item*) (item_cmpfunc.h:1166)
==26044== by 0x67BEEF: cmp_item_row::store_value(Item*) (item_cmpfunc.cc:4190)
==26044== by 0x67D296: Item_func_in::fix_length_and_dec() (item_cmpfunc.cc:4590)
==26044== by 0x69FF2D: Item_func::fix_fields(THD*, Item**) (item_func.cc:231)
==26044== by 0x67C6B8: Item_func_in::fix_fields(THD*, Item**) (item_cmpfunc.cc:4362)
==26044== by 0x67E101: Item_cond::fix_fields(THD*, Item**) (item_cmpfunc.cc:4838)
==26044== by 0x67E101: Item_cond::fix_fields(THD*, Item**) (item_cmpfunc.cc:4838)
==26044== by 0x76F8E2: setup_conds(THD*, TABLE_LIST*, TABLE_LIST*, Item**) (sql_base.cc:9003)
==26044== by 0x7FE8CB: setup_without_group(THD*, Bounds_checked_array<Item*>, TABLE_LIST*, TABLE_LIST*, List<Item>&, List<Item>&, Item**, st_order*, st_order*, int*, int*) (sql_resolver.cc:952)
==26044== by 0x7FC1C0: JOIN::prepare(TABLE_LIST*, unsigned int, Item*, unsigned int, st_order*, st_order*, Item*, st_select_lex*, st_select_lex_unit*) (sql_resolver.cc:177)
==26044== by 0x803D3B: mysql_prepare_select(THD*, TABLE_LIST*, unsigned int, List<Item>&, Item*, unsigned int, st_order*, st_order*, Item*, unsigned long long, select_result*, st_select_lex_unit*, st_select_lex*, bool*) (sql_select.cc:1054)
==26044== Uninitialised value was created by a heap allocation
==26044== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==26044== by 0xAA2918: my_malloc (my_malloc.c:38)
==26044== by 0xA9C14A: alloc_root (my_alloc.c:224)
==26044== by 0x899ED5: open_table_from_share(THD*, TABLE_SHARE*, char const*, unsigned int, unsigned int, unsigned int, TABLE*, bool) (table.cc:2168)
==26044== by 0x763CB1: open_table(THD*, TABLE_LIST*, Open_table_context*) (sql_base.cc:3205)
==26044== by 0x76635D: open_and_process_table(THD*, LEX*, TABLE_LIST*, unsigned int*, unsigned int, Prelocking_strategy*, bool, Open_table_context*) (sql_base.cc:4699)
==26044== by 0x7672C9: open_tables(THD*, TABLE_LIST**, unsigned int*, unsigned int, Prelocking_strategy*) (sql_base.cc:5213)
==26044== by 0x76843A: open_normal_and_derived_tables(THD*, TABLE_LIST*, unsigned int) (sql_base.cc:5913)
==26044== by 0x7DA78F: execute_sqlcom_select(THD*, TABLE_LIST*) (sql_parse.cc:5589)
==26044== by 0x7D2E84: mysql_execute_command(THD*) (sql_parse.cc:2974)
==26044== by 0x7DD136: mysql_parse(THD*, char*, unsigned int, Parser_state*) (sql_parse.cc:6792)
==26044== by 0x7CF6BE: dispatch_command(enum_server_command, THD*, char*, unsigned int) (sql_parse.cc:1434)

So it seems that the space is being allocated for the field x.d but never initialized. I'm not (yet) intimately familiar with this portion of the server so still have some debugging to do to figure out how to fix it.

Shuffling the statement around or selectively removing some elements will pass and return an error in some cases or continue crashing in others.