core dump of simple test program
Web Server forum
Back To The Forum Home!Search!Private Messaging System

Web Server Talk Web Server Talk > Unix and Linux reviews > Free Unix support > Unix Programming > core dump of simple test program




  Last Thread   Next Thread Next
  Show Printable Version Email this Page Subscribe to this Thread      Post New Thread    Post A Reply      

    core dump of simple test program  
Jaguk Ku


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
12-23-04 12:47 PM

Hi there,

I made a simple test program below

=======================================
#include <stdio.h>

struct _TEST {
char    s1[4];
char    s2[10];
} TEST;

int main()
{
memset(&TEST, 0x00, sizeof(TEST));

*(int*)TEST.s2 = 10;

printf("s2=%d\n", *(int*)TEST.s2);

exit(0);
}
=======================================
the output is normal like below
s2=10

but when i change struct _TEST little bit like below

=======================================
struct _TEST {
char    s1[3];
char    s2[10];
} TEST;
=======================================

it suddenly died with core dump when i executed it.
I don't know what is wrong.

Thanks in advance,

Jaguk Ku







[ Post a follow-up to this message ]



    Re: core dump of simple test program  
Jens.Toerring@physik.fu-berlin.de


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
12-23-04 12:47 PM

Jaguk Ku <jkku@softeleware.com> wrote:
> I made a simple test program below

> =======================================
> #include <stdio.h>

> struct _TEST {
>     char    s1[4];
>     char    s2[10];
> } TEST;

> int main()
> {
>     memset(&TEST, 0x00, sizeof(TEST));

>     *(int*)TEST.s2 = 10;

>     printf("s2=%d\n", *(int*)TEST.s2);

>     exit(0);
> }
> =======================================
> the output is normal like below
> s2=10

> but when i change struct _TEST little bit like below

> =======================================
> struct _TEST {
>     char    s1[3];
>     char    s2[10];
> } TEST;
>  =======================================[
/vbcol]
[vbcol=seagreen]
> it suddenly died with core dump when i executed it.
> I don't know what is wrong.

What you get here is a "bus error" and that is due to an alignment
problem. You seem to be using a processor that has certain restric-
tions when accessing multi-byte quantities (like an int) at once -
they must start on even addresses (or even addresses that start on
addresses that can be divided by 4 etc). That's because an access
like

* ( int * ) TEST.s2 = 10;

will be translated to machine code that uses instructions that move
2, 4 or 8 bytes (depending on the sizeof(int) on your machine) a
once, but expect a properly aligned address to work with.

When you have a structure like

> struct _TEST {
>     char    s1[4];
>     char    s2[10];
> } TEST;

's2' is going to be at an address that can be devided by 4, so if
you try to use 's2' as an int pointer it my still work since, by
luck, it's at an acceptable address. But when you change the
structure to

> struct _TEST {
>     char    s1[3];
>     char    s2[10];
> } TEST;

's2' is now at an odd address and trying to treat that as an int
pointer won't work with your processor (actually, even on CPUs
where you don't get a bus error with this it will probably still
be a significantly slower than a well-aligned access).

That's also the reason why the compiler is allowed to insert as
many "padding" bytes between the elements of a structure. If you
would change your structure to

> struct _TEST {
>     char    s1[3];
>     int    s2;
> } TEST;

and would check the offset of 's2' from the start of the structure
you will find that it isn't 3 (as one may expect by just counting
bytes) but 4 to take care of the alignment requirements on your
machine - to do that the compiler inserts an extra byte between 's1'
and 's2'. So never assume that sizeof(TEST) is equal to the sum of
the sizes of its components!

For that reason you should be very careful with casting between
pointers to different types - they can have different alignment
requirements, thus using what's really a char pointer as an int
pointer might get you in lots of trouble. The most evil thing
is that it might even work on a certain type of CPU but break the
program when you try to port it to a different architecture. So,
if you have to assign e.g. the data from an int to what's pointed
to by a char pointer, always make sure to use memcpy() - that
guarantees that you won't get problems with alignment requirements.

Finally, just for your information, the use of identifiers starting
with an underscore is not allowed in normal C programs - identifiers
starting with a leading underscore are reserved for the implementa-
tion, i.e. for use by the compiler and system header files etc. In
your case correcting this isn't a problems since

struct TEST {
char    s1[3];
char    s2[10];
} TEST;

will also do perfectly well, as will do

struct {
char    s1[3];
char    s2[10];
} TEST;

Regards, Jens
--
\   Jens Thoms Toerring  ___  Jens.Toerring@physik.fu-berlin.de
\__________________________  http://www.toerring.de





