reinterpret_cast issue on solaris

T

tkirankumar

Hi all,
This is regarding the issue I am facing while porting the my
application from SuSe Linux to
Sun Solaris.

The Existing system details:
Itanium boxes 1mhz 4 processor 8 gb machines with SuSe Linux

$ uname -a
Linux longrtedged01 2.4.21-215-itanium2-smp #1 SMP Mon Apr 26 16:28:29
UTC 2004 ia64

The New system Details:
Fujitsu 850 machines 2mhz 16 Sparc processor 32 GB machines running
solaris 10
$ uname -a
SunOS cbmrsd1a1 5.10 Generic_118833-17 sun4us sparc FJSV,GPUZC-M

reinterpret_cast is dumping the core in solaris

*reinterpret_cast< ValueType* >( mNextWriteAddress ) = aValue;

Here aValue is a Template ValueType which can be either int or long or
double. i.e

ValueType aValue;

Same thing is perfectly working in Linux.

I use g++ compiler
g++ -v
Reading specs from
/usr/local/lib/gcc-lib/sparc-sun-solaris2.10/3.3.2/specs
Configured with: ../configure --with-as=/usr/ccs/bin/as
--with-ld=/usr/ccs/bin/ld --disable-nls
Thread model: posix
gcc version 3.3.2

Help me sort out the issue
 
M

Michael Oswald

Hi all,

reinterpret_cast is dumping the core in solaris

*reinterpret_cast< ValueType* >( mNextWriteAddress ) = aValue;

Here aValue is a Template ValueType which can be either int or long or
double. i.e

Hard to say, but my first guess is an alignment problem. The Sparc
processors cannot access types which need alignment on a non-aligned
address. So if mNextWriteAdress is not on an alignment boundary, the
application normally terminates with a SIGBUS signal. Check, if it is a
SIGBUS and look if mNextWriteAdress is an aligned adress.

If that is not the case, you should present a bit more code.


lg,
Mike
 
T

tkirankumar

Thanks Michael for the message -
It is actually a SIGBUS.
And I could not quite understand about the alignment and non-alignment
concept that you have written. Can you please elaborate, so that I
could check mNextWriteAdress is an aligned address or no-aligned?

Thanks in Advance
 
M

Michael Oswald

Thanks Michael for the message -
It is actually a SIGBUS.
And I could not quite understand about the alignment and non-alignment
concept that you have written. Can you please elaborate, so that I
could check mNextWriteAdress is an aligned address or no-aligned?


Ok, as an example: lets assume aValue is a double and a double has a
sizeof(double) == 8. Let's assume further the Sparc has an alignment of
4 Bytes (the Sparcs I worked with had an alignment of 4 bytes, could be
different for yours...).

If you take the address of a double like

double d;
double* ptr = &d;

the ptr would (on this theoretical machine) be aligned to an 4 byte
boundary, this means the address must be divideable by 4 without
remainder (assuming this machine is a 32 Bit machine with 32 Bit
pointers and a long is 32 Bits) the following MUST hold:

(reinterpret_cast<unsigned long>(ptr) % 4) == 0

In your example

*reinterpret_cast< ValueType* >( mNextWriteAddress ) = aValue;

mNextWriteAddress could be anything, so the expression

(reinterpret_cast<unsigned long>( mNextWriteAddress) %8) could be != 0
which results in the SIGBUS.

Of course this is machine specific, so your Sparc might have a different
alignment.

You can imagine it like this:

Address Value
0x0000 0x11 0x22 0x33 0x44
0x0004 0x00 0x00 0x00 0x00

at 0x0000 there would be an aligned 32 Bit value 0x11223344 (let's
silently forget the byte order issues) and on 0x004 the value woudl be
0. Both values can be accessed with a normal 32-Bit instruction

In your example this could happen:


0x0000 0x00 0x11 0x22 0x33
0x0004 0x44 0x00 0x00 0x00

So the value 0x11223344 would start on address 0x0001 and not on 0x0000,
but the 32-Bit instruction cannot access 32 Bits from 0x0001.
On Intel machines, this is normally no problem, a Sparc is a little pickier.

The solution would be either use a different design, or make sure, that
mNextWriteAddress is aligned.
For example on a 4-Byte alignment (untested code!):

// convert to some pointer to byte-size
uint8_t* ptr = reinterpret_cast<uint8_t*>(mNextWriteAddress);
// align to 4 byte boundary
ptr += (ptr % 4 ? (4 - ptr % 4) : 0);
// set value
*reinterpret_cast< ValueType* >( ptr ) = aValue;

With this code you have to be sure that reading and writing is
synchronous, so you'll have to do the same on reading. And, since there
will be some bytes skipped, these should be initialised before (with
e.g. 0). And always be aware, that this is machine specific and not
fully portable!


lg,
Michael
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,262
Messages
2,571,049
Members
48,769
Latest member
Clifft

Latest Threads

Top