This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
c/7334: SIGBUS in assignment and in memcpy()
- From: glushko at yahoo dot com
- To: gcc-gnats at gcc dot gnu dot org
- Date: 17 Jul 2002 08:16:27 -0000
- Subject: c/7334: SIGBUS in assignment and in memcpy()
- Reply-to: glushko at yahoo dot com
>Number: 7334
>Category: c
>Synopsis: SIGBUS in assignment and in memcpy()
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: unassigned
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Wed Jul 17 01:26:01 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator: Igor Glushko
>Release: 2.95.2 and 3.0.2
>Organization:
>Environment:
SunOS samson 5.6 Generic_105181-23 sun4d sparc SUNW,SPARCserver-1000
>Description:
Assigning a not-aligned field of a packed structure produces SIGBUS and a core dump. In more complex program than the one attached the same result got using memcpy() instead of assignment.
>How-To-Repeat:
compile the attached file
>Fix:
use byte-by-byte assignmet copying in a while loop without any optimization
>Release-Note:
>Audit-Trail:
>Unformatted:
----gnatsweb-attachment----
Content-Type: text/plain; name="sigbus_in_assignment.c"
Content-Disposition: inline; filename="sigbus_in_assignment.c"
#include <stdio.h>
#include <string.h>
static
void*
byte_memcpy(void* to, const void* from, size_t n)
{
register char* t=(char*)to;
register const char* fb=(const char*)from;
register const char* fe=(const char*)from+n;
while(fb<fe){
*(t++)=*(fb++);
}
}
static
void
copy(int* pi, int i)
{
printf("copy(%p, %i): byte_memcpy(%p, %p, %u) ...\n", pi, i, pi, &i, sizeof(*pi));
// this works always (only with -O0 compilation option):
memcpy(pi, &i, sizeof(*pi));
printf("copy(%p, %i): memcpy(%p, %p, %u) ...\n", pi, i, pi, &i, sizeof(*pi));
// this works in this example, but does not in more complex cases:
memcpy(pi, &i, sizeof(*pi));
printf("copy(%p, %i): *(%p) = %i ...\n", pi, i, pi, i);
// here SIGBUS are caught:
*pi = i;
printf("copy(%p, %i)!\n", pi, i);
}
// Make GCC to recognize the '#pragma pack' construction.
#define HANDLE_SYSV_PRAGMA 1
#pragma pack(1)
struct s // packed structure
{
unsigned u;
char c;
int i;
};
#pragma pack()
int
main()
{
struct s ss = {1, 'a', -1};
printf("%u, %c, %i\n", ss.u, ss.c, ss.i);
ss.u = 2;
printf("%u, %c, %i\n", ss.u, ss.c, ss.i);
ss.c = 'b';
printf("%u, %c, %i\n", ss.u, ss.c, ss.i);
// this works well:
ss.i = -2;
// does not return from copy():
copy(&ss.i, -2);
printf("%u, %c, %i\n", ss.u, ss.c, ss.i);
return 0;
}