[ Post a follow-up to this message ]



    Re: core dump of simple test program  
Dan Mercer


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
12-23-04 11:00 PM


<Jens.Toerring@physik.fu-berlin.de> wrote in message news:32vljgF3qu8s3U1@un
i-berlin.de...
: Jaguk Ku <jkku@softeleware.com> wrote:
: > I made a simple test program below
:
: > =======================================
: > #include <stdio.h>
:
: > struct _TEST {
: >     char    s1[4];
: >     char    s2[10];
: > } TEST;
:
: > int main()
: > {
: >     memset(&TEST, 0x00, sizeof(TEST));
:
: >     *(int*)TEST.s2 = 10;
:
: >     printf("s2=%d\n", *(int*)TEST.s2);
:
: >     exit(0);
: > }
: > =======================================
: > the output is normal like below
: > s2=10
:
: > but when i change struct _TEST little bit like below
:
: > =======================================
: > struct _TEST {
: >     char    s1[3];
: >     char    s2[10];
: > } TEST;
: > =======================================
:
: > it suddenly died with core dump when i executed it.
: > I don't know what is wrong.
:
: What you get here is a "bus error" and that is due to an alignment
: problem. You seem to be using a processor that has certain restric-
: tions when accessing multi-byte quantities (like an int) at once -
: they must start on even addresses (or even addresses that start on
: addresses that can be divided by 4 etc). That's because an access
: like
:
: * ( int * ) TEST.s2 = 10;
:
: will be translated to machine code that uses instructions that move
: 2, 4 or 8 bytes (depending on the sizeof(int) on your machine) a
: once, but expect a properly aligned address to work with.
:
: When you have a structure like
:
: > struct _TEST {
: >     char    s1[4];
: >     char    s2[10];
: > } TEST;
:
: 's2' is going to be at an address that can be devided by 4, so if
: you try to use 's2' as an int pointer it my still work since, by
: luck, it's at an acceptable address. But when you change the
: structure to
:
: > struct _TEST {
: >     char    s1[3];
: >     char    s2[10];
: > } TEST;
:
: 's2' is now at an odd address and trying to treat that as an int
: pointer won't work with your processor (actually, even on CPUs
: where you don't get a bus error with this it will probably still
: be a significantly slower than a well-aligned access).
:
: That's also the reason why the compiler is allowed to insert as
: many "padding" bytes between the elements of a structure. If you
: would change your structure to
:
: > struct _TEST {
: >     char    s1[3];
: >     int    s2;
: > } TEST;
:
: and would check the offset of 's2' from the start of the structure
: you will find that it isn't 3 (as one may expect by just counting
: bytes) but 4 to take care of the alignment requirements on your
: machine - to do that the compiler inserts an extra byte between 's1'
: and 's2'. So never assume that sizeof(TEST) is equal to the sum of
: the sizes of its components!
:
: For that reason you should be very careful with casting between
: pointers to different types - they can have different alignment
: requirements, thus using what's really a char pointer as an int
: pointer might get you in lots of trouble. The most evil thing
: is that it might even work on a certain type of CPU but break the
: program when you try to port it to a different architecture. So,
: if you have to assign e.g. the data from an int to what's pointed
: to by a char pointer, always make sure to use memcpy() - that
: guarantees that you won't get problems with alignment requirements.
:
: Finally, just for your information, the use of identifiers starting
: with an underscore is not allowed in normal C programs - identifiers
: starting with a leading underscore are reserved for the implementa-
: tion, i.e. for use by the compiler and system header files etc. In
: your case correcting this isn't a problems since
:
: struct TEST {
:     char    s1[3];
:     char    s2[10];
: } TEST;
:
: will also do perfectly well, as will do
:
: struct {
:     char    s1[3];
:     char    s2[10];
: } TEST;

If you are going you use a field to hold data that you aceess with two
different data types,  you need to use a union.  Even so,  I feel what
you are trying to do may not be portable.

Dan Mercer

:
:                                   Regards, Jens
: --
:   \   Jens Thoms Toerring  ___  Jens.Toerring@physik.fu-berlin.de
:    \__________________________  http://www.toerring.de







[ Post a follow-up to this message ]



    Sponsored Links  




 





   All times are GMT. The time now is 01:18 PM.      Post New Thread    Post A Reply      
  Last Thread   Next Thread Next


Most Popular forums 

Forum Jump:
Rate This Thread:

Forum Rules:
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is OFF
vB code is ON
Smilies are ON
[IMG] code is OFF
 
Medical and Health forum | Computer Games Reviews | Graphics design forum

Back To The Top
Home | Usercp | Faq | Register