简体   繁体   English

System V共享内存出现分段错误

[英]Segmentation fault with System V shared memory

I am trying to understand why this simple code leads to a segmentation fault when I try to copy some characters into shared memory using strcpy : 我试图理解为什么当我尝试使用strcpy将一些字符复制到共享内存中时,这个简单的代码会导致分段错误:

#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <string.h>

int main()
{
    key_t key;
    int flag,id;
    char *buf;

    flag=IPC_CREAT|0600;
    if((key=ftok("myfile",12)) == -1 ) {
        perror("key");
        exit(2);
    }   
    printf("%X\n",key);

    if( (id=shmget(key,512,flag)) < 0) exit(1); 

    if( (buf=shmat(id,0,0)) < 0) exit(2);

    printf("PID %d, buf=%p\n",getpid(),buf);
    system("ipcs -m | grep 512");
    sleep(20);

    strcpy(buf,"Hello");
    sleep(100); 
    shmdt(buf);
    exit(0);
}

And here is what I get: 这就是我得到的:

C1A0DAB
PID 12063, buf=0xffffffff8bc78000
0x0c1a0dab 271941746  username      600        512        1
Segmentation fault (core dumped)

Moreover pmap of the process indicates : 另外该进程的pmap表明:

00007f778bc78000      4K rw-s-    [ shmid=0x10358072 ]

I guess something's wrong with pointer buf but I don't know how to correct this so far. 我猜指针buf出了点问题,但到目前为止我还不知道如何解决。

Any ideas? 有任何想法吗?

Please compile with all warnings enabled (at least -Wall for gcc and clang for instance). 请在启用所有警告的情况下进行编译(例如-Wall和clang至少为-Wall )。

You're missing #include <sys/shm.h> , so your compiler assumes that smhat returns an int, when it in fact returns a void* . 您缺少#include <sys/shm.h> ,因此您的编译器假定smhat返回一个int,而实际上却返回一个void* If the size of int and void* don't match, you have a problem. 如果int和void*的大小不匹配,则您有问题。

Add that include, add the other ones you're missing too while you're at it, and it should work. 添加其中包括,添加其他您所缺少的内容,它应该可以工作。

Pay attention to the warnings you get from the compiler. 请注意从编译器得到的警告。 In particular, you get: 特别是,您得到:

file.c:22:5: warning: implicit declaration of function ‘shmat’ [-Wimplicit-function-declaration]
file.c:22:13: warning: assignment makes pointer from integer without a cast

which tells you what the problem is -- the compiler is assuming that shmat returns a (32-bit) integer, when in fact it returns a (64-bit) pointer. 它告诉您问题出在哪里-编译器假设shmat返回一个(32位)整数,而实际上它返回了一个(64位)指针。 So you lose the top 32 bits of the pointer... 因此,您会丢失指针的前32位...

this info, from http://web.cse.ohio-state.edu/~babic/Sem.shmem.new.pdf needs to be taken into account: 需要考虑到来自http://web.cse.ohio-state.edu/~babic/Sem.shmem.new.pdf的此信息:

important: Semaphores and shared memories not explicitly removed stay in the system after a process that created them terminates and even when a user logs off. 重要提示:信号和共享内存未明确删除,即使它们创建的过程终止,甚至在用户注销后,它们仍保留在系统中。

Since UNIX supports limited number of those resources, it is important to make sure that all created semaphores and shared memories are remo ve before logging off. 由于UNIX支持有限数量的那些资源,因此在注销之前,确保所有创建的信号量和共享内存都已删除,这一点很重要。

The directory /usr/class/cis660 include s the script file rsm .dat that provides convenient way to remove all semaphores and all shared memories at once. 目录/ usr / class / cis660包含脚本文件rsm .dat,该脚本文件提供了一种方便的方式来一次删除所有信号量和所有共享内存。

An individual semaphore or shared memo ry may be removed using UNIX command ipcrm –s sem# or ipcrm –m mem# , respectively, where sem# and mem# are obtained from UNIX command ipcs , which lists all semaphores and shared memories 可以分别使用UNIX命令ipcrm –s sem#或ipcrm –m mem#除去单个信号或共享内存,其中sem#和mem#是从UNIX命令ipcs获得的,该命令列出了所有信号和共享内存。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM