Bug #56678 Valgrind warnings from binlog.binlog_unsafe
Submitted: 9 Sep 2010 8:57 Modified: 14 Dec 2010 20:16
Reporter: Jon Olav Hauglid Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: DML Severity:S3 (Non-critical)
Version:5.5 OS:Any
Assigned to: Jon Olav Hauglid CPU Architecture:Any
Tags: parsing for replication
Triage: Triaged: D3 (Medium)

[9 Sep 2010 8:57] Jon Olav Hauglid
Description:
From Tor Didriksen:

binlog.binlog_unsafe gives valgrind warnings in 5.5.

==31659== Source and destination overlap in memcpy(0x39187040, 0x24570570, -36212537)
==31659==    at 0x4C29E2A: memcpy (mc_replace_strmem.c:497)
==31659==    by 0x65A739: String::append(char const*, unsigned int) (sql_string.cc:385)
==31659==    by 0x5C8672: create_insert_stmt_from_insert_delayed(THD*, String*) (sql_insert.cc:638)
==31659==    by 0x5C9697: mysql_insert(THD*, TABLE_LIST*, List<Item>&, List<List<Item> >&, List<Item>&, List<Item>&, enum_duplicates, bool) (sql_insert.cc:1032)
==31659==    by 0x5E2E34: mysql_execute_command(THD*) (sql_parse.cc:2893)
==31659==    by 0x60031E: Prepared_statement::execute(String*, bool) (sql_prepare.cc:3767)
==31659==    by 0x5FF3AA: Prepared_statement::execute_loop(String*, bool, unsigned char*, unsigned char*) (sql_prepare.cc:3420)
==31659==    by 0x5FD2FD: mysql_sql_stmt_execute(THD*) (sql_prepare.cc:2621)
==31659==    by 0x5E114B: mysql_execute_command(THD*) (sql_parse.cc:2145)
==31659==    by 0x5EA3FD: mysql_parse(THD*, char*, unsigned int, Parser_state*) (sql_parse.cc:5554)
==31659==    by 0x5DEA56: dispatch_command(enum_server_command, THD*, char*, unsigned int) (sql_parse.cc:1099)
==31659==    by 0x5DDD2E: do_command(THD*) (sql_parse.cc:771)
==31659==    by 0x6C6870: do_handle_one_connection(THD*) (sql_connect.cc:1192)
==31659==    by 0x6C66CD: handle_one_connection (sql_connect.cc:1131)
==31659==    by 0xA521C5: pfs_spawn_thread (pfs.cc:1015)
==31659==    by 0x4E349C9: start_thread (pthread_create.c:300)

Looks like a problem with INSERT DELAYED.
No warnings in 5.1.

How to repeat:
./mtr --valgrind-mysqld binlog.binlog_unsafe
[10 Sep 2010 12:13] Jon Olav Hauglid
Simplified MTR test case:

--source include/have_log_bin.inc
CREATE TABLE t1(a INT);
PREPARE stmt FROM 'INSERT DELAYED INTO t1 VALUES (1), (2)';
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
DROP TABLE t1;
[10 Sep 2010 12:17] Jon Olav Hauglid
Looks like a regression introduced by the patch for bug#54579.
[13 Sep 2010 8:26] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/118056

3136 Jon Olav Hauglid	2010-09-13
      Bug #56678 Valgrind warnings from binlog.binlog_unsafe
      
      After the patch for Bug#54579, multi inserts done with INSERT DELAYED
      are binlogged as normal INSERT. During processing of the statement,
      a new query string without the DELAYED keyword is made. The problem
      was that this new string was incorrectly made when the INSERT DELAYED
      was part of a prepared statement - data was read outside the allocated
      buffer.
      
      The reason for this bug was that a pointer to the position of the
      DELAYED keyword inside the query string was stored when parsing the
      statement. This pointer was then later (at runtime) used (via pointer
      subtraction) to find the number of characters to skip when making a
      new query string without DELAYED. But when the statement was re-executed
      as part of a prepared statement, the original pointer would be invalid
      and the pointer subtraction would give a wrong/random result.
      
      This patch fixes the problem by instead storing the number of characters
      to skip at parse time. This value will not depend on the memory position
      of the query string at runtime and therefore not give wrong results
      when the statement is executed in a prepared statement.
      
      This bug was a regression introduced by the patch for Bug#54579.
      
      No test case added as this bug is already covered by the existing
      binlog.binlog_unsafe test case when running with valgrind.
[23 Sep 2010 8:27] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/118904

