2013-09-30 5 views
1

Я работаю над проблемой домашней работы, чтобы написать реализацию гипотезы collatz в C, используя fork() и объект общей памяти, выполняя вычисления в дочернем процессе и распечатывая результаты в родительском , Я не очень хорошо знаком с C, поэтому я многому научился. Используя gdb, я обнаружил segfault, когда пытаюсь получить доступ к объекту в родительском процессе. Я использую Вот мой код:Чтение Segfault из общей памяти

#include <sys/stat.h> 
#include <sys/types.h> 
#include <unistd.h> 
#include <sys/mman.h> 
#include <math.h> 

int main(int argc, const char* argv[]) 
{ 

const int SIZE = 4096; 
const char *name = "SM"; 
int shm_fd; 
void *ptr; 

pid_t child; 


if ((argc != 2) || (strtol(argv[1],NULL, 10) <= 0)) 
{ 
     printf("Invalid usage: requires 1 positive integer parameter\n"); 
     return -1; 
} 

child = fork(); 
if(child >=0) 
{ 
     if (child == 0) 
     { 
       shm_fd = shm_open(name, O_CREAT || O_RDWR, 0666); 
       ftruncate(shm_fd, SIZE); 
       ptr = mmap(0, SIZE, PROT_WRITE, MAP_SHARED, shm_fd, 0); 
       int currentval = strtol(argv[1],NULL,10); 
       sprintf(ptr,"%d",currentval); 
       ptr++;/* floor(log10(abs(currentval))) + 1;*/ 
       while (currentval > 1) 
       { 
         sprintf(ptr, ", "); 
         ptr += 2; 
         if (currentval % 2 == 1) 
         { 
           currentval = currentval * 3 + 1; 
           sprintf(ptr, "%d", currentval); 
           ptr++; 
         } 
         else 
         { 
           currentval = currentval/2; 
           sprintf(ptr, "%d", currentval); 
           ptr++; 
         } 
       } 
       sprintf(ptr, "\n"); 
       ptr+= 1; 
       return 0; 
     } 
     else 
     { 
       wait(); 

       shm_fd = shm_open(name, O_RDONLY, 0666); 
       ptr = mmap(0, SIZE, PROT_READ, MAP_SHARED, shm_fd, 0); 
       printf("%s\n",(char *)ptr); 
       shm_unlink(name); 
       return 0; 
     } 
} 
else 
{ 
     printf("error creating child process\n"); 
} 
return 0; 
} 

Я никогда не отлажен на Segfault раньше, поэтому любой совет будет приветствовать. Заранее спасибо.

ответ

1

Я нашел проблему. Он делал логическое ИЛИ вместо побитового ИЛИ, поэтому создавал дескриптор плохого файла.

shm_fd = shm_open (имя, O_CREAT || O_RDWR, 0666);

должен был

shm_fd = shm_open (имя, O_CREAT | O_RDWR, 0666);

0

Вы можете вставить трассировку из основного файла, который создается с помощью GDB:

gdb -c <core file> <executable> 

будет открыть ядро ​​в БГД, затем введите «BT». Это даст вам точное место, где была проблема. Вы также можете вставить этот вывод здесь.

+0

Я думаю, причина может заключаться в том, что ваш mmap может быть неисправен. Вы используете указатель, даже не проверяя условия ошибки. mmap при ошибке возвращает «-1» и устанавливает номер ошибки. – wabbit

+0

Я получаю два основных файла, когда я делаю дамп. Ребенок: '0 0x00832f25 в _IO_str_overflow_internal() из /lib/tls/libc.so.6 # 1 0x00831abf в _IO_default_xsputn_internal() из /lib/tls/libc.so.6 # 2 0x0080c4e8 в vfprintf() из /lib/tls/libc.so.6 # 3 0x00827b1b in vsprintf() из /lib/tls/libc.so.6 # 4 0x00814e3b в sprintf() из /lib/tls/libc.so.6 # 5 0x0804865d в main (argc = 2, argv = 0xbfea2e84) at problem_3_21.c: 42' – user2829815

+0

bt от родителя: '# 0 0x0083c26b в strlen() из /lib/tls/libc.so.6 # 1 0x0080f821 в vfprintf() из /lib/tls/libc.so.6 # 2 0x00814dc0 в printf() из /lib/tls/libc.so.6 # 3 0x08048748 в main (argc = 2, argv = 0xbfea2e84) at problem_3_21.c: 68 ' – user2829815

1

Я знаю, что это не имеет никакого отношения к тому, что вы просили, но так как я наткнулся на этот вопрос, для тех, кто может встретить может найти следующую полезную:

Во время чтения и печати серии для Коллатца гипотезы, если взятый пример - 8, программа выше работает нормально, так как ответ на это: 8, 4, 2, 1 Но если вы попробуете запустить его на 10, ответ на него будет следующим: 10, 5, 16, 8, 4, 2, 1, тогда как указанная выше программа будет показывать только: 1, 5, 16, 8, 4, 2, 1. Потому что она будет читать один символ за раз. И поэтому здесь требуется небольшая модификация.

int shift = 0; 
char store[sizeof(int)]; 
while (currentval > 1) 
{ 
     sprintf(ptr, ", "); 
     ptr += 2; 
     if (currentval % 2 == 1) 
     { 
       currentval = currentval * 3 + 1; 
     } 
     else 
     { 
       currentval = currentval/2; 
     } 
     sprintf(store, "%s", currentval); /* Convert the number to a string */ 
     sprintf(ptr, "%s", store); /* Store the string */ 
     shift = strlen(store); 
     ptr += shift; 
} 
sprintf(ptr, "\n"); 
ptr+= 1;    
Смежные вопросы