奇怪的 MSC 8.0 错误:“ESP 的值未在函数调用中正确保存..."

Weird MSC 8.0 error: quot;The value of ESP was not properly saved across a function call...quot;(奇怪的 MSC 8.0 错误:“ESP 的值未在函数调用中正确保存...)
本文介绍了奇怪的 MSC 8.0 错误:“ESP 的值未在函数调用中正确保存..."的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们最近尝试将我们的一些 Visual Studio 项目拆分为库,并且在一个测试项目中似乎一切都可以正常编译和构建,其中一个库项目作为依赖项.但是,尝试运行该应用程序给我们带来了以下令人讨厌的运行时错误消息:

We recently attempted to break apart some of our Visual Studio projects into libraries, and everything seemed to compile and build fine in a test project with one of the library projects as a dependency. However, attempting to run the application gave us the following nasty run-time error message:

运行时检查失败 #0 - ESP 的值未在函数调用中正确保存.这通常是调用使用不同调用约定声明的函数指针的结果.

Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function pointer declared with a different calling convention.

我们甚至从未为我们的函数指定调用约定(__cdecl 等),将所有编译器开关保留为默认值.我检查了项目设置对于跨库和测试项目的调用约定是一致的.

We have never even specified calling conventions (__cdecl etc.) for our functions, leaving all the compiler switches on the default. I checked and the project settings are consistent for calling convention across the library and test projects.

更新:我们的一位开发人员将基本运行时检查"项目设置从两者(/RTC1,相当于/RTCsu)"更改为默认",运行时消失了,程序显然运行正常.我完全不相信这一点.这是一个适当的解决方案,还是一个危险的黑客攻击?

Update: One of our devs changed the "Basic Runtime Checks" project setting from "Both (/RTC1, equiv. to /RTCsu)" to "Default" and the run-time vanished, leaving the program running apparently correctly. I do not trust this at all. Was this a proper solution, or a dangerous hack?

推荐答案

这个调试错误表示函数调用后栈指针寄存器没有返回到原来的值,即push的次数 函数调用之前的pops 数量不相等.

This debug error means that the stack pointer register is not returned to its original value after the function call, i.e. that the number of pushes before the function call were not followed by the equal number of pops after the call.

据我所知,有两个原因(都是动态加载的库).#1 是 VC++ 在错误消息中描述的内容,但我认为这不是最常见的错误原因(参见 #2).

There are 2 reasons for this that I know (both with dynamically loaded libraries). #1 is what VC++ is describing in the error message, but I don't think this is the most often cause of the error (see #2).

1) 调用约定不匹配:

调用者和被调用者对于谁将做什么没有适当的协议.例如,如果您正在调用 _stdcall 的 DLL 函数,但由于某种原因,您在调用中将其声明为 _cdecl(VC++ 中的默认值).如果您在不同的模块等中使用不同的语言,这种情况会发生很多.

The caller and the callee do not have a proper agreement on who is going to do what. For example, if you're calling a DLL function that is _stdcall, but you for some reason have it declared as a _cdecl (default in VC++) in your call. This would happen a lot if you're using different languages in different modules etc.

您必须检查有问题的函数的声明,并确保它没有被声明两次,而且是不同的.

You would have to inspect the declaration of the offending function, and make sure it is not declared twice, and differently.

2) 类型不匹配:

调用者和被调用者的编译类型不同.例如,一个公共标头定义了 API 中的类型并且最近发生了变化,一个模块被重新编译,但另一个没有——即某些类型在调用者和被调用者中的大小可能不同.

The caller and the callee are not compiled with the same types. For example, a common header defines the types in the API and has recently changed, and one module was recompiled, but the other was not--i.e. some types may have a different size in the caller and in the callee.

在这种情况下,调用者推送一个大小的参数,但被调用者(如果你使用 _stdcall 被调用者清理堆栈的地方)弹出不同大小的参数.因此,ESP 没有返回到正确的值.

In that case, the caller pushes the arguments of one size, but the callee (if you're using _stdcall where the callee cleans the stack) pops the different size. The ESP is not, thus, returned to the correct value.

(当然,这些参数以及它们下面的其他参数在被调用函数中看起来会出现乱码,但有时您可以在没有明显崩溃的情况下幸存下来.)

(Of course, these arguments, and others below them, would seem garbled in the called function, but sometimes you can survive that without a visible crash.)

如果您可以访问所有代码,只需重新编译即可.

If you have access to all the code, simply recompile it.

这篇关于奇怪的 MSC 8.0 错误:“ESP 的值未在函数调用中正确保存..."的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

Rising edge interrupt triggering multiple times on STM32 Nucleo(在STM32 Nucleo上多次触发上升沿中断)
How to use va_list correctly in a sequence of wrapper functions calls?(如何在一系列包装函数调用中正确使用 va_list?)
OpenGL Perspective Projection Clipping Polygon with Vertex Outside Frustum = Wrong texture mapping?(OpenGL透视投影裁剪多边形,顶点在视锥外=错误的纹理映射?)
How does one properly deserialize a byte array back into an object in C++?(如何正确地将字节数组反序列化回 C++ 中的对象?)
What free tiniest flash file system could you advice for embedded system?(您可以为嵌入式系统推荐什么免费的最小闪存文件系统?)
Volatile member variables vs. volatile object?(易失性成员变量与易失性对象?)