Segmentation Fault

C

Christian Lande

Hi all,

can anybody help me with the following code:

#include <stdio.h>
#include <emmintrin.h>
#define M 2
int main () {
int i;
__m128d *s, ts, td;

double *p = malloc(M*sizeof(*p)); //A
// double p[2]; //B

if (p==NULL) return 0;

p[0]=p[1]=1.0;

printf("%.3f %.3f\n", p[0], p[1]);

s = (__m128d *)p; //D
if (s != p) return 0;
ts = *s;
td = _mm_add_pd(ts, ts);
*s = td; //C

printf("%.3f %.3f\n", p[0], p[1]);
}

Line "C" causes a Segmentation Fault and I don't know why. If I replace line
"A" with line "B" it works correctly. Something must be wrong with line "D"
maybe somebody knows what?

Thanks for any help,
ChL

PS: I'm using an Intel Compiler icc version 8.0 on a Xeon machine compiling
with the command "icc test.c -o test -march=pentium4".
 
M

Mark A. Odell

Hi all,

can anybody help me with the following code:

#include <stdio.h>
#include <emmintrin.h>
#define M 2
int main () {
int i;
__m128d *s, ts, td;

double *p = malloc(M*sizeof(*p)); //A
// double p[2]; //B

if (p==NULL) return 0;

p[0]=p[1]=1.0;

printf("%.3f %.3f\n", p[0], p[1]);

s = (__m128d *)p; //D

What the heck is __m128d? Hint: it's not ISO C so how can we help you
here?
 
C

Christian Lande

Mark A. Odell said:
What the heck is __m128d? Hint: it's not ISO C so how can we help you
here?

yes, you are right, it's not ISO C, sorry. But I don't know any other
position where to ask such a question and I'm sure here are some people who
know the answer.

If you are interested in what is __m128d, you can look here
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/vclrf__m128d.asp
e.g. Some other compilers (like Intel icc for linux and windows) implement
it in the same way.

Thx for your answer,
ChL
 
D

Darrell Grainger

Hi all,

can anybody help me with the following code:

#include <stdio.h>
#include <emmintrin.h>

Have no idea what this header is. Without an explanation this could have
some impact.
#define M 2
int main () {
int i;
__m128d *s, ts, td;

What is __m128d? This is not a standard data type.
double *p = malloc(M*sizeof(*p)); //A

First use of malloc without prototype. You need to add an #include
// double p[2]; //B

if (p==NULL) return 0;

p[0]=p[1]=1.0;

printf("%.3f %.3f\n", p[0], p[1]);

s = (__m128d *)p; //D

Here I still have no idea what __m128d is and how it will affect things.
if (s != p) return 0;

This tells me that the implicit conversion and explicit conversion must be
the same to get passed this point. Is sizeof *p == sizeof *s? If not then
what is going on here?
ts = *s;
td = _mm_add_pd(ts, ts);
*s = td; //C

Is this definitely C? The use of C++ style comments makes me wonder. If it
is C, sizeof *p < sizeof *s could cause a crash here. Or are you assuming
that sizeof p[0] + sizeof p[1] == sizeof *s?

If that is the case, why not use a union that contains pointers to
doubles and a pointer to a __m128d. It would be more clear and the
compiler might catch something you are missing.
printf("%.3f %.3f\n", p[0], p[1]);

P.S. if main returns an int, where is your return statement?
 
I

Irrwahn Grausewitz

Christian Lande said:
Hi all,

can anybody help me with the following code:

#include <stdio.h>
#include <emmintrin.h>

As Mark already pointed out, by including this header you left
the realm of portable standard C.
#define M 2
int main () {
int i;
__m128d *s, ts, td;

double *p = malloc(M*sizeof(*p)); //A

// double p[2]; //B

if (p==NULL) return 0;

p[0]=p[1]=1.0;

printf("%.3f %.3f\n", p[0], p[1]);

s = (__m128d *)p; //D
if (s != p) return 0;
ts = *s;
td = _mm_add_pd(ts, ts);
*s = td; //C

printf("%.3f %.3f\n", p[0], p[1]);
}

Line "C" causes a Segmentation Fault and I don't know why.

If including stdlib.h didn't fix the code, here's another possible
cause for the segfault: if an object of type __m128d (whatever that
is) requires more memory than p points to, you write to memory your
program doesn't own in line "C".

<snip>

Regards
 
D

Dan Pop

In said:
#include <stdio.h>
#include <emmintrin.h>
???

#define M 2
int main () {
int i;
__m128d *s, ts, td;

I assume __m128d is an 128-bit (16 byte) type.
double *p = malloc(M*sizeof(*p)); //A
// double p[2]; //B

if (p==NULL) return 0;

p[0]=p[1]=1.0;

printf("%.3f %.3f\n", p[0], p[1]);

s = (__m128d *)p; //D
if (s != p) return 0;
^^^^^^
Is the compiler silently accepting this line? It doesn't look like
__m128d is merely an alias for double and you can't compare pointers to
different types.

If this works, then //C should, in principle, work, too.
td = _mm_add_pd(ts, ts);
*s = td; //C

The only explanation for a failure here after the success of "ts = *s;"
is that the _mm_add_pd(ts, ts) call invoked undefined behaviour.
printf("%.3f %.3f\n", p[0], p[1]);
}

Line "C" causes a Segmentation Fault and I don't know why. If I replace line
"A" with line "B" it works correctly.

This replacement generates a different stack layout, so it may be a red
herring.
Something must be wrong with line "D" maybe somebody knows what?

In this case, "ts = *s;" should have generated the crash. But this
didn't happen, so the pointer value is OK.
Thanks for any help,
ChL

PS: I'm using an Intel Compiler icc version 8.0 on a Xeon machine compiling
with the command "icc test.c -o test -march=pentium4".

Your code is not standard C code and your problem has nothing to do
with standard C.

Dan
 
D

Dan Pop

In said:
As Mark already pointed out, by including this header you left
the realm of portable standard C.


You forgot to #include <stdlib.h> before calling malloc; this might
well be the reason for the problem.

If he did, indeed, the compiler should have complained: a diagnostic is
required.

Dan
 
C

Christian Lande

Ok, thanks to all of you for reading and trying to help, meanwhile I solved
the problem.

It was because of the fact, that this __m128d-type was defined with an
alignment of every 16 Bytes, so I got the problem because of my reserved
double field has an alignment of every 8 Bytes.

Because of your comments that this is not the right group, can you give me a
hint where to ask for such things, please? These problems occouring from
time to time and I've allways the same problem not knowing where to ask for.

Thx,
ChL
 
C

CBFalconer

Christian said:
can anybody help me with the following code:

#include <stdio.h>
#include <emmintrin.h>

unknown header.
#define M 2
int main () {

int main (void) is better
int i;
__m128d *s, ts, td;

illegal identifier __m128d. Reserved for implementation
double *p = malloc(M*sizeof(*p)); //A
// double p[2]; //B

// comments are ill advised in newsgroups, require C99 compiler.
You probably don't have one. Use /* ... */ instead.
if (p==NULL) return 0;

p[0]=p[1]=1.0;

printf("%.3f %.3f\n", p[0], p[1]);

s = (__m128d *)p; //D

Again, unideclared and illegal identifier. Bad comment.
if (s != p) return 0;

Why should it be? They point to different types.

ts is of type blah, s of type pointer to blah (I won't sink to
typing __m128d). Even more things must be undefined by now.
td = _mm_add_pd(ts, ts);

Another illegal identifier, also undefined.
*s = td; //C

printf("%.3f %.3f\n", p[0], p[1]);
}

Line "C" causes a Segmentation Fault and I don't know why. If I
replace line "A" with line "B" it works correctly. Something must
be wrong with line "D" maybe somebody knows what?

Thanks for any help,
ChL

PS: I'm using an Intel Compiler icc version 8.0 on a Xeon machine
compiling with the command "icc test.c -o test -march=pentium4".

If that matters you are off topic.
 
C

CBFalconer

Christian said:
.... snip ...

Because of your comments that this is not the right group, can
you give me a hint where to ask for such things, please? These
problems occouring from time to time and I've allways the same
problem not knowing where to ask for.

Your best bet is to stick to pure ISO standard portable C and
eschew system specific extensions. The end convenience will pay
for itself many times over.

If this is not possible you should, in this case, look for a
newsgroup with 'Microsoft' in its name. In that case you should
also isolate your non-portable code to a file or two.
 
B

Barry Schwarz

Hi all,

can anybody help me with the following code:

#include <stdio.h>
#include <emmintrin.h>
#define M 2
int main () {
int i;
__m128d *s, ts, td;

double *p = malloc(M*sizeof(*p)); //A
// double p[2]; //B

if (p==NULL) return 0;

p[0]=p[1]=1.0;

printf("%.3f %.3f\n", p[0], p[1]);

s = (__m128d *)p; //D
if (s != p) return 0;

Doesn't your compiler generate a diagnostic for this? The two pointer
types are incompatible unless __m128d is just a typedef for double.
ts = *s;
td = _mm_add_pd(ts, ts);
*s = td; //C

What is the sizeof(__m128d)? If it is larger than 2*sizeof(double)
you are attempting to write to memory you don't own.
printf("%.3f %.3f\n", p[0], p[1]);
}

Line "C" causes a Segmentation Fault and I don't know why. If I replace line
"A" with line "B" it works correctly. Something must be wrong with line "D"

If it is the size problem mentioned above, line C will overwrite other
variables in your program but at least you own that memory.

However, both overwrites invoke undefined behavior so it really won't
work even if it appears to.
maybe somebody knows what?

With line A, line D cannot be the problem because the value returned
from malloc is guaranteed to be properly aligned for any type,
including __m128d. With line B, we don't know if p will be properly
aligned.

If you really want help, you are going to have to give us all the
non-standard details. What is type __m128d? What does _mm_add_pd do?


<<Remove the del for email>>
 
U

Ulrich Eckhardt

Christian said:
#include <emmintrin.h>
#define M 2
__m128d *s, ts, td;

double *p = malloc(M*sizeof(*p)); //A
// double p[2]; //B

if (p==NULL) return 0;

p[0]=p[1]=1.0;

printf("%.3f %.3f\n", p[0], p[1]);

s = (__m128d *)p; //D
if (s != p) return 0;
ts = *s;
td = _mm_add_pd(ts, ts);
*s = td; //C

printf("%.3f %.3f\n", p[0], p[1]);
}

Line "C" causes a Segmentation Fault and I don't know why.
If I replace line "A" with line "B" it works correctly.
Something must be wrong with line "D" maybe somebody knows what?

Casts are always wrong, only that they sometimes are the only cure. Here
however, you say that it should interpret the address 'p' as a '__m128d*'.
'd' only holds so much storage, so why don't you first make sure that
there is enough?

$include <assert.h>
assert( (sizeof *s) <= (M * (sizeof *p)));

The fact that it does seem to work with 'B' activated is just luck. Try
adding another var after p, and output its value before and after 'C'. The
stack area was already allocated to your process, but that doesn't mean
you are allowed to use it. The heap is allocated more exactly to fit your
needs, crossing these bounds therefore earlier causes the segmentation
fault.

Oh, while you are at it, could you please remove everything that is not
necessary to demonstrate your problem, e.g. the call to _mm_add_pd()?

Uli
 
U

Ulrich Eckhardt

Darrell said:
Is this definitely C? The use of C++ style comments makes me wonder.

C allows those comments. It didn't always allow them, but it does now (and
many compilers have been accepting it for some time).

Uli
 
R

Ravi Uday

Comments inline..

Christian Lande said:
Hi all,

can anybody help me with the following code:

#include <stdio.h>
#include <emmintrin.h>

Never heard of this header. System specific headers are not discussed
here..
#define M 2
int main () {
int i;
__m128d *s, ts, td;

/* whats this __m128d ... its not a C datatype that i've known. */
double *p = malloc(M*sizeof(*p)); //A
// double p[2]; //B

if (p==NULL) return 0;

p[0]=p[1]=1.0;

printf("%.3f %.3f\n", p[0], p[1]);

s = (__m128d *)p; //D

/* Unless you tell us whats __m128d stands for how can we know
whats happ ?*/
if (s != p) return 0;
ts = *s;
td = _mm_add_pd(ts, ts);

/* mm_add_pd.. where is this defined ! I think its in this function
the culprit is, there is some inconsistency in the params you have
passed. Did you make a typo !!!! */
*s = td; //C

printf("%.3f %.3f\n", p[0], p[1]);
}

Since main is declared as function that returns 'int' before exiting
the function, call return with 0/EXIT_FAILURE..etc..
Line "C" causes a Segmentation Fault and I don't know why. If I replace line
"A" with line "B" it works correctly. Something must be wrong with line "D"
maybe somebody knows what?

Thanks for any help,
ChL

Its better you post here a compilable code for us to run/exec and test
your program. By this we can make our statements/suggestions clear and
crisp.
 
C

Christian Lande

CBFalconer said:
If this is not possible you should, in this case, look for a
newsgroup with 'Microsoft' in its name.

I don't understand this suggestion. What should the code in a
'Microsoft'-Group, it was coded for a Xeon with Red Hat Linux?
In that case you should
also isolate your non-portable code to a file or two.

For what reason? In most groups attachments are not not gladly seen.

Thx for your answer,
ChL
 
C

Chris Dollin

Christian said:
For what reason? In most groups attachments are not not gladly seen.

Not in your postings - in your actual code.

Putting the non-portable bits in their own file(s) makes it easier
to replace them on a different platform than if the platform-dependencies
are wrapped in ifdefs and scattered all round your source.
 
A

Arthur J. O'Dwyer

I don't understand this suggestion. What should the code in a
'Microsoft'-Group, it was coded for a Xeon with Red Hat Linux?

Then you should look for a group with 'linux' in its name. Duh.
(If you specify an Intel architecture without specifying the OS, most
people will assume you're a Microsoft user. Especially if you come
off as clueless.)
For what reason? In most groups attachments are not not gladly seen.

He said "file," as in "source file." Attachments have nothing to
do with it. The point is that in a well-written program, the only
system dependencies ought to be easily locatable and modifiable. The
easiest way to do this is to put all of them in a separate source
file, called 'linuxdep.c' or some such. Then it will be much easier
to port the program to use another OS, architecture, or special-purpose
library.

HTH,
-Arthur
 
D

Dan Pop

In said:
Casts are always wrong, only that they sometimes are the only cure. Here

If the *only* way of *correctly* writing a piece of code requires a cast,
how can you claim that they are always wrong?

There are plenty of good uses of casts and there are also cases where
the language definition imposes the usage of dubious casts (try to
implement strchr if you need an example).

Dan
 
D

Dan Pop

In said:
C allows those comments. It didn't always allow them, but it does now (and
many compilers have been accepting it for some time).

A conforming C89 compiler *must* diagnose them. A conforming C99 compiler
must accept them, but conforming C99 compilers are few and far between.

Dan
 
D

Dan Pop

In said:
Ok, thanks to all of you for reading and trying to help, meanwhile I solved
the problem.

It was because of the fact, that this __m128d-type was defined with an
alignment of every 16 Bytes, so I got the problem because of my reserved
double field has an alignment of every 8 Bytes.

But then, the attempt to read from that address should have crashed your
code, which survived until attempting to write to that address...
Because of your comments that this is not the right group, can you give me a
hint where to ask for such things, please?

Since you say you're using a Microsoft extension, try a newsgroup whose
name starts with microsoft.

Dan
 

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
473,982
Messages
2,570,186
Members
46,744
Latest member
CortneyMcK

Latest Threads

Top