Segfault从共享内存中读取

时间:2013-09-30 03:44:00

标签: c segmentation-fault fork shared-memory

我正在编写一个家庭作业问题,使用fork()和共享内存对象在C语言中编写collat​​z猜想的实现,在子进程中执行计算并在父进程中打印出结果。我对C语言并不十分熟悉,所以我学习了很多工具。使用gdb,当我尝试访问父进程中的对象时,我发现了一个段错误。我正在使用这是我的代码:

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

我之前从未调试过段错误,所以任何建议都会受到欢迎。提前谢谢。

3 个答案:

答案 0 :(得分:1)

我发现了这个问题。它正在执行逻辑OR而不是按位OR,因此创建了一个错误的文件描述符。

shm_fd = shm_open(name,O_CREAT || O_RDWR,0666);

应该是

shm_fd = shm_open(name,O_CREAT | O_RDWR,0666);

答案 1 :(得分:1)

我知道这与你提出的问题无关但是因为我遇到了这个问题,对于其他可能遇到的人可能会发现以下内容:

在阅读和打印Collat​​z猜想的系列时,如果采用的示例是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;            

答案 2 :(得分:0)

可以粘贴使用gdb:

创建的核心文件的回溯
gdb -c <core file> <executable>

它会在gdb中打开核心,然后输入“bt”。这将为您提供问题所在的确切位置。您也可以在此处粘贴该输出。