Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-21977

main.func_math fails due to undefined behaviour

    XMLWordPrintable

    Details

      Description

      The test main.func_math fails on kvm-deb-sid-x86 since the creation of that builder:

      10.5 535c284aedddb6cc3bedba4a8877b501f456991e

      CURRENT_TEST: main.func_math
      mysqltest: At line 329: query 'SELECT -9223372036854775808 DIV -1' succeeded - should have failed with errno 1690...
      

      The query would wrongly return -9223372036854775808 (0x8000000000000000 in two’s complement signed 64-bit arithmetics). The reason is that undefined behavior allows GCC to optimize away the overflow check.

      I was able to repeat the failure locally using GCC 9.3.0 and the following invocation:

      sudo apt install g++-9-multilib lib32ncurses5-dev libgnutls28-dev:i386
      cmake -DCMAKE_INSTALL_PREFIX=/usr -DIGNORE_AIO_CHECK=ON -DPLUGIN_{ARCHIVE,INNODB,TOKUDB,MROONGA,OQGRAPH,ROCKSDB,CONNECT}=NO -DCMAKE_{C,CXX}_FLAGS='-O2 -m32 -march=i686'     -DCOMPILATION_COMMENT="mariadb.org binary distribution"     -DSYSTEM_TYPE="debian-linux-gnu"     -DCMAKE_SYSTEM_PROCESSOR=i386 -Wno-dev  -DWITH_SSL=bundled     -DBUILD_CONFIG=mysql_release     -DPLUGIN_{AWS_KEY_MANAGEMENT,AUTH_PAM}=NO -DGNUTLS_LIBRARY=/usr/lib/i386-linux-gnu/libgnutls.so -DMYSQL_MAINTAINER_MODE=OFF     -DDEB=Debian /mariadb/10.3
      nice make -j$(nproc)
      

      and the following patch:

      diff --git a/cmake/build_configurations/mysql_release.cmake b/cmake/build_configurations/mysql_release.cmake
      index f77907481a4..c237b006ac8 100644
      --- a/cmake/build_configurations/mysql_release.cmake
      +++ b/cmake/build_configurations/mysql_release.cmake
      @@ -121,7 +121,7 @@ ENDIF()
       
       IF(UNIX)
         SET(WITH_EXTRA_CHARSETS all CACHE STRING "")
      -  SET(PLUGIN_AUTH_PAM YES)
      +#  SET(PLUGIN_AUTH_PAM YES)
       
         IF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
           IF(NOT IGNORE_AIO_CHECK)
      

      Another build cmake -DWITH_UBSAN reported the error:

      10.3 c7daabdb0579531a22c24697f9efbe2ea2759435

      /mariadb/10.3/sql/item_func.cc:1759:39: runtime error: negation of -9223372036854775808 cannot be represented in type 'longlong' (aka 'long long'); cast to an unsigned type to negate this value to itself
      

      In the 32-bit build, I noticed that the res= uval0 / uval1 in Item_func_int_div::val_int() is expanded into 4 call __udivdi3. In the code path that is executed for the problematic test, the call to the inlined function Item::check_integer_overflow() is optimized away. The undefined behavior gives the permission for this optimization. It is only a coincidence that it is not being optimized away for other architectures.

      We do not run the builder for older versions than 10.3, but I believe that any version should be potentially affected by this.
      Alexander Barkov said that the fix could involve using Longlong_hybrid, which was introduced in MDEV-17249 (10.0.37, 10.1.37, 10.2.18, 10.3.10, 10.4.0). Technically, this fix should be doable in version 10.1, which has not reached EOL yet. In my opinion, it is sufficient to fix this in version 10.2 or 10.3. So, feel free to adjust the fixVersion.

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              bar Alexander Barkov
              Reporter:
              marko Marko Mäkelä
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: