【发布时间】:2017-11-04 16:02:39
【问题描述】:
我正在练习使用 C 在 Linux 中使用共享内存,这是我的代码作为一个简单示例:
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <errno.h>
#define SIZE_OF_MEMORY sizeof(int)
#define SHARED_MEMORY_NAME "GDM123456"
int main()
{
int shm_fd = shm_open(SHARED_MEMORY_NAME, O_RDWR | O_CREAT | O_EXCL, 0777);
if(shm_fd == -1)
{
printf("failed to open shared memory\n");
printf("shm_open error, errno(%d): %s\n", errno, strerror(errno));
exit(1);
}
if(ftruncate(shm_fd, SIZE_OF_MEMORY) == -1)
printf("failed to set size of memory\n");
int * i_ptr = mmap(NULL, SIZE_OF_MEMORY, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
*i_ptr = 1000;
if (munmap(i_ptr, SIZE_OF_MEMORY) == -1)
perror("Error un-mmapping the file");
shm_unlink(SHARED_MEMORY_NAME);
shmctl(shm_fd, IPC_RMID, 0);
}
由于我指定的 SHARED_MEMORY_NAME("GDM123456") 已经在 Linux 服务器中被占用,所以 shm_open 应该返回 -1 并将相应的值设置为 errno(我知道名称已被占用,因为这是一个很多学生将在我们的 Linux 服务器上运行的讲座示例给出的默认值,如果我将名称更改为其他名称,则不会触发“if-failed 块”。
但是,当我尝试运行代码时,结果是:
psyhq@bann:osc$ gcc sharedMemory.c -o sharedMemory -lrt
psyhq@bann:osc$ ./sharedMemory
failed to open shared memory
Segmentation fault (core dumped)
当我尝试打印 errno 时似乎发生了分段错误,所以我想知道这种情况是如何发生的?
这是我的 gdb 的结果:
psyhq@bann:osc$ gdb sharedMemory
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-100.el7
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /lhome/psyhq/osc/sharedMemory...done.
(gdb) r
Starting program: /lhome/psyhq/osc/sharedMemory
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
failed to open shared memory
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff78586e4 in vfprintf () from /lib64/libc.so.6
Missing separate debuginfos, use: debuginfo-install glibc-2.17-196.el7.x86_64
(gdb) b 24
Breakpoint 1 at 0x40095d: file sharedMemory.c, line 24.
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /lhome/psyhq/osc/sharedMemory
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
failed to open shared memory
Breakpoint 1, main () at sharedMemory.c:24
24 printf("shm_open error, errno(%d): %s\n", errno, strerror(errno));
(gdb) p errno
$1 = 17
(gdb) s
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff78586e4 in vfprintf () from /lib64/libc.so.6
(gdb)
PPS:这是我运行代码的 Linux 服务器的版本信息:
psyhq@bann:osc$ cat /proc/version
Linux version 3.10.0-693.2.2.el7.x86_64 (builder@kbuilder.dev.centos.org) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-16) (GCC) ) #1 SMP Tue Sep 12 22:26:13 UTC 2017
【问题讨论】:
-
它“似乎”。那么,什么是?确保使用调试器。
-
我没有得到这个编译没有包括一些标题。
-
@MarcusMüller 我为我的代码运行 gdb...我已将结果添加到我的问题中...而且我是 gdb/Linux-c 的新手...据我了解, errno 的值是正确的,Segfault 是由 printf 引起的……但我仍然不知道这是怎么发生的……你能帮帮我吗?
-
@wildplasser 也许您正在使用-std=c99?我不知道,但它在我们的 Linux 服务器中运行良好......无论如何我都会将我们服务器的版本信息添加到问题中。
-
不,只是默认值 (
std=gnu90)
标签: linux segmentation-fault printf shared-memory errno