当我抛出方法A时,它会导致缓冲区溢出,但是当我返回时,它运行正常。 我认为throw会将执行移动到调用方法,因此它所使用的地址应该与返回地址相同,但我显然是错误的。 有没有办法在Visual Studio调试器中查看抛出的地址?
谢谢
Berkus如是: 这是否意味着上层调用方法的堆栈已损坏?例如,
Method A calls
Method B calls
Method C. Method C throws an exception
然后,方法C的返回地址可能是正常但方法B的返回地址已损坏,导致缓冲区溢出?我所看到的是,如果没有抛出,我的应用程序运行正常,所以我认为方法A,B和C都有有效的返回地址。
答案 0 :(得分:2)
抛出将展开堆栈,直到它到达带有catch的函数。返回地址无关紧要,因为如果需要,throw可以上升几级堆栈帧。
答案 1 :(得分:0)
在C ++中,如果没有try / catch块,那么:
Method A calls
Method B calls
Method C. Method C throws an exception
将终止该申请。如果要避免终止,则必须在代码中使用try / catch块。
答案 2 :(得分:0)
返回地址和抛出异常的确切方式与特定编译器如何实现异常处理的细节有关。要非常肯定地说出任何有关它的信息,这里的某个人必须熟悉这些内部细节。
当然可以想象,缓冲区溢出可能会破坏仅由异常处理使用的数据(从而导致抛出失败),同时保留返回地址不变(从而允许正常返回成功)。但同样,这取决于编译器如何使用堆栈。 (在不同的编译器上,您可能会得到完全不同的症状)。腐败也可能导致你还没有注意到的其他问题。或者,在您下次更改代码后,此类损坏将在未来导致问题。如果堆栈(或C ++所依赖的其他内存)被破坏,那么几乎任何事情都可能发生。
对一些有根据的猜测工作或对编译器细节的了解,我确信有人最终可以回答有关返回地址和投掷方式的具体问题。但是,我真的认为这些问题是错误的。
如果您确实知道缓冲区溢出,那么尝试回答这些问题毫无意义。只需修复超限。
如果您只怀疑自己有超限或正在尝试追踪它是如何发生的,那么请尝试逐步调试调试器中的代码,并观察变量范围之外的内存更改。或者,也许,改变你的功能,总是抛出然后开始逐个评论你的过程的可疑部分。一旦投掷再次开始工作,您可以仔细查看您上次评论的代码,因为问题最有可能存在。如果这些建议没有用,那么我认为这里要问的真正问题是“我如何追踪只影响抛出异常的内存损坏?”。