2

很简单地说,如果 C++ 程序执行以下函数(例如,在 Windows 7 上,使用任何 VS 版本编译),然后随后崩溃并且您使用 WER 附加调试器,或者让 WER 生成故障转储并稍后分析此故障转储.

是否可以从dump中的信息直接推断出这个函数被执行了,也就是说,找到执行它的线程的踪迹,就知道这个函数被执行了。

或者当我破坏整个堆栈时,所有执行痕迹都消失了吗?

void bye_bye_stack() {
  int local = 42;
  int* stackaddr = &local;
  while(time(NULL) != NULL) { // prevent optimizations via call to time()
    ++stackaddr; // stack grows towards smaller addresses, so increasing the pointer will point to info we already put on the stack
    *stackaddr = local; // destroy stack content
    // program will (likely) crash here once we reach a read-only page
  }
}
4

3 回答 3

1

这不是直接回答你的问题。

但是,当我遇到堆栈被覆盖时,我曾经启动实用程序 gflags,它会在开始覆盖堆栈时立即断言。

Gflags 由 Microsoft 提供

于 2013-01-18T14:20:03.753 回答
1

一般来说,通过以您正在做的方式销毁堆栈,您将销毁“调用堆栈”,这意味着有关先前调用的例程的信息将消失。但是,如果您从该例程中触发访问冲突/分段错误,则将存储发生这种情况的指令指针,指向该例程。

但是,如果堆栈损坏并且您从该例程返回,那么即使不是不可能,也很难弄清楚发生了什么。

如果您想弄清楚发生了什么,我建议使用调试工具来找出堆栈被“粉碎”的位置。如果您的意图是销毁执行的证据,请确保您从该例程中“跳转”或“返回”,而不会触发异常。

于 2013-01-18T14:32:04.853 回答
-1

这真的取决于。崩溃转储中提供的回溯直接依赖于堆栈中存储的信息。这通常意味着当您怀疑堆栈损坏时,您不能信任回溯。

您提供的函数很可能会破坏整个堆栈,然后当您超出段限制或到达进程无法使用的内存时导致异常。此时堆栈中将没有任何内容来指示嫌疑人。

于 2013-01-18T14:29:45.020 回答