Build failed in Jenkins: cyrus-imapd-master #717

Bron Gondwana brong at opera.com
Thu Jul 19 00:46:12 EDT 2012


On Thu, Jul 19, 2012, at 12:02 PM, Greg Banks wrote:
> Hmm.
> 
> static void test_byteorder(void)
> {
>     const char b64[8] = { 0, 0, 0, 0, 0, 0, 0, 1 };
>     const char b32[4] = { 0, 0, 0, 1 };
> 
>     char i64[8];
>     char i32[4];
> 
> Here's your first problem, the alignment of all these variables is
> uncontrolled.  The code is only working by accident because the C
> runtime environment gives you an aligned stack, and also because x86
> doesn't care so much about alignment.

Yeah, OK - I'll fix that first.  that's pretty easy.

> In the header file lib/byteorder64.h
> 
> /* http://stackoverflow.com/a/4410728/94253 */
> 
> #if defined(__linux__)
> #  include <endian.h>
> #elif defined(__FreeBSD__) || defined(__NetBSD__)
> #  include <sys/endian.h>
> #elif defined(__OpenBSD__)
> #  include <sys/types.h>
> #  define be16toh(x) betoh16(x)
> #  define be32toh(x) betoh32(x)
> #  define be64toh(x) betoh64(x)
> #elif defined(WORDS_BIGENDIAN)
> #define CYRUS_BYTESWAP
> #endif
> 
> That could do with some improvement.

Looks like stackoverflow might indeed be full of it.  I guess we should
really test for each of those in configure.in and then #define the right
inline instruction.

> Solaris also has an optimised ntohll() in libc which uses the 64b bswap
> instruction, although it's not inlined.
> 
> http://cvs.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/lib/libc/amd64/gen/byteorder.s
> 
> and gcc has a builtin which uses the instruction on platforms which have
> it
> 
> http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#index-g_t_005f_005fbuiltin_005fbswap64-3333
> 
> which presumably will work on some platforms where Linux's <endian.h>
> (which re-implements the same thing differently) is not available.
> 
> Disassembling cunit/byteorder64.o, I don't see any bswap instructions in
> there, but nm shows undefined symbols for libc's htonl and ntohl. 
> Writing a function that calls ntohll() and nothing else, it seems that
> ntohll() expands to a no-op.  Running gcc -E confirms this.
> 
> Aha..
> 
> #ifdef be64toh
> #define htonll(x) htobe64(x)
> #define ntohll(x) be64toh(x)
> #elif defined (CYRUS_BYTESWAP)
> /* little-endian 64-bit host/network byte-order swap functions */
> extern unsigned long long _htonll(unsigned long long);
> extern unsigned long long _ntohll(unsigned long long);
> #define htonll(x) _htonll(x)
> #define ntohll(x) _ntohll(x)
> #else
> #define htonll(x) (x)
> #define ntohll(x) (x)
> #endif
> 
> The <endian.h> on my desktop defines a be64toh().  The same header on
> ci.cyrusimap.org doesn't.

Yeah, damn.  Is it really ancient, or 32 bit, or something?

Bron.


More information about the Cyrus-devel mailing list