Weird MSC 8.0错误:“ESP的值没有在函数调用中正确保存...” [英] Weird MSC 8.0 error: "The value of ESP was not properly saved across a function call..."

查看:186
本文介绍了Weird MSC 8.0错误:“ESP的值没有在函数调用中正确保存...”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们最近试图将我们的一些Visual Studio项目分解成库,并且一个项目似乎在一个测试项目中编译和构建,其中一个库项目作为依赖项。但是,尝试运行应用程序会给我们以下令人讨厌的运行时错误消息:


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


我们从来没有指定调用约定。)为我们的函数,让所有的编译器开关默认。



更新:我们的一个开发人员将基本运行时检查项目设置从 (/ RTC1,等价到/ RTCsu)到默认,运行时消失,让程序显然正确运行。我不相信这一点。

解决方案

这个调试错误意味着堆栈指针寄存器不会返回到它的函数调用之后的原始值,即函数调用之前 push 的数量在调用后未跟随相等数量的 pops



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



1)不匹配的调用约定:



调用者和被调用者没有正确的约定谁将要做什么。例如,如果你调用的是一个DLL函数 _stdcall ,但由于某种原因,它被声明为 _cdecl (在VC ++中为默认值)。如果你在不同的模块中使用不同的语言,这会发生很多。



你必须检查违规函数的声明,并确保它不是



调用者和被调用程序不编译为相同类型。例如,一个公共头定义了API中的类型,并且最近更改了,一个模块被重新编译,但另一个模块没有被重新编译。一些类型在调用者和被调用者中可能具有不同的大小。



在这种情况下,调用者推送一个大小的参数,但是被调用者re使用 _stdcall 其中被调用者清除堆栈)弹出不同的大小。因此,ESP不会返回正确的值。



(当然,这些参数和下面的其他参数在被调用函数中似乎是乱码,但有时你可以生存,没有可见的崩溃。)



如果你有权访问所有的代码,只需重新编译它。


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:

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.

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.

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?

解决方案

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.

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) Mismatched calling conventions:

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) Mismatched types:

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.

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.

这篇关于Weird MSC 8.0错误:“ESP的值没有在函数调用中正确保存...”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