【问题标题】:EXCEPTION_ACCESS_VIOLATION exception in Vectored Exception Handler矢量异常处理程序中的 EXCEPTION_ACCESS_VIOLATION 异常
【发布时间】:2017-08-30 03:15:56
【问题描述】:

我有一个捕捉到 EXCEPTION_ACCESS_VIOLATION 异常的向量异常处理程序。

Rip 和异常地址是不包含可执行代码的无效地址。

我需要找出它试图从哪里执行这个无效地址。

我检查了堆栈,但它不可靠。有时会说最后一个返回地址是调用 GetCurrentThreadId() 后返回的,但该 API 没有调用或跳转操作码,因此无法尝试从那里执行。

一个限制是我无法使用调试器单步执行应用程序。

如何找到异常之前执行的先前指令?

【问题讨论】:

  • 这是什么目标? x86?
  • 看起来像堆栈损坏由于某些自动局部变量的缓冲区溢出导致控制到达函数结束时出现异常。您能否运行一些验证程序,如 valgrind 或 Application Validator 来尝试在问题发生时而不是事后捕获此类问题?
  • 在可疑例程的顶部/底部使用 fprintf/fflush 怎么样?当它崩溃时,您可以检查您的日志文件以查看您的位置,然后添加更多日志消息,直到您找到它为止。
  • @old_timer 它的 x64
  • 您无法使用调试器单步执行应用程序代码?如果您可以在调试器中抛出应用程序并且可以很容易地触发异常,则可以在调试器中暂停应用程序,向上抛出断点,取消暂停,然后单步执行直到发生异常..

标签: c++ exception assembly exception-handling


【解决方案1】:

看来您的假设是错误的。访问冲突的发生基本上有三个原因。您正在尝试从无效地址读取数据、将数据写入无效地址或从无效地址读取指令。

在前两种情况下,指令指针是有效的,并且指向具有内存操作数的指令。但是你的情况显然是第三种,因为IP无效。

现在的问题是,IP 是如何损坏的?几乎可以肯定这是一个错误的跳转或分支指令。但为什么那会是 first 有问题的指令呢?您经常执行不打算解释为指令的字节。然后也很清楚堆栈是如何被破坏的。这些字节中的任何一个都可能是 PUSH 或 POP 指令。

x86 没有真正的“执行指令历史”;您得到的最接近的是 L1 缓存内容。这实际上是不可行的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-12
    • 2022-08-13
    • 2012-03-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多