-- ________________________________________________ | Fabio Bossi - ISIS CEC Ispra (Va) - Italy | | Tel: +39 332 789840 | | Fax: +39 332 785815 | | X.400: g=Fabio;s=Bossi;;p=ccrispra;a=garr;c=it | |________________________________________________| -------------------------- A typical way to obtain this sort of errors (in Fortran) is to have n-bit words not aligned on natural boundaries. E.g in a COMMON block if you have REAL*8 D REAL*4 R INTEGER*4 J INTEGER*2 I COMMON /XX/D,R,J,I everything is fine, all items are aligned on natural boundaries. If instead one declares COMMON /XX/I,J,D,R one has a bad alignment (a 16-bit word followed by a 32-bit word at an unnatural boundary, and also the nexg 64-bit word is unaligned) The same sort of thing can occur using the EQUIVALENCE statement. REAL*8 D REAL*4 R(10) EQUIVALENCE (D,R(2)) is unaligned (while D can be equivalenced with R(1) or R(5) or R(9)) Similar things can occur with record arrangents. Most compilers are smart enough to work around this, but at a price of slower performance, if many fixups are needed (e.g. in loops). > Is there a way to prevent the appearance of these messages, or better, to > fix the problem easily ? uac p noprint suppresses the messages (see man uac) ---------------------------------------------------------------------------- Lucio Chiappetti - IFCTR/CNR - via Bassini 15 - I-20133 Milano (Italy) ---------------- I don't know about Pro C, but we see this when we use #pragma pack(1) or gcc's __attribute__ ((packed)); you can get unaligned access errors if you don't align fields in a structure to their natural boundries. We use this for network communcation. Another common souce of these errors can occur when you align the members by hand properly, but then don't pad out the structure to an even # of bytes for the first element in the array #pragma pack(1) struct foo { int a; char b; }; #pragma pack(8) So sizeof (struct foo) == 5. this is OK for one instance of the structure, but bad news if you want an array of 2 or more lelements. foo_ptr = malloc (sizeof (foo) * 2) accessing foo_ptr[1].a is now going to give unaligned access errors. --------------------------------------------------------------------------- Another common thing that can happen is when you copy elements into a (unsigned char *) buffer and cast them to short, int, long, or pointers: Say someone sends you a 5 byte packet. The first byte is the length of a packet, the next 4 bytes are a 4 byte integer: unsigned char buf[5] my_int = *(int *)(buf+1) will give an unaligned access errors. memcpy (&my_int, buf+1, sizeof(int)); Will not. -Eric. --------------------------------- In modern RISC processors, the address for a memory fetch of a certain size must be evenly divisible by its size; i.e. a 8-byte floating point number must be at an address that is a multiple of 8. An 8-bit char can start at any address. If you had code like: struct test { char schv_char; double sdfv_valu; }; The compiler must determine the largest size object in the struct, double thus 8 bytes, ensure that all instances of struct test are stored starting at an address that is a multiple of 8, and insert 7 bytes of padding between schv_char and sdfv_valu to ensure sdfv_valu is at an address that is a multiple of 8. C normally handles this properly. Fortran does not. If you have to assess binary data where the double is not aligned, then use memcpy: unsigned char lcha_data[256]; double ldfv_valu ; memcpy ( &ldfv_valu,&lcha_data[123],sizeof ( ldfv_valu ) ); The cure for Fortran common blocks is to either put the largest sized variables first or to separate the variables of like size into a separate common block. ------------------------- Hi, you get these messages when ou're reading/writing an integer or double which is not on an 8 byte boundary. eg. double *n=0x03; *n = 1.0 this will result in such a warning. You can toggle off these messages by the uac command. type man uac :-) To debug it, you need the sources and then let uac dump core when it encounters such a condition .... Hopt this helps a bit -------------------- An unaligned access is bad- it's just that the OS is being nice and fixing things up for you. Basically, it means that a word-access was not word-aligned. For instance, on a 64-bit alpha, a 64-bit access to address 0x1400001b0 is okay, because it's 64-bit aligned, as is 0x1400001b8. A 64-bit access to 0x1400001b4, however, would be unaligned. This causes an unaligned access exception to be raised, which is handled by breaking the access into the obvious two 32-bit accesses. The way to fix this would be to determine where you are performing the access, and figure out why you are performing this access. The most common case is ported code which casts a pointer into the middle of a buffer to a pointer to a long, and dereferences it. The uac command controls what happens on unaligned access. By default, a warning is printed, "uac p 0" will turn off the printed warning, though I don't recommend doing this- your bug is still there. "uac p sigbus" will cause SIGBUS to be delivered to the process whenever it performs the unaligned access- this enables the programmer to determine exactly where the access is occurring, using standard debugging techniques (a la dbx). -Jim.Zelenka_at_cs.cmu.edu ---------------------- The following is copied from the archives of this list (I searched on unaligned access): > Here is a summary of the replies to my question (below). > > 1- The code needs to be 64-bit clean. > > 2- The error messages can be disabled by typing the command > "uac p 0" > > (it works) > > 3- Compilation flages like "-align dcommons", for Fortran, and > "-migrate", for C, will produce a 64-bit clean executable. > > (it works fine) "uac p 0" simply turns off the error messages. It doesn't do anything to improve performance. Guy Dallaire dallaire_at_total.net "God only knows if god exists"Received on Thu Apr 03 1997 - 18:32:00 NZST
This archive was generated by hypermail 2.4.0 : Wed Nov 08 2023 - 11:53:36 NZDT