C 函数调用中的堆栈溢出 - MS Visual C++ 2010年快报

发布于 2025-01-01 22:22:40 字数 875 浏览 0 评论 0原文

我用 C 语言编写了一个函数,当调用该函数时,会立即导致堆栈溢出。

原型: void dumpOutput(Settings *, char **, FILE * );

调用行: dumpOutput( stSettings, sInput, fpOut );

调用时,stSettings 已经是指向 Settings 结构体 sInput 的指针 是一个动态分配的二维数组,fpOut 是一个FILE *。它一直到达调用行,没有任何错误,没有内存泄漏等。

实际的函数相当长,我认为不值得在这里分享它,因为溢出发生在代码进入函数时(称为序言部分,我认为)

我尝试使用虚拟变量直接从 main() 调用相同的函数,以检查传递的参数是否存在任何问题,但它仍然会引发堆栈溢出情况。

调用该函数时,错误由 chkstk.asm 产生。该 asm 文件(根据其中的注释)尝试探测堆栈以检查/为被调用函数分配内存。它只是不断跳转到查找下一个较低的页面并探测部分,直到发生堆栈溢出。

dumpOutput 中的局部变量也不是内存野兽,只有 6 个整数和 2 个指针。

进入该函数时代码使用的内存为 60,936K,在发生堆栈溢出时增加到 61,940K。大部分内存都进入sInput。这是错误的原因吗?我不这么认为,因为只传递了它的指针。其次,我不明白为什么 dumpOutput 试图在堆栈上分配 1004K 内存?

我在这里完全不知所措。任何帮助将不胜感激。

提前致谢。

I have written a function in C, which, when called, immediately results in a stack overflow.

Prototype:
void dumpOutput( Settings *, char **, FILE * );

Calling line:
dumpOutput( stSettings, sInput, fpOut );

At the time of calling it, stSettings is already a pointer to Settings structure, sInput is a dynamically allocated 2D array and fpOut is a FILE *. It reaches all the way to the calling line without any errors, no memory leaks etc.

The actual function is rather lengthy and i think its not worth sharing it here as the overflow occurs just as the code enters the function (called the prologue part, i think)

I have tried calling the same function directly from main() with dummy variables for checking if there are any problems with passed arguments but it still throws the stack overflow condition.

The error arises from the chkstk.asm when the function is called. This asm file (according to the comments present in it) tries to probe the stack to check / allocate the memory for the called function. It just keeps jumping to Find next lower page and probe part till the stack overflow occurs.

The local variables in dumpOutput are not memory beasts either, just 6 integers and 2 pointers.

The memory used by code at the point of entering this function is 60,936K, which increases to 61,940K at the point when the stack overflow occurs. Most of this memory goes into the sInput. Is this the cause of error? I don't think so, because only its pointer is being passed. Secondly, i fail to understand why dumpOutput is trying to allocate 1004K of memory on stack?

I am totally at a loss here. Any help will be highly appreciated.

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

那一片橙海, 2025-01-08 22:22:40

根据设计,_chkstk() 的工作是生成堆栈溢出异常。您可以通过查看生成的机器代码来诊断它。进入该函数后,右键单击编辑窗口,然后单击“转到反汇编”。您应该看到与此类似的内容:

003013B0  push        ebp  
003013B1  mov         ebp,esp 
003013B3  mov         eax,1000D4h                  ; <== here
003013B8  call        @ILT+70(__chkstk) (30104Bh) 

通过 EAX 寄存器传递的值是重要的,它是您的函数需要的堆栈空间量。然后 Chkstk 通过探测堆栈页面来验证它实际上是否可用。如果您看到它重复循环,则代码中 EAX 的值很高。像我的一样,它保证消耗堆栈的所有字节。还有更多。这是它所防止的,您通常会收到访问冲突异常。但不能保证,您的代码可能会意外写入属于堆的映射页面。这会产生一个极其难以诊断的错误。 Chkstk() 可以帮助您在沮丧地大吃一惊之前找到这些错误。

我只是用这个小测试函数完成了它:

void test()
{
    char kaboom[1024*1024];
}

我们看不到你的,但例外情况表明你要么有一个大数组作为局部变量,要么你将一个大值传递给 _alloca()。通过从堆中分配该数组来修复。

By design, it is _chkstk()'s job to generate a stack overflow exception. You can diagnose it by looking at the generated machine code. After you step into the function, right-click the edit window and click Go To Disassembly. You ought to see something similar to this:

003013B0  push        ebp  
003013B1  mov         ebp,esp 
003013B3  mov         eax,1000D4h                  ; <== here
003013B8  call        @ILT+70(__chkstk) (30104Bh) 

The value passed through the EAX register is the important one, that's the amount of stack space your function needs. Chkstk then verifies it is actually available by probing the pages of stack. If you see it repeatedly looping then the value for EAX in your code is high. Like mine, it is guaranteed to consume all bytes of the stack. And more. Which is what it protects against, you normally get an access violation exception. But there's no guarantee, your code may accidentally write to a mapped page that belongs to, say, the heap. Which would produce an incredibly difficult to diagnose bug. Chkstk() helps you find these bugs before you blow your brains out in frustration.

I simply did it with this little test function:

void test()
{
    char kaboom[1024*1024];
}

We can't see yours, but the exception says that you either have a large array as a local variable or you are passing a large value to _alloca(). Fix by allocating that array from the heap instead.

莫言歌 2025-01-08 22:22:40

最有可能是堆栈损坏或递归错误,但在没有看到任何代码的情况下很难回答

Most likely a stack corruption or recursion error but it's hard to answer without seeing any code

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文