-
Notifications
You must be signed in to change notification settings - Fork 455
CDRIVER-4679 Prefer XSI-compliant strerror_r when available #1350
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
Conversation
src/libbson/src/bson/bson-error.c
Outdated
#elif defined(__GNUC__) && defined(_GNU_SOURCE) | ||
ret = strerror_r (err_code, buf, buflen); | ||
#else /* XSI strerror_r */ | ||
#elif defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 600 && !defined(_GNU_SOURCE) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://stackoverflow.com/a/65745713/162228 was a helpful reminder that undefined macros evaluate to zero.
What is the argument for not using the logic suggested in strerror_r(3)
?
(_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && ! _GNU_SOURCE
I'm now familiar with what platforms define _POSIX_C_SOURCE
and/or _XOPEN_SOURCE
, but it would seem more flexible to me to allow either. Likewise, ! _GNU_SOURCE
would also handle the case where _GNU_SOURCE
is defined but zero (not sure how relevant that is).
Also, I'm not sure if this line from the man page is relevant:
If no feature test macros are explicitly defined, then (since glibc 2.4) _POSIX_SOURCE is defined by default with the value 200112L, so that the XSI-compliant version of strerror_r() is provided by default.
I don't see _POSIX_SOURCE
referred to anywhere within libmongoc. It's mentioned once in the bundled zlib sources.
The versions of glibc mentioned in the man page predate 2011, so perhaps none of this is relevant to any supported platform.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the argument for not using the logic suggested in strerror_r(3)?
_XOPEN_SOURCE
implies _POSIX_C_SOURCE
per https://pubs.opengroup.org/onlinepubs/7908799/xsh/compilation.html: "Since this specification is aligned with the ISO C standard, and since all functionality enabled by _POSIX_C_SOURCE set greater than zero and less than or equal to 199506L should be enabled by _XOPEN_SOURCE set equal to 500, there should be no need to define either _POSIX_SOURCE or _POSIX_C_SOURCE if _XOPEN_SOURCE is so defined."
Likewise,
!_GNU_SOURCE
would also handle the case where_GNU_SOURCE
is defined but zero (not sure how relevant that is).
Only the presence of _GNU_SOURCE
matters, not its value, per https://man7.org/linux/man-pages/man7/feature_test_macros.7.html: "Defining this macro (with any value) implicitly defines [...]. In addition, various GNU-specific extensions are also exposed."
I don't see
_POSIX_SOURCE
referred to anywhere within libmongoc.
It is unconditionally defined via the definition of _XOPEN_SOURCE
here:
Line 398 in 6d2be25
add_definitions (-D_XOPEN_SOURCE=700 -D_BSD_SOURCE -D_DEFAULT_SOURCE) |
All our requirements concerning POSIX and extensions are being handled by the (unconditional) definition of the macros listed in the link above. The conflict between the XSI-compliant version and GNU extension version of strerror_r
is AFAIK a unique case (among the features being used by the C Driver).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the rigorous response! LGTM.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
musl defines the XSI-conforming strerror_r when _GNU_SOURCE
is defined.
Compiling with Alpine with docker results in an error:
docker run --rm -it --platform linux/amd64 -v `pwd`:/c-driver alpine
Configured with _GNU_SOURCE
defined:
cmake \
-DCMAKE_C_FLAGS="-D_GNU_SOURCE=1" \
-DBUILD_VERSION="1.25.0-pre" \
-DENABLE_SSL=OFF \
-DENABLE_SRV=OFF \
-S$(pwd) -B$(pwd)/cmake-build
Building selects the GNU extension:
/c-driver/src/libbson/src/bson/bson-error.c: In function 'bson_strerror_r':
/c-driver/src/libbson/src/bson/bson-error.c:120:8: error: assignment to 'char *' from 'int' makes pointer from integer without a cast [-Werror=int-conversion]
120 | ret = strerror_r (err_code, buf, buflen);
| ^
[ 40%] Building C object src/libbson/CMakeFiles/bson_shared.dir/src/bson/bson-iter.c.o
Does this suggest a bug in musl? Is musl be expected to provide the GNU extension when _GNU_SOURCE
is defined?
This seems to be a deliberate choice by musl, not a bug. Support for
This issue seems to have also plagued Gentoo maintainers as documented here:
and here:
and here:
In summary, combining musl and We could carve out an exclusion to handle the musl case (despite no feature test macro to detect musl directly), where the XSI-compliant variant is present despite |
@kevinAlbs: Thanks for catching that. That very issue was discussed in https://stackoverflow.com/q/41953104/162228, which I linked from CDRIVER-4679 and soon after forgot. Unfortunately, the Stack Overflow question was using C++ and ultimately worked around this using operator overloading. |
I vote for carving out an exclusion to handle musl. Given repeated requests for Alpine, I expect Alpine may eventually be a tested platform in the future (filed CDRIVER-4696 to consider testing with Alpine in Evergreen). |
Given our findings above, which are now documented in the CMakeLists.txt file, gave up on using feature test macros and instead opted to use CMake's |
set(BSON_HAVE_XSI_STRERROR_R 1) | ||
else() | ||
set(BSON_HAVE_XSI_STRERROR_R 0) | ||
endif () |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
gave up on using feature test macros and instead opted to use CMake's CheckCSourceCompiles module to obtain the definitive truth.
This does seem like the most reliable solution. Since CMake doesn't apply to the PHP driver, I created PHPC-2263 to port this to Autotools.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Confirmed latest changes build with Alpine in docker.
* CDRIVER-4679 Prefer XSI-compliant strerror_r when available * Use CheckCSourceCompiles to test for XSI-compliant strerror_r
…ongodb#1350)" This reverts commit ac436db.
…ongodb#1350)" This reverts commit ac436db.
…ongodb#1350)" This reverts commit ac436db.
Attempts to resolve CDRIVER-4679 by preferring the XSI-compliant version of
strerror_r
when available by using a more accurate feature test macros condition. The GNU extension is used as a fallback instead. An additional#error
was added to hopefully improve the resulting compilation error if a supportedstrerror_r
implementation cannot be found.Verified by this patch. Note: not yet verified on Alpine Linux as described in CDRIVER-4679 as the corresponding EVG distro is not available, so not entirely confident this actually addresses the originally reported issue.