--
________________________________________________
| 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