This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

c/7334: SIGBUS in assignment and in memcpy()


>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;
}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]