Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

t/vector fails on 32bit platforms at ASSERT_FALSE(vec.resize(INT64_MAX)) #279

Closed
cheese opened this issue Feb 19, 2020 · 13 comments
Closed

Comments

@cheese
Copy link

cheese commented Feb 19, 2020

Are 32bit platforms still supported?

Tested 1.1.19.1 on 32bit CentOS7 altarch, and t/vector failed during make test.
The same on 32bit ARM.

The only failing assertion is ASSERT_FALSE(vec.resize(INT64_MAX)).

This Dockerfile can reproduce the issue:

FROM i386/centos:7

MAINTAINER gearmand

ARG GEARMAN_REPO=https://github.com/gearman/gearmand

LABEL version="${version}" description="Gearman SSL Job Server Image"

# Configure environment
ENV HOME=/root

# Install packages
RUN yum update -y
RUN yum install -y rpm-build make
RUN yum install -y boost-devel boost-thread gcc-c++ gperf  gperftools-devel  hiredis-devel  libevent-devel  libmemcached-devel  libpq-devel \
  libuuid-devel  mariadb-connector-c-devel  memcached  openssl-devel  sqlite-devel  systemd  tokyocabinet-devel  zlib-devel

# Retrieve the source code and bootstrap
COPY gearmand-1.1.19.1.tar.gz /tmp/
RUN cd /tmp && tar fx gearmand-1.1.19.1.tar.gz
WORKDIR /tmp/gearmand-1.1.19.1

RUN ./configure --enable-ssl 2>&1 | tee ./configure.log
RUN make 2>&1 | tee ./build.log
RUN make test 2>&1 | tee ./test.log
@p-alik
Copy link
Collaborator

p-alik commented Feb 19, 2020

Tested 1.1.19.1 on 32bit CentOS7 altarch, and t/vector failed during make test.
The same on 32bit ARM.

There are {U,}INT64 type checks

gearmand/configure.ac

Lines 188 to 205 in a6bd168

# Checks for typedefs, structures, and compiler characteristics.
AC_CHECK_TYPES([ptrdiff_t])
AC_C_CONST
AC_C_INLINE
AC_C_VOLATILE
AC_HEADER_STDBOOL
AC_HEADER_TIME
AC_TYPE_INT32_T
AC_TYPE_INT64_T
AC_TYPE_OFF_T
AC_TYPE_PID_T
AC_TYPE_SIZE_T
AC_TYPE_SSIZE_T
AC_TYPE_UID_T
AC_TYPE_UINT16_T
AC_TYPE_UINT32_T
AC_TYPE_UINT64_T
AC_TYPE_UINT8_T

Shouldn't it cause an exception on 32bit system?

The only failing assertion is ASSERT_FALSE(vec.resize(INT64_MAX)).

The assertion has a long history 255137a.

@esabol
Copy link
Member

esabol commented Feb 19, 2020

This is not specific to 1.1.19, right? This applies to 1.1.18, 1.1.17, etc., too?

@p-alik
Copy link
Collaborator

p-alik commented Feb 19, 2020

yes

@esabol
Copy link
Member

esabol commented Feb 23, 2020

The only failing assertion is ASSERT_FALSE(vec.resize(INT64_MAX)).

If this is the only thing that fails, then that is easily fixed, right?

Is there any reason not to support 32-bit architectures?

@SpamapS
Copy link
Member

SpamapS commented Feb 25, 2020 via email

@esabol
Copy link
Member

esabol commented Feb 26, 2020

So I think this works on both 32-bit and 64-bit systems:

    // SIZE_MAX is ((size_t)(-1)), but we need to subtract 1 because the
    // gearman_vector_st implementation adds 1 to the capacity.
    ASSERT_FALSE(vec.resize(((size_t)(-1)) -1));

Anyone see a problem with that?

Otherwise, things get complicated:

#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__)) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
    ASSERT_FALSE(vec.resize(INT64_MAX));
#else
    // SIZE_MAX is ((size_t)(-1)), but we need to subtract 1 because the
    // gearman_vector_st implementation adds 1 to the capacity.
    ASSERT_FALSE(vec.resize(((size_t)(-1)) -1));
#endif

References:
https://stackoverflow.com/a/40033930/5153779
https://stackoverflow.com/a/44401992/5153779

Should we bother to rename INT64_MAX_resize_TEST to something else?

@p-alik
Copy link
Collaborator

p-alik commented Feb 27, 2020

Anyone see a problem with that?

LGTM. My worry is, that we haven't 32 CI environment for testing.

Should we bother to rename INT64_MAX_resize_TEST to something else?

Wouldn't it be appropriate to cut off INT64 prefix?

@cheese
Copy link
Author

cheese commented Feb 27, 2020

Anyone see a problem with that?

In C++ style, it would be better to use std::numeric_limits<size_t>::max() instead of ((size_t)(-1)).

Otherwise, things get complicated:

#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__)) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
    ASSERT_FALSE(vec.resize(INT64_MAX));
#else
    // SIZE_MAX is ((size_t)(-1)), but we need to subtract 1 because the
    // gearman_vector_st implementation adds 1 to the capacity.
    ASSERT_FALSE(vec.resize(((size_t)(-1)) -1));
#endif

What's the real intention of using INT64_MAX? The generic of INT64_MAX seems std::numeric_limits<ssize_t>::max() instead of std::numeric_limits<size_t>::max().

@esabol
Copy link
Member

esabol commented Feb 27, 2020

In reply to @p-alik's comment:

My worry is, that we haven't 32 CI environment for testing.

Yeah. I've tested it with a Docker i386/centos7 image similar to what @cheese posted above, fwiw. I think it is possible to add Docker builds to Travis CI, but I don't know how. I think it's not worth the effort.

Should we bother to rename INT64_MAX_resize_TEST to something else?

Wouldn't it be appropriate to cut off INT64 prefix?

Sure, that would be appropriate.

In reply to @cheese's comment:

In C++ style, it would be better to use std::numeric_limits<size_t>::max() instead of ((size_t)(-1)).

Interesting. I'll test that (maybe later today) and report back.

What's the real intention of using INT64_MAX?

I'm not sure any of us can answer that question since I'm guessing these tests were written before any of us got involved with gearmand. I think the intent is to just test resize() with the largest possible number it can take.

The generic of INT64_MAX seems std::numeric_limits<ssize_t>::max() instead of std::numeric_limits<size_t>::max().

Is that a significant distinction?

@cheese
Copy link
Author

cheese commented Feb 27, 2020

The generic of INT64_MAX seems std::numeric_limits<ssize_t>::max() instead of std::numeric_limits<size_t>::max().

Is that a significant distinction?

If your guess of the test intent is right, the argument should be std::numeric_limits<size_t>::max() - 1. But the original used INT64_MAX, which is much less than std::numeric_limits<size_t>::max() - 1 on x86_64. The original author may just use a large enough argument instead of the largest possible one.

@esabol
Copy link
Member

esabol commented Aug 1, 2020

So this issue has languished. Rereading the thread here, I'm still not clear what the solution is. I think I'm still inclined to go with @cheese's suggestion of std::numeric_limits<size_t>::max() - 1. Anyone else have an opinion?

@p-alik
Copy link
Collaborator

p-alik commented Aug 2, 2020

I'm of the same opinion because it is most appropriate for the purpose of test.

bool resize(const size_t);

@esabol
Copy link
Member

esabol commented Nov 9, 2020

Merged commit addresses this issue, so I’m going to close this.

@esabol esabol closed this as completed Nov 9, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants