Re: Question about setjmp on Itanium HPUX.

From: Richard Bos (rlb_at_hoekstra-uitgeverij.nl)
Date: 11/19/04


Date: Fri, 19 Nov 2004 10:27:09 GMT

Peter Smithson <pgsmithson_deletethisbit@yahoo.co.uk> wrote:

> #include <stdio.h>
> #include <setjmp.h>
> #include <malloc.h>

No such header in ISO C. Use <stdlib.h> instead.

> struct mystruct {
> char abc;
> jmp_buf s_jbuf;
> };
>
> #define ALLIGN 8
>
> int main()
> {
> struct mystruct s_x;

This is correct.

> struct mystruct *p_x = (void *)
> ((char *)malloc(sizeof(struct mystruct)+ALLIGN)+ALLIGN);

*Kablooie!* Yes, that was the sound of the alignment of your struct
being blown to bits. You do not know that a jmp_buf needs to be aligned
on 8 bytes or a whole fraction of 8 bytes. You do know that the pointer
returned from malloc() is correctly aligned for all types, including
jmp_buf and your struct. Therefore, you do not know that (that pointer+8
bytes) is correctly aligned for either. And _that_ means that...

> printf("Doing setjmp 2...\n");
> setjmp(p_x->s_jbuf);

...passing this quite probably incorrectly aligned pointer to setjmp()
causes undefined behaviour.

You can solve this by either not adding anything to malloc()'s return
value, or adding a number of bytes which you know will preserve correct
alignment.
In the first case, you write just

  struct mystruct *p_x = malloc(sizeof *p_x + ALLIGN);

and use the last ALLIGN (btw, the correct spelling is ALIGN) bytes for
whatever extra data you need instead of the first ones. However, do note
that if you use them for anything but chars, you end up with the same
potential alignment problems as you have now.

In the second case, you need to find out a safe value for the addition.
The one value which you are guaranteed is safe for struct mystruct is
sizeof(struct mystruct); this _must_ be good enough, since in an array,
each element is sizeof(struct mystruct) beyond the previous. So in this
case, you write

  #define ALIGN sizeof(struct mystruct)
  struct mystruct *p_x=
    (void *)((char *)malloc(sizeof *p_x+ALIGN) + ALIGN);

or even, more simply,

  struct mystruct *p_x=malloc(2*sizeof *p_x)+1;

since you're now in effect dealing with an array of two struct elements.
Note that in this case, as in your original code, you need to remember
to subtract the extra amount of memory when you free() it.

This problem is not specific to either setjmp() or your implementation,
btw. Your code is simply not conforming; it would cause problems for any
type with a strict enough alignment, on any implementation that cares
about alignment.

Richard



Relevant Pages

  • Re: A malloc question
    ... reliably store 100 chars followed by a struct in this memory, ... the alignment of p+100 may not be suitable for the struct. ... the paddings for memory alignment are ... malloc() will see a request of 24 byte allocation. ...
    (comp.lang.c)
  • Re: Structure size directives
    ... alignment requirements, it's a terrible idea to use e.g. ... "If you use #pragma pack to align struct or union members on ... System programmers who are concerned about code bloat et al can just ...
    (comp.lang.c)
  • Mixing C and C++
    ... I have therefore implemented the assignment operator to create 'shallow' copy by default (so this is consistent with the C API so that a pointer to the struct could be passed to a C API function with no adverse effect). ... MyStruct(const MyStruct& ms) ... MyStruct& operator= (const MyStruct& rhs) ... void deepcopy ...
    (comp.lang.c)
  • Re: realloc() implicit free() ?
    ... block size as a request for one byte, and let the alignment mechanisms raise it as they will. ... is therefore suitably aligned for any type (`struct s' in particular), the value can be assigned to any type of pointer, and can then be used to access an object of that type. ... of the Standard can distort its meaning. ...
    (comp.lang.c)
  • Re: "free space" with declared type (alignment discussion)
    ... >>a function pointer member, a struct pointer member, and maybe a few ... > It doesn't put any extra constraint on alignment beyond this. ... > To assess actual alignment constraints, a structure might be used to figure how ...
    (comp.lang.c)