3 Replies Latest reply on Dec 28, 2010 5:15 PM by Steve.Clamage-Oracle

    Recived Bus Error (core dumped) while memcpy to mmapped addres

    826793
      I am getting core dump while doing memcpy operation at address of file mapped by mmap () system call. Here is the code

      #include <fcntl.h>
      #include <unistd.h>
      #include <sys/mman.h>


      typedef struct
      {
      int DayID;
      int Rate ;
      } DayRates;

      typedef struct
      {
      int WeekID;
      int Rate;
      } WeekRates;


      typedef struct
      {
      DayRates *dr;
      WeekRates *wr;
      } RateData;

      typedef struct
      {
      RateData rdr;
      int RateID;
      char RateBalance;
      } RateInfo;

      void f_write (void s1, RateInfo S1, int size)
      {
      if (_s1 == NULL)
      {
      printf ("Input Parameter is Invalid\n") ;
      return ;
      }
      memcpy (_s1, (const void *)&(_S1.rdr.dr->DayID), sizeof (int)) ;
      memcpy ((_s1 + sizeof (int)), (const void *)&(_S1.rdr.dr->Rate), sizeof (int)) ;
      memcpy ((_s1 + sizeof (DayRates)), (const void *)&(_S1.rdr.wr->WeekID), sizeof (int)) ;
      memcpy ((_s1 + sizeof (DayRates) + sizeof (int)), (const void *)&(_S1.rdr.wr->Rate), sizeof (int)) ;
      memcpy ((_s1 + sizeof (DayRates) + sizeof (WeekRates)), (const void *)&(_S1.RateID), sizeof (int)) ;
      memcpy ((_s1 + sizeof (DayRates) + sizeof (WeekRates) + sizeof (int)), (const void *)&(_S1.RateBalance), sizeof (char)) ;
      return ;
      }
      void f_read (void _t1, RateInfo _T1, int size)
      {
      T1->RateID = *(int*)(t1 + sizeof (DayRates) + sizeof (WeekRates)) ;
      T1->RateBalance = *(char*)(t1 + sizeof (DayRates) + sizeof (WeekRates) +sizeof (int)) ;
      T1->rdr.dr = (DayRates*)(t1) ;
      T1->rdr.wr = (WeekRates*)(t1 + sizeof (DayRates)) ;
      return ;
      }
      void Display (RateInfo D1)
      {
      printf ("\n Start\n") ;
      printf ("D1.rdr.dr->DayID = [%d]\n", D1.rdr.dr->DayID) ;
      printf ("D1.rdr.dr->Rate = [%d]\n", D1.rdr.dr->Rate) ;
      printf ("D1.rdr.wr->WeekID = [%d]\n", D1.rdr.wr->WeekID) ;
      printf ("D1.rdr.wr->Rate = [%d]\n", D1.rdr.wr->Rate) ;
      printf ("D1.RateID = [%d]\n", D1.RateID) ;
      printf ("D1.RateBalance = [%c]\n", D1.RateBalance) ;
      printf ("\n End\n") ;
      return ;
      }

      void init (RateInfo _S1)
      {
      _S1->rdr.dr = (DayRates*) calloc (1, sizeof (DayRates)) ;
      _S1->rdr.dr->DayID = 2 ;
      _S1->rdr.dr->Rate = 102 ;
      _S1->rdr.wr = (WeekRates*) calloc (1, sizeof (WeekRates)) ;
      _S1->rdr.wr->WeekID = 3 ;
      _S1->rdr.wr->Rate = 402 ;
      _S1->RateID = 1 ;
      _S1->RateBalance = 'A' ;
      return ;
      }

      int main(int argc, char *argv[])
      {
      int input;
      size_t filesize;
      void *source = NULL ;
      RateInfo S1, T1 ;
      bzero (&S1, sizeof (RateInfo)) ;
      bzero (&T1, sizeof (RateInfo)) ;
      filesize = sizeof (DayRates) + sizeof (WeekRates) + sizeof (int) + sizeof (char) + 1;

      if(argc != 2)
      {
      printf("%s SOURCE \n", argv[0]);
      exit(1);
      }
      if((input = open(argv[1], O_RDWR|O_CREAT|O_TRUNC, 0666)) == -1)
      {
      printf("Error: opening file: %s\n", argv[1]);
      exit(1);
      }
      lseek(input, filesize - 1, SEEK_SET);
      write(input, '\0', 1);

      if((source = mmap(0, filesize, PROT_WRITE, MAP_SHARED, input, 0)) == (void *) -1)
      {
      printf("Error mapping input file for writing: %s\n", argv[1]);
      exit(1);
      }
      //Initialize
      init (&S1) ;
      Display (S1) ;
      f_write (source, S1, filesize) ;
      free (S1.rdr.dr) ;
      free (S1.rdr.wr) ;
      munmap(source, filesize);

      if((source = mmap(0, filesize-1, PROT_READ, MAP_SHARED, input, 0)) == (void *) -1)
      {
      printf("Error mapping input file for reading: %s\n", argv[1]);
      exit(1);
      }
      f_read (source, &T1, filesize-1) ;
      Display (T1) ;

      munmap(source, filesize-1);
      close(input);
      return 0;

      }

      The above code works fine for me in Linux box.

      SunOS Box Specification:

      bash-2.05# uname -a
      SunOS psp 5.10 Generic_118558-11 sun4u sparc SUNW,Sun-Fire-V440
      bash-2.05#

      bash-2.05# gdb ./a.out core
      GNU gdb 6.6
      Copyright (C) 2006 Free Software Foundation, Inc.
      GDB is free software, covered by the GNU General Public License, and you are
      welcome to change it and/or distribute copies of it under certain conditions.
      Type "show copying" to see the conditions.
      There is absolutely no warranty for GDB. Type "show warranty" for details.
      This GDB was configured as "sparc-sun-solaris2.8"...

      warning: Can't read pathname for load map: I/O error.
      Reading symbols from /usr/lib/libc.so.1...done.
      Loaded symbols for /usr/lib/libc.so.1
      Reading symbols from /usr/lib/libdl.so.1...done.
      Loaded symbols for /usr/lib/libdl.so.1
      Reading symbols from /usr/platform/SUNW,Sun-Fire-V440/lib/libc_psr.so.1...done.
      Loaded symbols for /usr/platform/SUNW,Sun-Fire-V440/lib/libc_psr.so.1

      warning: Can't read pathname for load map: I/O error.

      warning: Can't read pathname for load map: I/O error.
      Core was generated by `./a.out anup'.
      Program terminated with signal 10, Bus error.
      #0 0xff3a0528 in memcpy () from /usr/platform/SUNW,Sun-Fire-V440/lib/libc_psr.so.1
      (gdb) bt full
      #0 0xff3a0528 in memcpy () from /usr/platform/SUNW,Sun-Fire-V440/lib/libc_psr.so.1
      No symbol table info available.
      #1 0x000107f8 in f_write (_s1=0xff380000, _S1={rdr = {dr = 0x21170, wr = 0x21180}, RateID = 1, RateBalance = 65 'A'}, size=22)
      at mmap_test.c:39
      No locals.
      #2 0x00010c48 in main (argc=2, argv=0xffbffbec) at mmap_test.c:112
      input = 3
      filesize = 22
      source = (void *) 0xff380000
      S1 = {rdr = {dr = 0x21170, wr = 0x21180}, RateID = 1, RateBalance = 65 'A'}
      T1 = {rdr = {dr = 0x0, wr = 0x0}, RateID = 0, RateBalance = 0 '\0'}
      (gdb) quit
      bash-2.05#


      Thanks in advance.

      Edited by: 823790 on Dec 27, 2010 4:21 AM
        • 1. Re: Recived Bus Error (core dumped) while memcpy to mmapped addres
          Steve.Clamage-Oracle
          1. Please use "code" tags for source code and computer output, to preserve formatting, and to prevent source code constructs from being swallowed as formatting directives by the forum display software.

          2. You did not show how you compiled the program. Sometimes compiler options make a difference.

          3. I compiled the code with the Oracle Solaris Studio C compiler. It complained about numerous functions called without a prototype. The assumed declaration in the absence of a prototype can be wrong, leading to unpredictable program behavior. You should include the system headers that declare the system functions. I added
          <tt>stdio.h, string.h, strings.h</tt> (for bzero), and <tt>stdlib.h</tt>.
          BTW, <tt>bzero</tt> is not a standard function, but is from BSD Unix. I suggest using the standard function <tt>memset</tt> instead. Apart from being a standard function, optimizing compilers will often generate better code for standard functions like this than you get from calling the library function.

          4. I also got numerous warnings about doing arithmetic with void* pointers, the results of which are undefined. You should use char* for pointer arithmetic, not void*.

          5. The a.out requires a command-line argument, apparently a file name, but you did not explain what the file should be.

          I suggest fixing the defects I listed in #3, then compile with Studio C with -g for debugging. Then run it under the dbx debugger. You can turn on Run-Time Checking to get a picture of where the program went wrong.
          % cc myprog.c -g <any other needed options>
          % dbx a.out
          (dbx) check -all
          access checking - ON
          memuse checking - ON
          (dbx) run <argument>
          • 2. Re: Recived Bus Error (core dumped) while memcpy to mmapped addres
            826793
            I am compiling the code with :
            ==================
            bash-2.05# gcc -g mmap_test.c

            And to execute the binary:
            =================
            ./a.out out_file

            Where out_file is any file preferably non existing file.

            Once gain I have modified the code to include system header files recommended by you n your post, but unfortunately the same Bus Error I am getting.
            • 3. Re: Recived Bus Error (core dumped) while memcpy to mmapped addres
              Steve.Clamage-Oracle
              I made all of the corrections I suggested to the source code, then compiled with both gcc 4.3.2 and Oracle Solaris Studio 12.2. My platform is Solaris 10 update 8 on Sparc.

              In both cases, the program ran to completion, producing this output:
              % ./a.out foo
              
               Start
              D1.rdr.dr->DayID = [2]
              D1.rdr.dr->Rate = [102]
              D1.rdr.wr->WeekID = [3]
              D1.rdr.wr->Rate = [402]
              D1.RateID = [1]
              D1.RateBalance = [A]
              
               End
              
               Start
              D1.rdr.dr->DayID = [2]
              D1.rdr.dr->Rate = [102]
              D1.rdr.wr->WeekID = [3]
              D1.rdr.wr->Rate = [402]
              D1.RateID = [1]
              D1.RateBalance = [A]
              
               End 
              File foo contained some binary data.