Bug #88134 Conditional jump or move depends on uninitialised value (ctype-utf8.c:4937)
Submitted: 18 Oct 2017 7:02 Modified: 20 Oct 2017 13:59
Reporter: yghmgl yang Email Updates:
Status: Can't repeat Impact on me:
None 
Category:MySQL Server Severity:S3 (Non-critical)
Version:5.6.37 OS:Any
Assigned to: CPU Architecture:Any
Tags: debug valgrind-build

[18 Oct 2017 7:02] yghmgl yang
Description:
==917== Conditional jump or move depends on uninitialised value(s)
==917==    at 0xEACDEA: my_wildcmp_unicode_impl (ctype-utf8.c:4937)
==917==    by 0xEAD1AF: my_wildcmp_unicode (ctype-utf8.c:5060)
==917==    by 0xEAE898: my_wildcmp_utf8 (ctype-utf8.c:5994)
==917==    by 0x690EBC: Item_func_like::val_int() (item_cmpfunc.cc:5297)
==917==    by 0x66E5B3: Item::send(Protocol*, String*) (item.cc:6936)
==917==    by 0x72F963: Protocol::send_result_set_row(List<Item>*) (protocol.cc:844)
==917==    by 0x7A13AC: select_send::send_data(List<Item>&) (sql_class.cc:2526)
==917==    by 0x7B8539: JOIN::exec() (sql_executor.cc:151)
==917==    by 0x81BC5E: mysql_execute_select(THD*, st_select_lex*, bool) (sql_select.cc:1101)
==917==    by 0x81BF50: mysql_select(THD*, TABLE_LIST*, unsigned int, List<Item>&, Item*, SQL_I_List<st_order>*, SQL_I_List<st_order>*, Item*, unsigned long long, select_result*, st_select_lex_unit*, st_select_lex*) (sql_select.cc:1222)
==917==    by 0x81A049: handle_select(THD*, select_result*, unsigned long) (sql_select.cc:110)
==917==    by 0x7F277F: execute_sqlcom_select(THD*, TABLE_LIST*) (sql_parse.cc:5237)
==917==    by 0x7EB005: mysql_execute_command(THD*) (sql_parse.cc:2695)
==917==    by 0x7F528B: mysql_parse(THD*, char*, unsigned int, Parser_state*) (sql_parse.cc:6489)
==917==    by 0x7E8005: dispatch_command(enum_server_command, THD*, char*, unsigned int) (sql_parse.cc:1377)
==917==    by 0x7E7037: do_command(THD*) (sql_parse.cc:1040)
==917==    by 0x20973B67: threadpool_process_request(THD*) (threadpool_common.cc:321)
==917==    by 0x20976A37: handle_event(connection_t*) (threadpool_unix.cc:1611)
==917==    by 0x20976C94: worker_main(void*) (threadpool_unix.cc:1664)
==917==    by 0xB99FDC: pfs_spawn_thread (pfs.cc:1860)
==917==    by 0x5043DC4: start_thread (in /usr/lib64/libpthread-2.17.so)
==917==    by 0x61AC21C: clone (in /usr/lib64/libc-2.17.so)
==917==  Uninitialised value was created by a client request
==917==    at 0xAC907F: free_root (my_alloc.c:391)
==917==    by 0x7E95AF: dispatch_command(enum_server_command, THD*, char*, unsigned int) (sql_parse.cc:1829)
==917==    by 0x7E7037: do_command(THD*) (sql_parse.cc:1040)
==917==    by 0x20973B67: threadpool_process_request(THD*) (threadpool_common.cc:321)
==917==    by 0x20976A37: handle_event(connection_t*) (threadpool_unix.cc:1611)
==917==    by 0x20976C94: worker_main(void*) (threadpool_unix.cc:1664)
==917==    by 0xB99FDC: pfs_spawn_thread (pfs.cc:1860)
==917==    by 0x5043DC4: start_thread (in /usr/lib64/libpthread-2.17.so)
==917==    by 0x61AC21C: clone (in /usr/lib64/libc-2.17.so)

How to repeat:
pquery is random execute sql statement, so it hard to find which statement cause this issue,but it happened every day in my daily test.

