Bug#443880: SIGBUS on sparc
Jurij Smakov schrieb: On Mon, Mar 03, 2008 at 11:22:19AM +0100, Guido Draheim wrote: [...] There is no redesign required - this problem can only occur on non-x86 little-endian platforms. You did not tell about that detail but I can guess it from the result. In fetch.h there is #define zzip_file_header_get_crc32(__p) ZZIP_GET32((__p)-z_crc32) and that ZZIP_GET32 can be defined in a way that it would fetch each byte seperately. This is already done on a lot of platforms - the definition is dependent on ZZIP_WORDS_BIGENDIAN and covers acrchitectures like SPARC which have aligned word access as well. However, SPARC is big-endian as have been all the other test platforms in the lab. So, what's your target platform currently? If I am guessing right then would need to redefine the #ifdefs and configure detections in such a way that it would enable a bytewise access macro on a litte-endian platform right there in fetch.h Sparc is big-endian, but that's not what causes a problem here (even though it would be nice to check that endianness is detected correctly for sparc). Let's say that the macro which will get used is this one: # define ZZIP_GET32(__p) bswap_32(*(uint32_t*)(__p)) This will only work on sparc if the address __p is word-aligned (divisible by 4). Compiler is likely to generate a single load-word instruction for that, and if __p is not word-aligned, then the process will get a SIGBUS. Normally, it happens automatically, i.e. if you define an int (of size 4) field inside a struct, then compiler will take care of allocating memory for it in such a way that it is word-aligned. However, since the structures in format.h are defined mostly using arrays of zzip_byte_t, there is no way the compiler can guess which of them should be aligned, so it places them arbitrarily. Thus, attempt to cast the value to uint32_t fails. Best regards, Hi Jurij, checking into the codebase I find that there is already a configure time check for ZZIP_HAVE_ALIGNED_ACCESS_REQUIRED - is that being enabled in the generated $build/zzip/_config ? I would like to disable the Linux bswap optimization in that case (so it is left enabled for all other Linux platforms that allow misaligned access). I am going to commit a change that looks for that additional configure value anyway. I hope this fixes the problem. cheers, Guido -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of unsubscribe. Trouble? Contact [EMAIL PROTECTED]
Bug#443880: SIGBUS on sparc
Jurij Smakov schrieb: Hi, I've done further investigation since it's still failing. A detailed trace I've obtained from a SIGBUS during lua-zip build: Core was generated by `lua5.1 -l zip tests/test_zip.lua'. Program terminated with signal 10, Bus error. #0 0x7008293c in __zzip_parse_root_directory (fd=3, trailer=0xffd66d58, hdr_return=0x47dc0, io=0x70098020) at ../../zzip/zip.c:440 440 hdr-d_crc32 = zzip_disk_entry_get_crc32 (d); (gdb) bt full #0 0x7008293c in __zzip_parse_root_directory (fd=3, trailer=0xffd66d58, hdr_return=0x47dc0, io=0x70098020) at ../../zzip/zip.c:440 __bsx = 4292242562 d = (struct zzip_disk_entry *) 0xffd66c82 u_extras = 0 u_comment = 0 u_namlen = 6 dirent = {z_magic = PK\001\002, z_encoder = {version = \024, ostype = }, z_extract = {version = \024, ostype = }, z_flags = \000, z_compr = \b, z_dostime = { time = )£, date = Ù0}, z_crc32 = 㦢O, z_csize = |\000\000, z_usize = \237\000\000, z_namlen = \006, z_extras = \000, z_comment = \000, z_diskstart = \000, z_filetype = \001, z_filemode = \000\000, z_offset = \000\000\000} hdr = (struct zzip_dir_hdr *) 0x47ec0 hdr0 = (struct zzip_dir_hdr *) 0x47ec0 p_reclen = (uint16_t *) 0x0 entries = 4 zz_offset = 0 fd_map = 0x70074000 Address 0x70074000 out of bounds zz_fd_gap = 4826 zz_entries = 4 zz_rootsize = 214 zz_rootseek = 4826 #1 0x70083238 in __zzip_dir_parse (dir=0x47da8) at ../../zzip/zip.c:661 rv = ZZIP_NO_ERROR filesize = 5062 trailer = {zz_tail = 0x13b0, zz_for_correct_rootseek = 0x703241ac, zz_entries = 4, zz_finalentries = 4, zz_rootseek = 4826, zz_rootsize = 214} #2 0x700830b0 in zzip_dir_fdopen_ext_io (fd=3, errcode_p=0x0, ext=0x70098014, io=0x70098020) at ../../zzip/zip.c:622 rv = 270344 dir = (ZZIP_DIR *) 0x47da8 #3 0x700834ec in zzip_dir_open_ext_io (filename=0x4a400 luazip.zip, e=0x0, ext=0x70098014, io=0x70098020) at ../../zzip/zip.c:726 fd = 3 #4 0x7008343c in zzip_dir_open (filename=0x4a400 luazip.zip, e=0x0) at ../../zzip/zip.c:708 No locals. #5 0x700618e0 in ?? () No symbol table info available. #6 0x700618e4 in ?? () No symbol table info available. Backtrace stopped: previous frame identical to this frame (corrupt stack?) (gdb) print d-z_crc32 $1 = (zzip_byte_t (*)[4]) 0xffd66c92 Here's the problem: z_crc32 (and all other fields in this structure) are defined as zzip_byte_t arrays, which means that compiler does not care about their alignment. When an attempt is made to cast z_crc32 to a 32-bit integer, it gets a SIGBUS, since z_crc32 is only half-word aligned. I don't see a way to fix this without a major redesign or making all the memory-accessing/casting macros in format.h to use memcpy (ugly). Best regards, There is no redesign required - this problem can only occur on non-x86 little-endian platforms. You did not tell about that detail but I can guess it from the result. In fetch.h there is #define zzip_file_header_get_crc32(__p) ZZIP_GET32((__p)-z_crc32) and that ZZIP_GET32 can be defined in a way that it would fetch each byte seperately. This is already done on a lot of platforms - the definition is dependent on ZZIP_WORDS_BIGENDIAN and covers acrchitectures like SPARC which have aligned word access as well. However, SPARC is big-endian as have been all the other test platforms in the lab. So, what's your target platform currently? If I am guessing right then would need to redefine the #ifdefs and configure detections in such a way that it would enable a bytewise access macro on a litte-endian platform right there in fetch.h cheers, Guido -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of unsubscribe. Trouble? Contact [EMAIL PROTECTED]
Bug#443880: SIGBUS on sparc
On Mon, Mar 03, 2008 at 11:22:19AM +0100, Guido Draheim wrote: [...] There is no redesign required - this problem can only occur on non-x86 little-endian platforms. You did not tell about that detail but I can guess it from the result. In fetch.h there is #define zzip_file_header_get_crc32(__p) ZZIP_GET32((__p)-z_crc32) and that ZZIP_GET32 can be defined in a way that it would fetch each byte seperately. This is already done on a lot of platforms - the definition is dependent on ZZIP_WORDS_BIGENDIAN and covers acrchitectures like SPARC which have aligned word access as well. However, SPARC is big-endian as have been all the other test platforms in the lab. So, what's your target platform currently? If I am guessing right then would need to redefine the #ifdefs and configure detections in such a way that it would enable a bytewise access macro on a litte-endian platform right there in fetch.h Sparc is big-endian, but that's not what causes a problem here (even though it would be nice to check that endianness is detected correctly for sparc). Let's say that the macro which will get used is this one: # define ZZIP_GET32(__p) bswap_32(*(uint32_t*)(__p)) This will only work on sparc if the address __p is word-aligned (divisible by 4). Compiler is likely to generate a single load-word instruction for that, and if __p is not word-aligned, then the process will get a SIGBUS. Normally, it happens automatically, i.e. if you define an int (of size 4) field inside a struct, then compiler will take care of allocating memory for it in such a way that it is word-aligned. However, since the structures in format.h are defined mostly using arrays of zzip_byte_t, there is no way the compiler can guess which of them should be aligned, so it places them arbitrarily. Thus, attempt to cast the value to uint32_t fails. Best regards, -- Jurij Smakov [EMAIL PROTECTED] Key: http://www.wooyd.org/pgpkey/ KeyID: C99E03CC -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of unsubscribe. Trouble? Contact [EMAIL PROTECTED]
Bug#443880: SIGBUS on sparc
Hi, I've done further investigation since it's still failing. A detailed trace I've obtained from a SIGBUS during lua-zip build: Core was generated by `lua5.1 -l zip tests/test_zip.lua'. Program terminated with signal 10, Bus error. #0 0x7008293c in __zzip_parse_root_directory (fd=3, trailer=0xffd66d58, hdr_return=0x47dc0, io=0x70098020) at ../../zzip/zip.c:440 440 hdr-d_crc32 = zzip_disk_entry_get_crc32 (d); (gdb) bt full #0 0x7008293c in __zzip_parse_root_directory (fd=3, trailer=0xffd66d58, hdr_return=0x47dc0, io=0x70098020) at ../../zzip/zip.c:440 __bsx = 4292242562 d = (struct zzip_disk_entry *) 0xffd66c82 u_extras = 0 u_comment = 0 u_namlen = 6 dirent = {z_magic = PK\001\002, z_encoder = {version = \024, ostype = }, z_extract = {version = \024, ostype = }, z_flags = \000, z_compr = \b, z_dostime = { time = )£, date = Ù0}, z_crc32 = 㦢O, z_csize = |\000\000, z_usize = \237\000\000, z_namlen = \006, z_extras = \000, z_comment = \000, z_diskstart = \000, z_filetype = \001, z_filemode = \000\000, z_offset = \000\000\000} hdr = (struct zzip_dir_hdr *) 0x47ec0 hdr0 = (struct zzip_dir_hdr *) 0x47ec0 p_reclen = (uint16_t *) 0x0 entries = 4 zz_offset = 0 fd_map = 0x70074000 Address 0x70074000 out of bounds zz_fd_gap = 4826 zz_entries = 4 zz_rootsize = 214 zz_rootseek = 4826 #1 0x70083238 in __zzip_dir_parse (dir=0x47da8) at ../../zzip/zip.c:661 rv = ZZIP_NO_ERROR filesize = 5062 trailer = {zz_tail = 0x13b0, zz_for_correct_rootseek = 0x703241ac, zz_entries = 4, zz_finalentries = 4, zz_rootseek = 4826, zz_rootsize = 214} #2 0x700830b0 in zzip_dir_fdopen_ext_io (fd=3, errcode_p=0x0, ext=0x70098014, io=0x70098020) at ../../zzip/zip.c:622 rv = 270344 dir = (ZZIP_DIR *) 0x47da8 #3 0x700834ec in zzip_dir_open_ext_io (filename=0x4a400 luazip.zip, e=0x0, ext=0x70098014, io=0x70098020) at ../../zzip/zip.c:726 fd = 3 #4 0x7008343c in zzip_dir_open (filename=0x4a400 luazip.zip, e=0x0) at ../../zzip/zip.c:708 No locals. #5 0x700618e0 in ?? () No symbol table info available. #6 0x700618e4 in ?? () No symbol table info available. Backtrace stopped: previous frame identical to this frame (corrupt stack?) (gdb) print d-z_crc32 $1 = (zzip_byte_t (*)[4]) 0xffd66c92 Here's the problem: z_crc32 (and all other fields in this structure) are defined as zzip_byte_t arrays, which means that compiler does not care about their alignment. When an attempt is made to cast z_crc32 to a 32-bit integer, it gets a SIGBUS, since z_crc32 is only half-word aligned. I don't see a way to fix this without a major redesign or making all the memory-accessing/casting macros in format.h to use memcpy (ugly). Best regards, -- Jurij Smakov [EMAIL PROTECTED] Key: http://www.wooyd.org/pgpkey/ KeyID: C99E03CC