本文介绍了Stackoverflow和函数指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我的应用程序包括数百个函数评估数字代码(源在5MB范围每个)和我管理函数与 std :: map 到函数指针。
显然发生的是,当试图向一个函数传递一个参数时,我得到一个栈溢出,通过一个指针访问它:



gdb输出:

 编程接收信号SIGSEGV,分段故障。 
0x0000000001ec0df7 in xsectiond149(sme =无法访问内存地址0x7fffff34b888
)at xsection149.c:2
2 Poly3 xsectiond149(std :: tr1 :: unordered_map< int,Poly3& ,
EvaluationNode :: Ptr ti [],ProcessVars& s)

和xsection149。 c:2只有用于定义函数的开始大括号。



/ proc /< pid> / map 为过程显示最接近触发错误的地址的地址范围只有这一行:

  7ffffff74000-7ffffffff000 rw -p 7ffffff73000 00:00 0 [stack] 

因此上述错误中的地址超出范围。



现在我的问题:如何解决这个问题?我不能封装我的头在我可以分配在堆上...



唯一认为发生在我的主程序是:

  //包含O(10 ^ 4)Poly3(具有6个双精度的结构)的映射
tr1 :: unordered_map< int,Poly3& sm
//填充smetemp
computeSMEs(smetemp);
//类型的函数指针的映射,O(10 ^ 3)元素
tr1 :: unordered_map< int,xsdptr> diagfunctions = get_diagram_map();

如何溢出堆栈?



编辑:我试图运行它在valgrind,这是我得到的错误,谷歌没有给任何有意义的信息:

  valgrind:m_debuginfo / storage.c:417(vgModuleLocal_addDiCfSI):
断言'cfsi.len< 5000000失败。
== 491 == at 0x38029D5C:? (在/ usr / lib64 / valgrind / memcheck-amd64-linux)

EDIT2 :反汇编函数直到失败的地方(0x0000000001ec0df7)给我:

 函数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)//此instr失败

并且函数的前几行读为:

  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 * .mt + s.p1p2 * sme [220] * s.mt -
1 / 8. * s.p1p2 * sme * s.mt + 1 / 8. * s.p1p2 * sme [1210 ] * s.mt +
1 / 2. * s.p1p2 * sme * s.mt-1 / 2. * s.p1p2 * sme * s.mt +
// .....
}

实验期间的功能)



任何人都可以满足这里的情况?你需要哪些额外的信息对不起,但我几乎没有asm的经验



EDIT3
使用 ulimit -s< size>

解决方案

它看起来像函数 xsectiond149 需要大约13 MB的堆栈帧(请注意指令 sub $ 0xc96b58,%rsp 写下来有两个指令后)。你需要确保线程有足够大的堆栈(默认情况下它不会)在调用该函数之前。



你也可以考虑改变你的代码生成器在堆上分配更多的东西而不是堆栈。


I'm quite lost on this one and I hope someone here could help.

My application consists of hundreds of functions evaluating numerical code (source is in the 5MB range each) and I manage the functions with a std::map to function pointers. What apparently happens is that I get a stack overflow when trying to pass an argument to one of the functions, accessed by a pointer to it:

gdb output:

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)

and xsection149.c:2 has only the opening brace for the definition of the function.

/proc/<pid>/map for the process shows for the address range closest to the address that triggers the error only this line:

7ffffff74000-7ffffffff000 rw-p 7ffffff73000 00:00 0                      [stack]

so the address in the above error is out of bounds.

Now my question: How do I resolve this problem? I can not wrap my head around as to what I could allocate on the heap...

The only think that happens in my main routine is:

// 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(); 

How could this overflow the stack??

EDIT: I've tried to run it in valgrind, this is the error I get and google didn't give any meaningful info:

valgrind: m_debuginfo/storage.c:417 (vgModuleLocal_addDiCfSI): 
    Assertion 'cfsi.len < 5000000' failed.
==491==    at 0x38029D5C: ??? (in /usr/lib64/valgrind/memcheck-amd64-linux)

EDIT2: Disassembling the function up to the point where it fails (0x0000000001ec0df7) gives me:

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                                         

and the first few lines of the function read:

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 +
   // .....
}

(Note that I have changed the signature of the function during experimentation)

Can anyone make the ends meet to what is going on here? Which additional information would you need? Sorry, but I have almost no experience with asm.

EDIT3:Increasing the stack size with ulimit -s <size> did the trick. Thank you all for your help!

解决方案

It looks like the function xsectiond149 needs a stack frame of about 13 MB (note the instruction sub $0xc96b58,%rsp, and the failure as soon as it tries to write something down there two instructions later). You need to ensure that the thread has a large enough stack (by default it won't) before calling the function.

You might also look into changing your code generator to allocate more stuff on the heap instead of the stack.

这篇关于Stackoverflow和函数指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-24 23:51