Bug #55077 Assertion failed: width > 0 && to != ((void *)0), file .\dtoa.c
Submitted: 8 Jul 2010 12:36 Modified: 16 Nov 2010 2:05
Reporter: Shane Bester (Platinum Quality Contributor) Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Data Types Severity:S3 (Non-critical)
Version:5.5.6-debug OS:Any (Windows, Mac OS X)
Assigned to: Alexey Kopytov CPU Architecture:Any
Tags: regression
Triage: Triaged: D1 (Critical)

[8 Jul 2010 12:36] Shane Bester
Description:
Version: '5.5.6-m3-debug'  socket: ''  port: 3306  Source distribution
Assertion failed: width > 0 && to != ((void *)0), file .\dtoa.c, line 219
mysqld.exe!my_sigabrt_handler()[my_thr_init.c:519]
mysqld.exe!raise()[winsig.c:597]
mysqld.exe!abort()[abort.c:78]
mysqld.exe!_wassert()[assert.c:212]
mysqld.exe!my_gcvt()[dtoa.c:219]
mysqld.exe!Field_double::val_str()[field.cc:4580]
mysqld.exe!Field::val_str()[field.h:160]
mysqld.exe!Protocol_text::store()[protocol.cc:1145]
mysqld.exe!Item_field::send()[item.cc:5999]
mysqld.exe!Protocol::send_result_set_row()[protocol.cc:877]
mysqld.exe!select_send::send_data()[sql_class.cc:1784]
mysqld.exe!end_send()[sql_select.cc:12503]
mysqld.exe!evaluate_join_record()[sql_select.cc:11707]
mysqld.exe!sub_select()[sql_select.cc:11582]
mysqld.exe!do_select()[sql_select.cc:11334]
mysqld.exe!JOIN::exec()[sql_select.cc:2354]
mysqld.exe!mysql_select()[sql_select.cc:2551]
mysqld.exe!handle_select()[sql_select.cc:290]
mysqld.exe!execute_sqlcom_select()[sql_parse.cc:4882]
mysqld.exe!mysql_execute_command()[sql_parse.cc:2329]
mysqld.exe!mysql_parse()[sql_parse.cc:5911]
mysqld.exe!dispatch_command()[sql_parse.cc:1138]
mysqld.exe!do_command()[sql_parse.cc:807]
mysqld.exe!do_handle_one_connection()[sql_connect.cc:1196]
mysqld.exe!handle_one_connection()[sql_connect.cc:1136]
mysqld.exe!pthread_start()[my_winthread.c:62]
mysqld.exe!_callthreadstartex()[threadex.c:348]
mysqld.exe!_threadstartex()[threadex.c:331]

How to repeat:
#run on debug server:
drop table if exists `t1`;
create table `t1`(`a` char(1),`b` float);
insert into t1 values ('1',1);
select
if(
   (select multipolygon(1)from`t1`limit 1),
   (select multipolygon(1)from`t1`limit 1),`b`
  )`a`  
from `t1` 
group by `a`;
[8 Jul 2010 12:41] Valeriy Kravchuk
Verified just as described with recent mysql-next-mr from bzr on Mac OS X:

valeriy-kravchuks-macbook-pro:next-mr openxs$ bin/mysql -uroot test
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.6.99-m4-debug Source distribution

Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
This software comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to modify and redistribute it under the GPL v2 license

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> drop table if exists `t1`;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> create table `t1`(`a` char(1),`b` float);
Query OK, 0 rows affected (0.05 sec)

mysql> insert into t1 values ('1',1);
Query OK, 1 row affected (0.00 sec)

mysql> select
    -> if(
    ->    (select multipolygon(1)from`t1`limit 1),
    ->    (select multipolygon(1)from`t1`limit 1),`b`
    ->   )`a`  
    -> from `t1` 
    -> group by `a`;
ERROR 2013 (HY000): Lost connection to MySQL server during query
mysql> 100708 15:39:06 mysqld_safe mysqld restarted

mysql> exit
Bye
valeriy-kravchuks-macbook-pro:next-mr openxs$ tail -100 var/macbook-pro.err 
100708 15:38:58 mysqld_safe Starting mysqld daemon with databases from /Users/openxs/dbs/next-mr/var
100708 15:38:59 [Warning] Setting lower_case_table_names=2 because file system for /Users/openxs/dbs/next-mr/var/ is case insensitive
100708 15:38:59 [Warning] One can only use the --user switch if running as root

