Использование mmap и memcpy и ошибка Segmentation Fault (сброс ядра)

У меня есть два файла, и я хочу скопировать содержимое одного файла в другой с помощью memcpy. Но я получаю эту ошибку Segmentation Fault (core dumped). Мой основной

int main( int argc, char * argv[] ){
    int d1;
    int d2;
    char *a;
    char *b;
    d1 = da_open_r(argv[1]); // open file READ ONLY
    d2 = da_open_w(argv[2]); //  open file to WRITE
    a = (char*)da_mmap(d1); // map first file
    b = (char*)da_mmap(d2); // map second file
    memcpy(b, a, 10); // I think this line is bad
    kp_test_munamp(a, 10 ); // 
    kp_test_munamp(b, 10 );
    kp_test_close(d1); // close 1 file
    kp_test_close(d2); // close 2 file
    return 0;
}

а вот мои da_mmap и kp_test_munamp

void *da_mmap(int d){
    mmap(NULL, 10, PROT_READ|PROT_WRITE, MAP_SHARED, d, 0);
}

int kp_test_munamp( void *a, int size ){
   int rv;
   rv = munmap( a, size );
   if( rv != 0 ){
      puts( "munmap failed" );
      abort();
   }
   return 1;
}

Я пытался исправить это почти два часа, но до сих пор не знаю, что не так. РЕДАКТИРОВАТЬ мой полный код

#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/time.h>
#include <string.h>

int da_open_r(const char *name);
int da_open_w(const char *name);
void *da_mmap(int d);
int kp_test_munamp( void *a, int size );
int kp_test_close(int fd);

int da_open_r(const char *name){
    int dskr;
    dskr = open( name, O_RDWR );
    if( dskr == -1 ){
      perror( name );
      exit( 255 );
    }
    printf( "dskr1 = %d\n", dskr );
    return dskr;
}

int da_open_w(const char *name){
    int dskr;
    dskr = open( name, O_RDWR );
   if( dskr == -1 ){
      perror( name );
      exit( 255 );
   }
   printf( "dskr2 = %d\n", dskr );
   return dskr;
}

void *da_mmap(int d){
     void *a = NULL;
     a = mmap(NULL, 10, PROT_WRITE, MAP_SHARED, d, 0);
     if( a == MAP_FAILED ){
          perror( "mmap failed" );
          abort();
     }
     return a;
}

int kp_test_munamp( void *a, int size ){
   int rv;
   rv = munmap( a, size );
   if( rv == -1 ){
      puts( "munmap failed" );
      abort();
   }
   return 1;
}

int kp_test_close(int fd){
   int rv;
   rv = close( fd );
   if( rv != 0 ) perror ( "close() failed" );
   else puts( "closed" );
   return rv;
}

int main( int argc, char * argv[] ){
    int d1;
    int d2;
    char *a;
    char *b;
    d1 = da_open_r(argv[1]); // read only
    d2 = da_open_w(argv[2]); //  WRITE
    a = (char*)da_mmap(d1);
    b = (char*)da_mmap(d2);
    memcpy(b, a, 10); // I think this line is bad
    kp_test_munamp(a, 10 );
    kp_test_munamp(b, 10 );
    kp_test_close(d1);
    kp_test_close(d2);
    return 0;
}

person David    schedule 03.05.2015    source источник
comment
Вы проверяете, все ли операции, связанные с файлами, выполнены успешно?   -  person GingerJack    schedule 03.05.2015
comment
Компилируется ли код без предупреждений при использовании -Wall -Wextra -pedantic?   -  person alk    schedule 03.05.2015
comment
Отслеживали ли вы свой код в отладчике, чтобы определить строку исходного кода, где происходит сбой? Скомпилируйте, используя параметр -g, затем запустите gbd yourprogramname, выполните b main <enter>, затем r <enter>, а затем проследите строку за строкой, используя t <enter>. Тебе это понравится.   -  person alk    schedule 03.05.2015
comment
У меня нет стека! Но почему? Я думал, что все переменные в main идут в стек. Как это возможно, что нет стека!?   -  person David    schedule 03.05.2015
comment
Там могут быть устаревшие сегменты общей памяти, оставшиеся от различных тестовых запусков вашей программы. Проверьте это с помощью инструмента командной строки ipcs. Удалите тех, кто использует ipcrm.   -  person alk    schedule 03.05.2015


Ответы (1)


da_mmap() ничего не возвращает! Это приводит к тому, что значения a и b являются мусором и, скорее всего, указывают на недопустимую память, что, в свою очередь, приводит к сбою memcpy() при воздействии на нее.

Добавить оператор возврата

void * da_mmap(int d) {
  return mmap(NULL, 10, PROT_READ|PROT_WRITE, MAP_SHARED, d, 0);
}

Также вы должны проверить результат сопоставления, выполнив:

{
  void * pvtmp = da_mmap(d1); // map first file
  if (MAP_FAILED == pvtmp)
  {
    perror("da_mmap() failed");
    exit(1);
  }

  a = pvtmp;
}    

То же самое для b.


Ссылаясь на оболочку вокруг munmap(). Исправьте тестирование ошибок здесь. Однако по соглашению успех обозначается возвратом 0 (неудача - возвратом -1).

person alk    schedule 03.05.2015
comment
Спасибо за ответ! Но все же у меня возникла та же проблема. - person David; 03.05.2015
comment
Я получаю ту же ошибку Segmentation Fault (ядро сброшено) - person David; 03.05.2015
comment
@David: Ты уверен, что все перекомпилировал, простите? - person alk; 03.05.2015
comment
да. Также я отредактировал свой вопрос и вставил весь свой код. - person David; 03.05.2015
comment
@David: Не могу воспроизвести на моей стороне, ваш код работает. - person alk; 03.05.2015