Predictable exit code of crashed process in 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
:
EXCEPTION_ACCESS_VIOLATION
映射到后面列表中的 STATUS_ACCESS_VIOLATION
.列表中以STATUS
为前缀的所有异常都直接定义为以EXCEPTION
为前缀的异常代码.按照文档 RaiseException
,它解释了在异常发生时尝试调试异常的过程,最后一步是:
所以回答我的问题:
- 是的,退出代码是可预测的,它映射到
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 中崩溃进程的可预测退出代码
基础教程推荐
- 管理共享内存应该分配多少内存?(助推) 2022-12-07
- 如何使图像调整大小以在 Qt 中缩放? 2021-01-01
- 使用从字符串中提取的参数调用函数 2022-01-01
- Windows Media Foundation 录制音频 2021-01-01
- 为什么语句不能出现在命名空间范围内? 2021-01-01
- 如何“在 Finder 中显示"或“在资源管理器中显 2021-01-01
- 为 C/C++ 中的项目的 makefile 生成依赖项 2022-01-01
- 在 C++ 中循环遍历所有 Lua 全局变量 2021-01-01
- 如何在不破坏 vtbl 的情况下做相当于 memset(this, ...) 的操作? 2022-01-01
- 从 std::cin 读取密码 2021-01-01