gpt4 book ai didi

c - mmap/munmap 问题 - 在第 783 次迭代后出现总线错误?

转载 作者:IT王子 更新时间:2023-10-29 00:37:53 24 4
gpt4 key购买 nike

好的,这是设置:我在 HPC 工作,我们正在为扩展到数万个节点的需求做准备。为了解决这个问题,我实现了一个本地进程,在每个节点上缓存信息以减少网络流量。然后它通过共享内存公开此信息。基本逻辑是有一个众所周知的共享内存块,其中包含当前缓存表的名称。当更新发生时,缓存工具创建一个新的共享内存表,填充它,然后用新表的名称更新众所周知的 block 。

代码似乎可以正常工作(例如,valgrind 说没有内存泄漏)但是当我故意对其进行压力测试时,前 783 次更新工作得非常好 - 但在第 784 次,当我尝试更新时出现 SIGBUS 错误写入映射内存。

如果问题是打开的文件太多(因为我正在泄漏文件描述符),我预计 shm_open() 会失败。如果问题是我正在泄漏映射内存,我希望 mmap() 失败或 valgrind 报告泄漏。

这是代码片段。谁能给个建议?

int
initialize_paths(writer_t *w, unsigned max_paths)
{
int err = 0;
reader_t *r = &(w->unpublished);

close_table(r,PATH_TABLE);

w->max_paths = max_paths;

err = open_table(r, PATH_TABLE, O_RDWR | O_CREAT, max_paths, 0);

return err;
}

static void
close_table(reader_t *r, int table)
{
if (r->path_table && r->path_table != MAP_FAILED) {
munmap(r->path_table,r->path_table->size);
r->path_table=NULL;
}
if (r->path_fd>0) { close(r->path_fd); r->path_fd=0; }
}


static int
open_table(op_ppath_reader_t *r, int table, int rw, unsigned c, unsigned c2)
{
// Code omitted for clarity
if (rw & O_CREAT) {
prot = PROT_READ | PROT_WRITE;
} else {
// Note that this overrides the sizes set above.
// We will get the real sizes from the header.
prot = PROT_READ;
size1 = sizeof(op_ppath_header_t);
size2 = 0;
}

fd = shm_open(name, rw, 0644);
if (fd < 0) {
_DBG_ERROR("Failed to open %s\n",name);
goto error;
}

if (rw & O_CREAT) {
/* Create the file at the specified size. */
if (ftruncate(fd, size1 + size2)) {
_DBG_ERROR("Unable to size %s\n",name);
goto error;
}
}

h = (op_ppath_header_t*)mmap(0, size1 + size2, prot, MAP_SHARED, fd, 0);
if (h == MAP_FAILED) {
_DBG_ERROR("Unable to map %s\n",name);
goto error;
}

if (rw & O_CREAT) {
/*
* clear the table & set the maximum lengths.
*/
memset((char*)h,0,size1+size2); -- SIGBUS OCCURS HERE
h->s1 = size1;
h->s2 = size2;
} else {
// more code omitted for clarity.
}

更新:

下面是一些失败的示例调试输出:

NOTICE: Pass 783: Inserting records.
NOTICE: Creating the path table.
TRC: initialize_paths[
TRC: close_table[
TRC: close_table]
TRC: open_table[
DBG: h=0x0x2a956b2000, size1=2621536, size2=0

这是上一次迭代的相同输出:

NOTICE: Pass 782: Inserting records.
NOTICE: Creating the path table.
TRC: initialize_paths[
TRC: close_table[
TRC: close_table]
TRC: open_ppath_table[
DBG: h=0x0x2a956b2000, size1=2621536, size2=0
TRC: open_ppath_table]
TRC: op_ppath_initialize_paths]

请注意,指针地址是有效的,大小也是有效的。

GDB 以这种方式报告崩溃:

Program received signal SIGBUS, Bus error.
[Switching to Thread 182895447776 (LWP 5328)]
0x00000034a9371d20 in memset () from /lib64/tls/libc.so.6
(gdb) where
#0 0x00000034a9371d20 in memset () from /lib64/tls/libc.so.6
#1 0x0000002a955949d0 in open_table (r=0x7fbffff188, table=1, rw=66,
c=32768, c2=0) at ofedplus_path_private.c:294
#2 0x0000002a95595280 in initialize_paths (w=0x7fbffff130,
max_paths=32768) at path_private.c:567
#3 0x0000000000402050 in server (fname=0x7fbffff270 "gidtable", n=10000)
at opp_cache_test.c:202
#4 0x0000000000403086 in main (argc=6, argv=0x7fbffff568)
at opp_cache_test.c:542

(gdb)

当在下一行设置 h->size1 并且 size1 是映射区域的前 4 个字节时,删除 memset 仍然会导致 SIGBUS。

最佳答案

SIGBUS 可能是由对您的 SHM 对象的多次引用引起的。
查看上面的代码,您使用了 shm_open()mmap()munmap() 但是
你缺少 shm_unlink()

正如 *shm_open/shm_close 的联机帮助页所述,这些对象是引用计数的。

The operation of shm_unlink is analogous to unlink(2): it removes a shared memory object name, and, once all processes have unmapped the object, deallocates and destroys the contents of the associated memory region.
After a successful shm_unlink, attempts to shm_open an object with the same name will fail (unless O_CREAT was specified, in which case a new, distinct object is created).

也许这些信息将有助于解决您的问题。

关于c - mmap/munmap 问题 - 在第 783 次迭代后出现总线错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1667909/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com