C++ 堆栈溢出和函数指针

C++ 堆栈溢出和函数指针,c++,stack-overflow,function-pointers,C++,Stack Overflow,Function Pointers,我对这件事很迷茫,希望这里有人能帮忙 我的应用程序由数百个计算数字代码的函数组成(每个源代码都在5MB范围内),我使用std::map到函数指针来管理这些函数。 显然,当我试图将一个参数传递给其中一个函数时,会出现堆栈溢出,该函数由指向它的指针访问: gdb输出: Program received signal SIGSEGV, Segmentation fault. 0x0000000001ec0df7 in xsectiond149 (sme=Cannot access memory at

我对这件事很迷茫,希望这里有人能帮忙

我的应用程序由数百个计算数字代码的函数组成(每个源代码都在5MB范围内),我使用
std::map
到函数指针来管理这些函数。 显然,当我试图将一个参数传递给其中一个函数时,会出现堆栈溢出,该函数由指向它的指针访问:

gdb输出:

Program received signal SIGSEGV, Segmentation fault.
0x0000000001ec0df7 in xsectiond149 (sme=Cannot access memory at address 0x7fffff34b888
) at xsection149.c:2
2       Poly3 xsectiond149(std::tr1::unordered_map<int, Poly3> & sme, 
                           EvaluationNode::Ptr ti[], ProcessVars & s)
因此,上述错误中的地址超出了范围

现在我的问题是:如何解决这个问题?我不知道我能在堆上分配什么

在我的主要日程中,唯一的想法是:

// A map containing O(10^4) Poly3 (struct with 6 doubles)
tr1::unordered_map<int, Poly3> smetemp;
// populates smetemp
computeSMEs(smetemp);
// Map of function pointers of type, O(10^3) elements
tr1::unordered_map<int, xsdptr> diagfunctions = get_diagram_map(); 
//一个包含O(10^4)Poly3(带6个双精度的结构)的映射
tr1::无序映射SMETEM;
//填充SMETEM
计算时间(SMETEM);
//类型为O(10^3)元素的函数指针的映射
tr1::无序的_-map-diagfunctions=get_-diagram_-map();
这怎么会溢出堆栈

编辑:我试图在valgrind中运行它,这是我得到的错误,google没有提供任何有意义的信息:

valgrind: m_debuginfo/storage.c:417 (vgModuleLocal_addDiCfSI): 
    Assertion 'cfsi.len < 5000000' failed.
==491==    at 0x38029D5C: ??? (in /usr/lib64/valgrind/memcheck-amd64-linux)
valgrind:m_debuginfo/storage.c:417(vgModuleLocal_addDiCfSI):
断言“cfsi.len<5000000”失败。
==491==0x38029D5C时:???(在/usr/lib64/valgrind/memcheck-amd64-linux中)
EDIT2:将函数分解到失败点(0x0000000001ec0df7)时,会给出:

Dump of assembler code for function xsectiond149(std::tr1::unordered_map<int, Poly3,      std::tr1::hash<int>, std::equal_to<int>, std::allocator<std::pair<int const, Poly3> >,   false>&, std::vector<boost::shared_ptr<EvaluationNode>,    std::allocator<boost::shared_ptr<EvaluationNode> > >&, ProcessVars&):
<...+0>:      push   %rbp                                                               
<...+1>:      mov    %rsp,%rbp                                                          
<...+4>:      push   %r15                                                               
<...+6>:      push   %r14                                                               
<...+8>:      push   %r13                                                               
<...+10>:     push   %r12                                                               
<...+12>:     push   %rbx                                                               
<...+13>:     sub    $0xc96b58,%rsp                                                     
<...+20>:     mov    %rdi,%rbx                                                          
<...+23>:     mov    %rsi,-0xc8b078(%rbp)      // this instr fails                                         
函数xsection149的汇编程序代码转储(std::tr1::无序映射&,std::vector&,ProcessVars&): :按%rbp键 :移动%rsp,%rbp :推送%r15 :推送%r14 :推送%r13 :推送%r12 :按%rbx键 :低于$0xc96b58,%rsp :mov%rdi,%rbx :mov%rsi,-0xc8b078(%rbp)//此指令失败 函数的前几行是:

Poly3 xsectiond149(std::tr1::unordered_map<int, Poly3> & sme,   
                   std::vector<EvaluationNode::Ptr> & ti, 
                   ProcessVars & s)
{
    Poly3 sum(0,0,0,-2);
    Poly3 prefactor, expr;

    // CF*CA^2*NF*NA^(-2)
    double col0 = 0.5625000000000000000000000000;

    prefactor = col0*ti[0]->value()*s.Qtpow2*s.epow2*s.gpow6;
    expr =       (128*(s.p1p2*sme[192]*s.mt - s.p1p2*sme[193]*s.mt +
       1/2.*s.p1p2*sme[195]*s.mt - 1/2.*s.p1p2*sme[196]*s.mt -
       s.p1p2*sme[201]*s.mt + s.p1p2*sme[202]*s.mt +
       1/2.*s.p1p2*sme[210]*s.mt - 1/2.*s.p1p2*sme[211]*s.mt -
       1/4.*s.p1p2*sme[216]*s.mt + 1/4.*s.p1p2*sme[217]*s.mt -
       s.p1p2*sme[219]*s.mt + s.p1p2*sme[220]*s.mt -
       1/8.*s.p1p2*sme[1209]*s.mt + 1/8.*s.p1p2*sme[1210]*s.mt +
       1/2.*s.p1p2*sme[1215]*s.mt - 1/2.*s.p1p2*sme[1216]*s.mt +
   // .....
}
Poly3 xsectiond149(标准::tr1::无序图和sme,
标准::矢量和ti,
ProcessVars&s)
{
Poly3和(0,0,0,-2);
Poly3前因子,expr;
//CF*CA^2*NF*NA^(-2)
双col0=0.562500000000000000000;
prefactor=col0*ti[0]->value()*s.Qtpow2*s.epow2*s.gpow6;
expr=(128*(s.p1p2*sme[192]*s.mt-s.p1p2*sme[193]*s.mt+
1/2.*s.p1p2*sme[195]*s.mt-1/2.*s.p1p2*sme[196]*s.mt-
s、 p1p2*sme[201]*s.mt+s.p1p2*sme[202]*s.mt+
1/2.*s.p1p2*sme[210]*s.mt-1/2.*s.p1p2*sme[211]*s.mt-
1/4.*s.p1p2*sme[216]*s.mt+1/4.*s.p1p2*sme[217]*s.mt-
s、 p1p2*sme[219]*s.mt+s.p1p2*sme[220]*s.mt-
1/8.*s.p1p2*sme[1209]*s.mt+1/8.*s.p1p2*sme[1210]*s.mt+
1/2.*s.p1p2*sme[1215]*s.mt-1/2.*s.p1p2*sme[1216]*s.mt+
// .....
}
(请注意,我在实验过程中更改了函数的签名)

有人能收支相抵吗?你需要哪些额外的信息?对不起,我几乎没有asm方面的经验

EDIT3: 使用
ulimit-s
增加堆栈大小就达到了目的。感谢大家的帮助!

在Valgrind(使用默认工具memcheck)下获取并运行程序。这样,您就可以更轻松地找到故障源

您还可以在Valgrind进入调试器(通常是GDB)的模式下运行Valgrind,然后您可以使用所有酷的GDB命令检查调用者堆栈帧上的值,等等

不管怎样,如果你陷入困境,Valgrind应该帮助你找到一些继续的方向

关于您的编辑,以下是我的回复(引用storage.c的Valgrind源代码r11604):

445/*健全*/
446 VGU断言(cfsi.len>0);
447/*如果失败,则意味着您只有一个过程
448,包含超过500万字节的代码。这很不错
不太可能。不是这样,就是debuginfo阅读器
450.5百万当然是随意的,但它足够大了
451的大小大于
452属于单一程序*/
453 VGU资产(cfsi.len<5000000);

看起来函数
xsectiond149
需要一个大约13MB的堆栈帧(请注意指令
sub$0xc96b58,%rsp
,并且在两条指令之后尝试在其中写入内容时失败)。您需要确保线程具有足够大的堆栈(默认情况下不会)在调用函数之前


您还可以考虑更改代码生成器,以便在堆上而不是堆栈上分配更多的内容。

堆栈溢出或访问冲突?似乎是后者,而不是前者。我想看看引入此segv的签入内容。@GMan:我想这是堆栈溢出,很难说。实际上是访问
smetemp
在调用
xsectiond149(…)之前工作正常
,因此我猜将参数传递给函数时会出现问题。看起来像是简单的堆栈溢出。不要在微小的线程堆栈上声明巨大的变量=P@bbtrb,如果你有5兆的源代码要处理,我想这一切都在源代码控制之下。而且你不只是得到5兆的源代码,它肯定是以这样的速度工作的我在过去指出了这一点。那么,它在工作和失败之间发生了什么变化?找到该签入,希望它能更容易地发现问题。:)Th
Poly3 xsectiond149(std::tr1::unordered_map<int, Poly3> & sme,   
                   std::vector<EvaluationNode::Ptr> & ti, 
                   ProcessVars & s)
{
    Poly3 sum(0,0,0,-2);
    Poly3 prefactor, expr;

    // CF*CA^2*NF*NA^(-2)
    double col0 = 0.5625000000000000000000000000;

    prefactor = col0*ti[0]->value()*s.Qtpow2*s.epow2*s.gpow6;
    expr =       (128*(s.p1p2*sme[192]*s.mt - s.p1p2*sme[193]*s.mt +
       1/2.*s.p1p2*sme[195]*s.mt - 1/2.*s.p1p2*sme[196]*s.mt -
       s.p1p2*sme[201]*s.mt + s.p1p2*sme[202]*s.mt +
       1/2.*s.p1p2*sme[210]*s.mt - 1/2.*s.p1p2*sme[211]*s.mt -
       1/4.*s.p1p2*sme[216]*s.mt + 1/4.*s.p1p2*sme[217]*s.mt -
       s.p1p2*sme[219]*s.mt + s.p1p2*sme[220]*s.mt -
       1/8.*s.p1p2*sme[1209]*s.mt + 1/8.*s.p1p2*sme[1210]*s.mt +
       1/2.*s.p1p2*sme[1215]*s.mt - 1/2.*s.p1p2*sme[1216]*s.mt +
   // .....
}
445     /* sanity */
446     vg_assert(cfsi.len > 0);
447     /* If this fails, the implication is you have a single procedure
448     with more than 5 million bytes of code. Which is pretty
449     unlikely. Either that, or the debuginfo reader is somehow
450     broken. 5 million is of course arbitrary; but it's big enough
451     to be bigger than the size of any plausible piece of code that
452     would fall within a single procedure. */
453     vg_assert(cfsi.len < 5000000);