100708 15:38:59 [Note] Plugin 'FEDERATED' is disabled.
100708 15:38:59 [Note] Plugin 'ndbcluster' is disabled.
InnoDB: The InnoDB memory heap is disabled
InnoDB: Mutexes and rw_locks use GCC atomic builtins
InnoDB: Compressed tables use zlib 1.2.3
InnoDB: The first specified data file ./ibdata1 did not exist:
InnoDB: a new database to be created!
100708 15:38:59  InnoDB: Setting file ./ibdata1 size to 10 MB
InnoDB: Database physically writes the file full: wait...
100708 15:39:00  InnoDB: Log file ./ib_logfile0 did not exist: new to be created
InnoDB: Setting log file ./ib_logfile0 size to 5 MB
InnoDB: Database physically writes the file full: wait...
100708 15:39:00  InnoDB: Log file ./ib_logfile1 did not exist: new to be created
InnoDB: Setting log file ./ib_logfile1 size to 5 MB
InnoDB: Database physically writes the file full: wait...
InnoDB: Doublewrite buffer not found: creating new
InnoDB: Doublewrite buffer created
InnoDB: 127 rollback segment(s) active.
InnoDB: Creating foreign key constraint system tables
InnoDB: Foreign key constraint system tables created
100708 15:39:00 InnoDB 1.2.0 started; log sequence number 0
100708 15:39:00 [Warning] It might be a maiden lunch of the server, for there is no UUID existing. A new UUID is generated. it is c8bda60c-8a8d-11df-b503-539e20c6802d
100708 15:39:01 [Note] Event Scheduler: Loaded 0 events
100708 15:39:01 [Note] /Users/openxs/dbs/next-mr/libexec/mysqld: ready for connections.
Version: '5.6.99-m4-debug'  socket: '/tmp/mysql.sock'  port: 3306  Source distribution
Assertion failed: (width > 0 && to != ((void *)0)), function my_gcvt, file dtoa.c, line 219.
100708 15:39:06 - mysqld got signal 6 ;

MySQL 5.1.49 does not have this assertion failure, so this is a regression of a kind.
[27 Jul 2010 13:46] Guilhem Bichot
I cannot repeat it under Linux with tree next-mr-bugfixing at revision tor.didriksen@oracle.com-20100727130203-8wufa1ssxxn1froj , BUILD/compile-pentium64-debug.
I ran those queries:
drop table if exists `t1`;
create table `t1`(`a` char(1),`b` float);
insert into t1 values ('1',1);
select
if(
   (select multipolygon(1)from`t1`limit 1),
   (select multipolygon(1)from`t1`limit 1),`b`
  )`a`  
from `t1` 
group by `a`;
drop table t1;
I'm asking Valeriy to re-check this, also on Linux to see whether this is platform-specific.
[27 Jul 2010 14:24] Valeriy Kravchuk
I still see this assertion failure on current mysql-next-mr tree with the following revision-info

macbook-pro:mysql-next-mr-work openxs$ bzr revision-info
3167 alik@sun.com-20100723125004-ebkwb9bu61uka1ud

on Mac OS X 10.5.6, built with BUILD/compile-pentium-debug-max.
[25 Aug 2010 15:58] 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/116784

3082 Alexey Kopytov	2010-08-25
      Bug#55077: Assertion failed: width > 0 && to != ((void *)0),
                 file .\dtoa.c
      
      The assertion failure was correct because the 'width' argument
      of my_gcvt() has the signed integer type, whereas the unsigned
      value UINT_MAX32 was being passed by the caller
      (Field_double::val_str()) leading to a negative width in
      my_gcvt().
      
      The following chain of problems was found by further analysis:
      
      1. The display width for a floating point number is calculated
      in Field_double::val_str() as either field_length or the
      maximum possible length of string representation of a floating
      point number, whichever is greater. Since in the bug's test
      case field_length is UINT_MAX32, we get the same value as the
      display width. This does not make any sense because for numeric
      values field_length only matters for ZEROFILL columns,
      otherwise it does not make sense to allocate that much memory
      just to print a number. Field_float::val_str() has a similar
      problem.
      
      2. Even if the above wasn't the case, we would still get a
      crash on a slightly different test case when trying to allocate
      UINT_MAX32 bytes with String::alloc() because the latter does
      not handle such large input values correctly due to alignment
      overflows.
      
      3. Even when String::alloc() is fixed to return an error when
      an alignment overflow occurs, there is still a problem because
      almost no callers check its return value, and
      Field_double::val_str() is not an exception (same for
      Field_float::val_str()).
      
      4. Even if all of the above wasn't the case, creating a
      Field_double object with UINT_MAX32 as its field_length does
      not make much sense either, since the .frm code limits it to
      MAX_FIELD_CHARLENGTH (255) bytes. Such a beast can only be
      created by create_tmp_field_from_item() from an Item with
      REAL_RESULT as its result_type() and UINT_MAX32 as its
      max_length.
      
      5. For the bug's test case, the above condition (REAL_RESULT
      Item with max_length = UINT_MAX32) was a result of
      Item_func_if::fix_length_and_dec() "shortcutting" aggregation
      of argument types when one of the arguments was a constant
      NULL. In this case, the attributes of the aggregated type were
      simply copied from the other, non-NULL argument, but max_length
      was still calculated as per the general, non-shortcut case, by
      choosing the greatest of argument's max_length, which is
      obviously not correct.
      
      The patch addresses all of the above problems, even though
      fixing the assertion failure for the particular test case would
      require only a subset of the above problems to be solved.
     @ client/sql_string.cc
        Return an error in case of uint32 overflow in alignment.
        Also assert there was no overflow to help find such conditions
        in debug builds, since almost no callers check the return value
        of String::alloc().
     @ mysql-test/r/func_if.result
        Add a test case for bug #55077.
     @ mysql-test/t/func_if.test
        Add a test case for bug #55077.
     @ sql/field.cc
        - Assert we don't operate with fields wider than 255 
        (MAX_FIELD_CHARLENGTH) bytes in both Field_float and  
        Field_double. 
        - Don't take field_length into account when calculating the 
        output buffer length.
        - Check the return value of String::alloc()
     @ sql/item_cmpfunc.cc
        When shortcutting type aggregation, don't take the NULL 
        argument's max_length into account.
     @ sql/sql_string.cc
        Return an error in case of uint32 overflow in alignment.
        Also assert there was no overflow to help find such conditions
        in debug builds, since almost no callers check the return value
        of String::alloc().
[30 Aug 2010 8:30] Bugs System
Pushed into mysql-trunk 5.6.1-m4 (revid:alik@sun.com-20100830082732-n2eyijnv86exc5ci) (version source revid:alik@sun.com-20100830082732-n2eyijnv86exc5ci) (merge vers: 5.6.1-m4) (pib:21)
[30 Aug 2010 8:34] Bugs System
Pushed into mysql-next-mr (revid:alik@sun.com-20100830082745-n6sh01wlwh3itasv) (version source revid:alik@sun.com-20100830082745-n6sh01wlwh3itasv) (pib:21)
[8 Sep 2010 19:16] Paul Dubois
Noted in 5.5.6, 5.6.1 changelogs.

IF() with a subquery argument could raise a debug assertion for debug
builds under some circumstances.
[10 Sep 2010 18:51] Bugs System
Pushed into mysql-5.5 5.5.7-rc (revid:joerg@mysql.com-20100910184813-csdto6tk4nlogrsq) (version source revid:dlenev@mysql.com-20100831090419-rzr5ktekby2gspm1) (merge vers: 5.5.6-m3) (pib:21)
[13 Sep 2010 13:49] Bugs System
Pushed into mysql-trunk 5.6.1-m4 (revid:dlenev@mysql.com-20100913103627-p2oqplu42x1gv2bd) (version source revid:dlenev@mysql.com-20100831090419-rzr5ktekby2gspm1) (merge vers: 5.5.6-m3) (pib:21)
[13 Sep 2010 13:51] Bugs System
Pushed into mysql-next-mr (revid:dlenev@mysql.com-20100913121556-sfxqlpj9kbc28kaf) (version source revid:dlenev@mysql.com-20100831090419-rzr5ktekby2gspm1) (pib:21)
[15 Oct 2010 15:38] Tor Didriksen
Introduced regression:
Bug #57203 Assertion `field_length <= 255' failed.
[11 Nov 2010 14:50] Shane Bester
still seeing this on different testcases?  take a look at bug #58137
[13 Nov 2010 16:20] Bugs System
Pushed into mysql-trunk 5.6.99-m5 (revid:alexander.nozdrin@oracle.com-20101113155825-czmva9kg4n31anmu) (version source revid:alexander.nozdrin@oracle.com-20101113152450-2zzcm50e7i4j35v7) (merge vers: 5.6.1-m4) (pib:21)
[13 Nov 2010 16:39] Bugs System
Pushed into mysql-next-mr (revid:alexander.nozdrin@oracle.com-20101113160336-atmtmfb3mzm4pz4i) (version source revid:vasil.dimov@oracle.com-20100629074804-359l9m9gniauxr94) (pib:21)
[16 Dec 2010 22:33] Bugs System
Pushed into mysql-5.5 5.5.9 (revid:jonathan.perkin@oracle.com-20101216101358-fyzr1epq95a3yett) (version source revid:jonathan.perkin@oracle.com-20101216101358-fyzr1epq95a3yett) (merge vers: 5.5.9) (pib:24)
[24 Jan 2011 12:39] Øystein Grøvlen
The fix for this bug seems to be the cause of the regression reported in Bug#59632.