“这个应用程序要求运行时以不寻常的方式终止它”的原因是什么?

有一个常见的错误是由Visual C运行时抛出:

这个应用程序已经请求运行时以不寻常的方式终止它。
请联系应用程序的支持团队获取更多信息。

这个错误信息实际上什么意思


让我用一个比喻来解释我正在问什么。

如果我看到一条消息:

exception:访问冲突(0xc0000005),地址0x702be865

这种访问违规与性骚扰或者试图闯入我的计算机的人无关(不是一般失败是一个准将读我的C驱动程序的准将,或者你可能被拖入监狱执行在Windows 95中的非法操作)。

在这种情况下, 访问冲突对应于常量EXCEPTION_ACCESS_VIOLATION (在winbase.h声明,值为0xC0000005)。 这是一个可能的exception错误代码,可以在EXCEPTION_RECORD结构中返回。 代码ACCESS_VIOLATION意味着程序试图读取或写入内存中不应该存在的地址。 如果你试图从一个从未被分配过的内存地址读取数据,那么你正在做一些非常糟糕的事情 – 而这个例外告诉你。

当程序有一个指向内存的指针时, 通常是不是或者不再是有效的。 解决scheme是停止尝试访问无效的内存。

注意 :我不是问:

  • 为什么程序x得到C0000005错误?
  • 为什么我的代码获取访问冲突?
  • 如何debugging访问冲突?

所以,如果我问你什么原因导致访问冲突 ,你不会告诉我检查堆栈跟踪,或者观察输出窗口,或者发布示例代码。 你会说: “试图访问无效的内存”。


回到我的问题。 以下错误是什么意思:

该应用程序已经请求运行时以不寻常的方式终止。

我(相当)确定Microsoft Visual C运行时库没有函数:

 void TerminateRuntime(bool UnusualWay); 

所以我必须弄清楚它实际上是什么意思:

  • 终止 visual C运行库是什么意思? (msvcrt是一个dll,你不会终止它,你只是不再使用它)
  • 什么是终止MSVCRT 通常的方法?
  • 有人会select不寻常的方式终止它吗?
  • 是不是今天的不寻常的方式,实际上是过去常用的方式?
  • 如果我(错误地)以一种不寻常的方式终止它,我会怎样做才能以通常的方式终止它?

换句话说:什么错误是MSVCRT捕捉,隐藏在无形的错误信息后面?

abort()函数被调用时,你会得到这个消息。

来自MSDN:

退出

中止当前进程并返回一个错误代码。

 void abort( void ); 

返回值

中止不会将控制权返回给调用进程。 默认情况下,它终止当前进程并返回3的退出码。

备注

默认情况下, 中止例程打印消息:

“这个应用程序已经要求运行时以不寻常的方式终止它,请联系应用程序的支持团队获取更多信息。”

似乎在VC运行时的最新版本中,消息已被“abort()已被调用”取代,也许可以澄清它的真正含义。 如果您想重现该消息,请使用旧的VC运行库(肯定是VC ++ 6.0),并调用abort()

在内部,当调用abort()时,它会调用internal.h中定义的一个函数_amsg_exit ,它基本上“为控制台应用程序发出运行时错误消息到stderr,或者在Windows应用程序的消息框中显示消息”。 “这个应用程序请求运行时以exception方式终止它”的错误信息在cmsgs.h中定义:

cmsgs.h

 #define _RT_ABORT_TXT "" EOL "This application has requested the Runtime to terminate it in an unusual way.\nPlease contact the application's support team for more information." EOL 

并且传入的错误代码( _RT_ABORT )在rterr.h中定义:

rterr.h

 #define _RT_ABORT 10 /* Abnormal program termination */ 

所以或者,您可以通过调用_amsg_exit( _RT_ABORT )


问题更新海报 :我问了这个问题两个星期后, Raymond Chen在他自己的博客上回答 :

您正在运行您的程序,然后突然退出并显示消息。 此应用程序已经请求运行时以不寻常的方式终止它。 发生了什么?

该消息是由C运行时函数abort打印的 ,这也是导致程序以退出代码3终止的相同函数。

您的程序可能会显式调用中止,也可能最终被运行时库本身隐式调用。

  • 断言失败时,断言macros调用将中止 。
  • 默认情况下, 终止函数调用中止。

C ++标准规定了terminate调用的条件,这是一个很长的列表,所以我不打扰在这里重复它们。 有关详细信息,请查阅您最喜爱的C ++标准副本。 (最常见的原因是抛出一个未处理的exception。)