"Bus error" please help, I am going insane!

"Bus error" please help, I am going insane!

Post by Imra » Sun, 17 Mar 2002 01:12:20



On solaris, I am writing a client/server gizmo using sockets.  Now, the
problem I'm running into is this:

I have an array of void*.

void *myargs[ HOWEVERMANYIWANT ]

I pass this array to a function:

myfunction( void **args ) { ...

Now, inside that function I try and dereference the args, depending on the
type I stuffed into it earlier.

int i = *(int*)args[0];

(Can you believe that this blows up in my face and gives me a "Bus
Error"??!!)
(Maybe you can...so then let me know!)

Now, maybe it is important to know that the original args array of void *'s
was declared in a static library, and linked in with the program.  It is
also certainly large enough for the integer.

But now here comes the amazing part, in the de*, when I do a:
'print args[0]'
it spits out an address 'xxxyyy', when I examined the memory at this
address, it pointed to exactly the integer I wanted in the first place
(namely, 0xDEADBEEF ).

Further confusing me completely is the fact that a
memcpy ( &someint, args[0], sizeof( int ) ); ----> works! yay, i got my
integer.

BUT, if I use the type 'double' ( memcpy( &somedouble, args[0], sizeof(
double) ) ),
this fails, with.....sadly....a "Bus Error".

In the de*, the error is reported as a segmentation violation.
However, when run on its own the error is "Bus error".

People, I am going insane....If you read through this all the way, I say to
you, thanks.  I appreciate any help.  Please let me know whats going on!

Imran

 
 
 

"Bus error" please help, I am going insane!

Post by Mosh » Sun, 17 Mar 2002 01:29:59


Imran had nothing better to do than to say:

Quote:> int i = *(int*)args[0];
> (Can you believe that this blows up in my face and gives me a "Bus
> Error"??!!)

Well, yes... You may be accessing over word (32-bit) boundaries. Some
platforms (e.g., Linux) support that, while others (e.g. Solaris), don't.

Quote:> But now here comes the amazing part, in the de*, when I do a:
> 'print args[0]' it spits out an address 'xxxyyy', when I examined the
> memory at this address, it pointed to exactly the integer I wanted in
> the first place (namely, 0xDEADBEEF ).

The de* could use a safer method of accessing the values. That's
probably no proof of anything.

Quote:> Further confusing me completely is the fact that a
> memcpy ( &someint, args[0], sizeof( int ) ); ----> works! yay, i got my
> integer.

That's what I was going to suggest... has always worked for me.
But don't you mean &args[0] ? You need a pointer to the memory you're
copying. Have you verified that the value you get into someint is actually
*correct*?

Quote:> BUT, if I use the type 'double' ( memcpy( &somedouble, args[0], sizeof(
> double) ) ), this fails, with.....sadly....a "Bus Error".

See above.

Moshe

--
*** SPAM BLOCK: Remove bra before replying! ***
Moshe Jacobson :: http://www.veryComputer.com/ :: moshe at runslinux dot net

 
 
 

"Bus error" please help, I am going insane!

Post by Imra » Sun, 17 Mar 2002 01:41:37


Quote:> But don't you mean &args[0] ? You need a pointer to the memory you're
> copying. Have you verified that the value you get into someint is actually
> *correct*?

Yup, the integer value is correct.  I want to copy the memory pointed to by
args[0], which is a void*. &args[0] would mean address of pointer to void,
that would actually copy the pointer, not the data right?
Quote:

> > BUT, if I use the type 'double' ( memcpy( &somedouble, args[0], sizeof(
> > double) ) ), this fails, with.....sadly....a "Bus Error".

 
 
 

"Bus error" please help, I am going insane!

Post by Donald McLachl » Sun, 17 Mar 2002 01:47:54



> On solaris, I am writing a client/server gizmo using sockets.  Now, the
> problem I'm running into is this:

> I have an array of void*.

> void *myargs[ HOWEVERMANYIWANT ]

> I pass this array to a function:

> myfunction( void **args ) { ...

> Now, inside that function I try and dereference the args, depending on the
> type I stuffed into it earlier.

> int i = *(int*)args[0];

> (Can you believe that this blows up in my face and gives me a "Bus
> Error"??!!)
> (Maybe you can...so then let me know!)

On sparcs, ints are 4 bytes and must be aligned on 4-byte boundaries.
What is the address of args[0]?  Is it 4-byte aligned?
Try printf("%x\n, args[0]);

Quote:> Further confusing me completely is the fact that a
> memcpy ( &someint, args[0], sizeof( int ) ); ----> works! yay, i got my
> integer.

This seems to support my guess.  memcpy() will copy non-word aligned bytes OK,
int *x = odd_address; int y = *x will not copy non-word aligned bytes.

How do you load the int pointer into myargs[]?  int x; myargs[i] = &x?

--

Communications Research Centre / RNS    Tel     (613) 998-2845
3701 Carling Ave.,                      Fax     (613) 998-9648
Ottawa, Ontario
K2H 8S2
Canada

 
 
 

"Bus error" please help, I am going insane!

Post by Joe Durusa » Sun, 17 Mar 2002 04:50:36



> Imran had nothing better to do than to say:
> > int i = *(int*)args[0];
> > (Can you believe that this blows up in my face and gives me a "Bus
> > Error"??!!)

> Well, yes... You may be accessing over word (32-bit) boundaries. Some
> platforms (e.g., Linux) support that, while others (e.g. Solaris), don't.

> > But now here comes the amazing part, in the de*, when I do a:
> > 'print args[0]' it spits out an address 'xxxyyy', when I examined the
> > memory at this address, it pointed to exactly the integer I wanted in
> > the first place (namely, 0xDEADBEEF ).

> The de* could use a safer method of accessing the values. That's
> probably no proof of anything.

> > Further confusing me completely is the fact that a
> > memcpy ( &someint, args[0], sizeof( int ) ); ----> works! yay, i got my
> > integer.

> That's what I was going to suggest... has always worked for me.
> But don't you mean &args[0] ? You need a pointer to the memory you're
> copying. Have you verified that the value you get into someint is actually
> *correct*?

> > BUT, if I use the type 'double' ( memcpy( &somedouble, args[0], sizeof(
> > double) ) ), this fails, with.....sadly....a "Bus Error".

> See above.

> Moshe

> --
> *** SPAM BLOCK: Remove bra before replying! ***
> Moshe Jacobson :: http://www.veryComputer.com/ :: moshe at runslinux dot net

Let me re-emphasize the necessity of specifying the platform and OS
in this situation.  Otherwise, you will only get guesses.  For example,
on SPARC hardware, non-sligned addresses are the most common cause of
bus errors.  

Speaking only for myself,

Joe Durusau

 
 
 

"Bus error" please help, I am going insane!

Post by Imra » Sun, 17 Mar 2002 02:02:15


Thanks,

Yes, this was late last night, and I remember args[0] was not word aligned
(it ended with an 'a').  Thats when I tried the memcpy() approach.  Which
works for ints, short,long, char, but fails for double.

I also load the value in a similar way to what you said:
(msg is a char *, the integer is located at message_offset, I verified this
in the de*)
    args[i] = &( msg[ message_offset ]);
but I have also tried a memcpy approach.
    char * tmp = &(msg[ message_offset ]);
    memcpy( &(args[i]), &(tmp), sizeof( void*) );




> > On solaris, I am writing a client/server gizmo using sockets.  Now, the
> > problem I'm running into is this:

> > I have an array of void*.

> > void *myargs[ HOWEVERMANYIWANT ]

> > I pass this array to a function:

> > myfunction( void **args ) { ...

> > Now, inside that function I try and dereference the args, depending on
the
> > type I stuffed into it earlier.

> > int i = *(int*)args[0];

> > (Can you believe that this blows up in my face and gives me a "Bus
> > Error"??!!)
> > (Maybe you can...so then let me know!)

> On sparcs, ints are 4 bytes and must be aligned on 4-byte boundaries.
> What is the address of args[0]?  Is it 4-byte aligned?
> Try printf("%x\n, args[0]);

> > Further confusing me completely is the fact that a
> > memcpy ( &someint, args[0], sizeof( int ) ); ----> works! yay, i got my
> > integer.

> This seems to support my guess.  memcpy() will copy non-word aligned bytes
OK,
> int *x = odd_address; int y = *x will not copy non-word aligned bytes.

> How do you load the int pointer into myargs[]?  int x; myargs[i] = &x?

> --

> Communications Research Centre / RNS Tel (613) 998-2845
> 3701 Carling Ave., Fax (613) 998-9648
> Ottawa, Ontario
> K2H 8S2
> Canada

 
 
 

"Bus error" please help, I am going insane!

Post by Donald McLachl » Sun, 17 Mar 2002 03:21:54



> Thanks,

> Yes, this was late last night, and I remember args[0] was not word aligned
> (it ended with an 'a').  Thats when I tried the memcpy() approach.  Which
> works for ints, short,long, char, but fails for double.

> I also load the value in a similar way to what you said:

Um, I said:

        int x;
        arg[0] = &x;                /* copies an int ptr to a void ptr */

This is not at all like the following code you provided which copies 4 bytes
at some address into the 4 bytes of a void ptr. (unless msg is declared
int msg[] ... but I'm guessing msg is declared as char msg[])

Quote:> (msg is a char *, the integer is located at message_offset, I verified this
> in the de*)
>     args[i] = &( msg[ message_offset ]);
> but I have also tried a memcpy approach.
>     char * tmp = &(msg[ message_offset ]);
>     memcpy( &(args[i]), &(tmp), sizeof( void*) );

If you are going to use a non-aligned ptr, you will have to memcpy your data out
of that address into you data, (as you described doing earlier).

        int y;
        memcpy(&y, arg[0], sizeof(y));      /* copies 4 bytes of mem into the void ptr */

--

Communications Research Centre / RNS    Tel     (613) 998-2845
3701 Carling Ave.,                      Fax     (613) 998-9648
Ottawa, Ontario
K2H 8S2
Canada

 
 
 

"Bus error" please help, I am going insane!

Post by Kurtis D. Rade » Sun, 17 Mar 2002 13:42:05



> Imran had nothing better to do than to say:
>> int i = *(int*)args[0];
>> (Can you believe that this blows up in my face and gives me a "Bus
>> Error"??!!)

> Well, yes... You may be accessing over word (32-bit) boundaries. Some
> platforms (e.g., Linux) support that, while others (e.g. Solaris), don't.

I think you meant to say something else. The operating system is not a factor.
The CPU and/or system architecture is. That is, some CPUs require specific
memory alignment for some data types. Others may allow a non-aligned access
but with a performance penalty. That is one of the reasons why the C language
allows the compiler to insert arbitrary padding between structure members.