Windows 中崩溃进程的可预测退出代码

Predictable exit code of crashed process in Windows(Windows 中崩溃进程的可预测退出代码)

本文介绍了Windows 中崩溃进程的可预测退出代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于Windows中正常退出的进程,该进程的退出码一般要么是main的返回值,要么是传递给std::exit的退出码.%ERRORLEVEL% 然后可用于查询退出代码,并可用于确定程序是否正确执行,或者是否有一些异常输入/失败指示特定问题(特定于应用程序).

但是,如果进程崩溃,我对退出代码感兴趣.举一个很简单的例子程序:

int main(){int * a = nullptr;*a = 0xBAD;返回0;}

当我编译它并在 Windows 中运行时,我在命令行上得到:

MyCrashProgram.exe ->崩溃回声 %ERRORLEVEL% ->-1073741819

退出代码始终是这个数字.这让我想到了几个问题:

  • 基于无效写入崩溃,退出代码 -1073741819 是否可以预测?
  • 如果是这样,是否有某种方法可以根据退出代码确定崩溃的类型?
  • 这是否会随着所使用的编译器而改变(我使用的是 MSVC 2012)?
  • 这是否会随着使用的 Windows 版本(我使用的是 Win10 TP)而改变?
  • 这是否会随着架构而改变(例如 x64 - 我使用的是 Win32)?

注意,我对如何修改程序来捕获异常不感兴趣.我有兴趣对现有程序中可能发生的崩溃进行分类,我可能无法修改.

解决方案

关于 STATUS_ACCESS_VIOLATION 的评论,把我带到了 GetExceptionCode:

<块引用>返回值标识异常的类型.下表列出了由于常见编程错误而可能发生的异常代码.这些值在 WinBase.h 和 WinNT.h 中定义.

EXCEPTION_ACCESS_VIOLATION 映射到后面列表中的 STATUS_ACCESS_VIOLATION.列表中以STATUS为前缀的所有异常都直接定义为以EXCEPTION为前缀的异常代码.按照文档 RaiseException,它解释了在异常发生时尝试调试异常的过程,最后一步是:

<块引用>如果进程没有被调试,或者关联的调试器没有处理异常,系统会根据异常类型提供默认处理.对于大多数例外情况,默认操作是调用 ExitProcess 函数.

所以回答我的问题:

  • 是的,退出代码是可预测的,它映射到 EXCEPTION_STATUS_VIOLATION.
  • 其他类型的错误会映射到其他常见的异常代码.但是,通过使用任意异常代码(未处理)调用 RaiseException,进程的退出代码可以是任何东西
  • 退出代码取决于执行 Windows 版本或体系结构的 Windows SDK,而不是编译器.虽然这在理论上可能会随着较新的 ​​Windows SDK 而改变,但这不太可能实现向后兼容性.

For a process exiting normally in Windows, the exit code of the process is generally either the return value from main, or the exit code passed to std::exit. %ERRORLEVEL% can then be used to query the exit code, and that can be used to determine whether the program executed either correctly, or there were some exceptional inputs/failures that indicate a particular problem (application specific).

However, I'm interested in the exit code if the process crashes. Take a very simple example program:

int main()
{
    int * a = nullptr;
    *a = 0xBAD;
    return 0;
}

When I compile this and run in Windows, on the command line I get:

MyCrashProgram.exe -> crashes
echo %ERRORLEVEL%  -> -1073741819

The exit code is consistently this number. Which leads me to several questions:

  • Was the exit code -1073741819 somehow predicable, based on the invalid write crash?
  • If so, is there some way to determine the type of crash, based on the exit code?
  • Does this change with the compiler used (I used MSVC 2012)?
  • Does this change with the version of Windows being used (I used Win10 TP)?
  • Does this change with the architecture (eg. x64 - I used Win32)?

Note, I am not interested in how to modify the program to catch the exception. I am interested in classifying crashes that can happen in existing programs, that I may not be able to modify.

解决方案

The comment about STATUS_ACCESS_VIOLATION, led me to the documentation on GetExceptionCode:

The return value identifies the type of exception. The following table identifies the exception codes that can occur due to common programming errors. These values are defined in WinBase.h and WinNT.h.

EXCEPTION_ACCESS_VIOLATION maps to STATUS_ACCESS_VIOLATION in the list that follows. All exceptions in the list prefixed with STATUS are directly defined to exception codes prefixed with EXCEPTION. Following the documentation to RaiseException, it explains the process of attempting to debug the exception when it occurs, the final step being:

If the process is not being debugged, or if the associated debugger does not handle the exception, the system provides default handling based on the exception type. For most exceptions, the default action is to call the ExitProcess function.

So to answer my questions:

  • Yes, the exit code was predicatble, it maps to EXCEPTION_STATUS_VIOLATION.
  • Other types of errors would map to other common exception codes. However, with a call to RaiseException with an arbitrary exception code (which was unhandled), the exit code of the process could be anything
  • The exit code is dependent on the Windows SDK, not the compiler, executing Windows version or architecture. Although this could theoretically change with newer Windows SDKs, that is highly unlikely for backwards compatibility.

这篇关于Windows 中崩溃进程的可预测退出代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:Windows 中崩溃进程的可预测退出代码