0

当我输入方法 A 时,它会导致缓冲区溢出,但当我返回时,它运行良好。我认为 throw 将执行转移到调用者方法,所以它去的地址应该与返回地址相同,但我显然错了。有没有办法在 Visual Studio 调试器中查看抛出的地址?

谢谢

Berkus:这是否意味着上层调用方法的堆栈已损坏?例如,

Method A calls 
   Method B calls 
      Method C. Method C throws an exception 

那么,有可能是方法C的返回地址没问题,但方法B的返回地址损坏,导致缓冲区溢出?我看到的是,如果没有抛出,我的应用程序运行良好,所以我认为方法 A、B 和 C 都有有效的返回地址。

4

3 回答 3

2

Throw 将展开堆栈,直到它到达带有 catch 的函数。返回地址无关紧要,因为 throw 可以在必要时上几级堆栈帧。

于 2010-06-14T17:11:16.557 回答
0

确切的返回地址和抛出的异常如何交互取决于您的特定编译器如何实现异常处理的细节。要确定地谈论它,这里的人必须熟悉这些内部细节。

当然可以想象,缓冲区溢出可能会损坏仅由异常处理使用的数据(从而导致 throw 失败),同时保持返回地址不变(从而允许正常返回成功)。但同样,这取决于您的编译器如何使用堆栈。(在不同的编译器上,您可能会得到完全不同的症状)。腐败也可能导致您根本没有注意到的其他问题。或者这种损坏会在您下次更改代码后导致将来出现问题。如果堆栈(或 C++ 依赖的其他内存)损坏,那么几乎任何事情都可能发生。

通过一些有根据的猜测或对编译器细节的了解,我相信最终有人可以回答有关返回地址和抛出如何工作的具体问题。但是,我真的认为这些是错误的问题。

如果您确实知道缓冲区溢出,那么尝试回答这些问题是没有意义的。只需修复溢出。

如果您只是怀疑您有溢出或试图追踪它是如何发生的,那么请尝试在调试器中单步执行您的代码并观察变量范围之外的内存更改。或者,也许,将您的函数更改为始终抛出,然后开始一一注释掉过程中的可疑部分。一旦 throw 再次开始工作,您就可以仔细查看您上次评论的代码,因为问题很可能就在那里。如果这些建议没有帮助,那么我认为这里要问的真正问题是“我如何追踪只影响抛出异常的内存损坏?”。

于 2010-06-14T18:49:08.687 回答
0

在 C++ 中,如果你没有 try/catch 块,那么:

Method A calls 
   Method B calls 
      Method C. Method C throws an exception 

将终止应用程序。如果要避免终止,您的代码中必须有一个 try/catch 块。

于 2010-06-14T17:36:36.817 回答