3142 Jon Olav Hauglid	2010-09-23
      Bug #56678 Valgrind warnings from binlog.binlog_unsafe
      
      After the patch for Bug#54579, multi inserts done with INSERT DELAYED
      are binlogged as normal INSERT. During processing of the statement,
      a new query string without the DELAYED keyword is made. The problem
      was that this new string was incorrectly made when the INSERT DELAYED
      was part of a prepared statement - data was read outside the allocated
      buffer.
      
      The reason for this bug was that a pointer to the position of the
      DELAYED keyword inside the query string was stored when parsing the
      statement. This pointer was then later (at runtime) used (via pointer
      subtraction) to find the number of characters to skip when making a
      new query string without DELAYED. But when the statement was re-executed
      as part of a prepared statement, the original pointer would be invalid
      and the pointer subtraction would give a wrong/random result.
      
      This patch fixes the problem by instead storing the number of characters
      to skip at parse time. This value will not depend on the memory position
      of the query string at runtime and therefore not give wrong results
      when the statement is executed in a prepared statement.
      
      This bug was a regression introduced by the patch for Bug#54579.
      
      No test case added as this bug is already covered by the existing
      binlog.binlog_unsafe test case when running with valgrind.
[24 Sep 2010 6:32] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/118988

3143 Jon Olav Hauglid	2010-09-24
      Bug #56678 Valgrind warnings from binlog.binlog_unsafe
      
      After the patch for Bug#54579, multi inserts done with INSERT DELAYED
      are binlogged as normal INSERT. During processing of the statement,
      a new query string without the DELAYED keyword is made. The problem
      was that this new string was incorrectly made when the INSERT DELAYED
      was part of a prepared statement - data was read outside the allocated
      buffer.
      
      The reason for this bug was that a pointer to the position of the
      DELAYED keyword inside the query string was stored when parsing the
      statement. This pointer was then later (at runtime) used (via pointer
      subtraction) to find the number of characters to skip when making a
      new query string without DELAYED. But when the statement was re-executed
      as part of a prepared statement, the original pointer would be invalid
      and the pointer subtraction would give a wrong/random result.
      
      This patch fixes the problem by instead storing the offsets from the
      beginning of the query string to the start and end of the DELAYED 
      keyword. These values will not depend on the memory position
      of the query string at runtime and therefore not give wrong results
      when the statement is executed in a prepared statement.
      
      This bug was a regression introduced by the patch for Bug#54579.
      
      No test case added as this bug is already covered by the existing
      binlog.binlog_unsafe test case when running with valgrind.
[24 Sep 2010 8:45] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/119006

3145 Jon Olav Hauglid	2010-09-24
      Bug #56678 Valgrind warnings from binlog.binlog_unsafe
      
      After the patch for Bug#54579, multi inserts done with INSERT DELAYED
      are binlogged as normal INSERT. During processing of the statement,
      a new query string without the DELAYED keyword is made. The problem
      was that this new string was incorrectly made when the INSERT DELAYED
      was part of a prepared statement - data was read outside the allocated
      buffer.
      
      The reason for this bug was that a pointer to the position of the
      DELAYED keyword inside the query string was stored when parsing the
      statement. This pointer was then later (at runtime) used (via pointer
      subtraction) to find the number of characters to skip when making a
      new query string without DELAYED. But when the statement was re-executed
      as part of a prepared statement, the original pointer would be invalid
      and the pointer subtraction would give a wrong/random result.
      
      This patch fixes the problem by instead storing the offsets from the
      beginning of the query string to the start and end of the DELAYED 
      keyword. These values will not depend on the memory position
      of the query string at runtime and therefore not give wrong results
      when the statement is executed in a prepared statement.
      
      This bug was a regression introduced by the patch for Bug#54579.
      
      No test case added as this bug is already covered by the existing
      binlog.binlog_unsafe test case when running with valgrind.
[24 Sep 2010 8:45] Jon Olav Hauglid
Pushed to mysql-5.5-runtime (5.5.7-m3).
[30 Sep 2010 17:03] Davi Arnaut
FWIW, the bug is also causing a regular crash when running the test suite. mysql-5.5-runtime with the fix works fine.
[9 Nov 2010 19:46] Bugs System
Pushed into mysql-5.5 5.5.7-rc (revid:sunanda.menon@sun.com-20101109182959-otkxq8vo2dcd13la) (version source revid:marko.makela@oracle.com-20100824081003-v4ecy0tga99cpxw2) (merge vers: 5.1.50) (pib:21)
[12 Nov 2010 1:59] Paul Dubois
Noted in 5.5.7 changelog.

Prepared multiple-row INSERT DELAYED statements were written to the
binary log without DELAYED.
[13 Nov 2010 16:19] Bugs System
Pushed into mysql-trunk 5.6.99-m5 (revid:alexander.nozdrin@oracle.com-20101113155825-czmva9kg4n31anmu) (version source revid:marko.makela@oracle.com-20100824081003-v4ecy0tga99cpxw2) (merge vers: 5.1.50) (pib:21)
[13 Nov 2010 16:35] Bugs System
Pushed into mysql-next-mr (revid:alexander.nozdrin@oracle.com-20101113160336-atmtmfb3mzm4pz4i) (version source revid:marko.makela@oracle.com-20100824081003-v4ecy0tga99cpxw2) (pib:21)
[29 Nov 2010 11:11] Bugs System
Pushed into mysql-trunk 5.6.1-m5 (revid:alexander.nozdrin@oracle.com-20101129111021-874if2qsp0i8d5ze) (version source revid:alexander.nozdrin@oracle.com-20101129111021-874if2qsp0i8d5ze) (merge vers: 5.6.1-m5) (pib:23)