首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >共享内存段的间歇SIGBUS

共享内存段的间歇SIGBUS
EN

Stack Overflow用户
提问于 2022-04-13 00:19:44
回答 1查看 74关注 0票数 0

我有一个服务器进程,它使用System共享内存调用(shmget/shmat)分配一大块内存,从address到0x500000000到0x1d00000000,然后将其绑定到第一个NUMA节点。请参阅下面的伪代码(它在逻辑上应该是正确的,但可能无法编译)。

问题是,有时当我访问内存时,我会得到一个SIGBUS信号,但大多数时候我没有,它大部分时间都能工作。我使用信号处理程序来优雅地捕获信号(也包括SIGSEGV )。

我不明白这是怎么回事。什么会导致SIGBUS的不稳定?

代码语言:javascript
复制
size_t totalSize_ = 96 GiB;
const int flags = IPC_CREAT         // creatE a new shared memory segment
                    | SHM_HUGETLB   // huge pages
                    | SHM_NORESERVE // don't reserve swap space for this.
                    | 0666          // Leave the leading 0 (octal)
                    | SHM_R | SHM_W // These are redundant with 0666
    ;
shmid_ = shmget(key_, totalSize_, flags);

void* desiredBase = 0x0x500000000; 
auto base = shmat(shmid_, desiredBase, 0);

uint32_t mask = 1; // first NUMA node
mbind(base , totalSize_ , MPOL_BIND, &mask, 64, 0) ;

然后,我做了一些测试,以确保内存是可访问的(因为NUMA绑定),方法是逐步遍历地址空间并调用memcpy每个GiB。

代码语言:javascript
复制
for(addr = base; addr < last, addr += 1GiB)
   memcpy(addr, "testpattern",10);

然后我寻找SIGBUS信号。如果NUMA节点没有足够大的页面内存分配给它,我会得到SIGBUS信号。这很好。但是,如果我用相同的代码和设置重新启动服务器,有时它会在第3大页上给我一个SIGBUS。然后我再重新启动它,它对所有96个巨大的页面都很好。我们的系统每个NUMA节点(4个节点)有100 GiB的巨大页面内存。

我如何调试这个?哪些日志文件是有用的?在memcpy上添加一个重试循环直到SIGBUS消失是否有意义?

/proc/self/maps的第一部分如下所示:

代码语言:javascript
复制
00400000-01213000 r-xp 00000000 103:07 4986562                           /opt/daemon-0.0.9/bin/daemon
01413000-01415000 r-xp 00e13000 103:07 4986562                           /opt/daemon-0.0.9/bin/daemon
01415000-0141b000 rwxp 00e15000 103:07 4986562                           /opt/daemon-0.0.9/bin/daemon
0141b000-01427000 rwxp 00000000 00:00 0
01b5d000-01bfa000 rwxp 00000000 00:00 0                                  [heap]
500000000-1d00000000 rwxs 00000000 00:0d 44072961                        /SYSV50420051 (deleted)
2aaac0000000-2aab00000000 rwxp 00000000 00:0d 83594486                   /anon_hugepage (deleted)
7ff9e4000000-7ff9e4021000 rwxp 00000000 00:00 0
7ff9e4021000-7ff9e8000000 ---p 00000000 00:00 0
EN

回答 1

Stack Overflow用户

发布于 2022-05-05 03:02:35

你的旗帜中的SHM_NORESERVE可能是罪魁祸首。来自the docs for shmget()

不为此段保留交换空间。当预留交换空间时,可以保证可以修改段。当交换空间没有保留时,如果没有可用的物理内存,则如果没有可用的物理内存,则可能在写入时获得SIGSEGV

(强调后加)

段创建、绑定和后续访问通常工作,这一事实表明了某种上下文效应,例如当前可用物理内存的数量,而使用该标志创建段的风险中明显存在分段错误。

SIGSEGVSIGBUS并不完全相同,但两者都是在类似的情况下生成的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71850463

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档