Suggested fix:
my_wildcmp_unicode_impl (ctype-utf8.c:4937)
      if (w_wc ==  (my_wc_t) escape && wildstr < wildend)
escape is not initialized 

my_wildcmp_unicode_impl (ctype-utf8.c:4937) call from

 my_wildcmp_unicode (ctype-utf8.c:5060)
my_wildcmp_unicode(const CHARSET_INFO *cs,
                   const char *str,const char *str_end,
                   const char *wildstr,const char *wildend,
                   int escape, int w_one, int w_many,
                   MY_UNICASE_INFO *weights)
{
  return my_wildcmp_unicode_impl(cs, str, str_end,
                                 wildstr, wildend,
                                 escape, w_one, w_many, weights, 1);
}
escape not initialized in this layer

next layer is
static
int my_wildcmp_utf8(const CHARSET_INFO *cs,
		    const char *str,const char *str_end,
		    const char *wildstr,const char *wildend,
		    int escape, int w_one, int w_many)
{
  MY_UNICASE_INFO *uni_plane= cs->caseinfo;
  return my_wildcmp_unicode(cs,str,str_end,wildstr,wildend,
                            escape,w_one,w_many,uni_plane); 
}

escape not initialized in this layer
next layer
longlong Item_func_like::val_int()
{
  DBUG_ASSERT(fixed == 1);
  String* res = args[0]->val_str(&cmp.value1);
  if (args[0]->null_value)
  {
    null_value=1;
    return 0;
  }
  String* res2 = args[1]->val_str(&cmp.value2);
  if (args[1]->null_value)
  {
    null_value=1;
    return 0;
  }
  null_value=0;
  if (canDoTurboBM)
    return turboBM_matches(res->ptr(), res->length()) ? 1 : 0;
  return my_wildcmp(cmp.cmp_collation.collation,
		    res->ptr(),res->ptr()+res->length(),
		    res2->ptr(),res2->ptr()+res2->length(),
		    escape,wild_one,wild_many) ? 0 : 1;
}
escape not initialized in this layer

longlong val_int() is from class  Item_func_like and class Item_func_like have no initialized  escape 

class Item_func_like :public Item_bool_func2
{
  // Turbo Boyer-Moore data
  bool        canDoTurboBM;	// pattern is '%abcd%' case
  const char* pattern;
  int         pattern_len;

  // TurboBM buffers, *this is owner
  int* bmGs; //   good suffix shift table, size is pattern_len + 1
  int* bmBc; // bad character shift table, size is alphabet_size

  void turboBM_compute_suffixes(int* suff);
  void turboBM_compute_good_suffix_shifts(int* suff);
  void turboBM_compute_bad_character_shifts();
  bool turboBM_matches(const char* text, int text_len) const;
  enum { alphabet_size = 256 };

  Item *escape_item;
  
  bool escape_used_in_parsing;

public:
  int escape;

  Item_func_like(Item *a,Item *b, Item *escape_arg, bool escape_used)
    :Item_bool_func2(a,b), canDoTurboBM(FALSE), pattern(0), pattern_len(0), 
     bmGs(0), bmBc(0), escape_item(escape_arg),
     escape_used_in_parsing(escape_used) {}
  longlong val_int();
  enum Functype functype() const { return LIKE_FUNC; }
  optimize_type select_optimize() const;
  cond_result eq_cmp_result() const { return COND_TRUE; }
  const char *func_name() const { return "like"; }
  bool fix_fields(THD *thd, Item **ref);
  void cleanup();
  /**
    @retval true non default escape char specified
                 using "expr LIKE pat ESCAPE 'escape_char'" syntax
  */
  bool escape_was_used_in_parsing() const { return escape_used_in_parsing; }
};
[18 Oct 2017 17:24] Shane Bester
Hi, 

You wrote "so it hard to find which statement cause this issue".

It is really not hard.  Tell valgrind to stop at error and enter the gdb debugger then print the thd->query_string or thd->query in the mysql_parse frame.

Then test that query on its own,  and also test 5.7.20 and 8.0.3 to see if it is reproducible there.