故意使我的 Windows 应用程序崩溃的最佳方法是啥?

Posted

技术标签:

【中文标题】故意使我的 Windows 应用程序崩溃的最佳方法是啥?【英文标题】:What's the best way to deliberately crash my Windows application?故意使我的 Windows 应用程序崩溃的最佳方法是什么? 【发布时间】:2014-10-20 23:28:10 【问题描述】:

我在我的 Qt 应用程序的 Windows 版本中添加了一个 mini-core-dump 功能(通过 __try/__except 和 MiniDumpWriteDump()),因此如果/当我的应用程序崩溃时,将写入一个 .dmp 文件输出到磁盘供我稍后查看和调试。

这很好用,但为了测试,我希望有一个已知可靠的方法来让我的程序崩溃。例如,GUI 中可能有一个“立即崩溃”按钮,当用户单击它时,它会导致应用程序故意崩溃。

当然,一种方法是这样的:

int * badPointer = NULL;
*badPointer = 666;

这对我有用,但我不喜欢这种方法,因为它依赖于未定义的行为——特别是,C++ 标准不要求上述代码导致崩溃,所以有可能(从语言律师的角度来看)当上述代码执行时,某些未来版本的编译器不会崩溃。

作为一种更“官方”的方法,我尝试了这个:

abort();

...确实会终止程序,但不会导致触发 MiniCrashDump 处理程序的 Windows 结构化异常,因此不会写入 .dmp 文件。

我的问题是,是否有“官方正确的方法”可以让我的程序崩溃?我看到 Windows API 有一个可以调用的 RaiseException() 函数,但我不确定它的正确参数应该是什么。这是要走的路吗,还是有一些更具体的电话我最好使用?

【问题讨论】:

锤击屏幕。 您正在大量使用特定于实现的关键字和行为,并且您担心某天 C++ 规范可能会说些什么?当然,RaiseException() 是官方的方式。 @HansPassant 让我担心的不是 C++ 规范,而是 MSVC 优化器,它可能会开始做 gcc 风格的思维技巧,比如说“因为我知道 badPointer 是 NULL,并且因为取消引用 NULL指针是未定义的行为,我可以优化掉那个写“......然后突然我的崩溃按钮不再崩溃了。 :) 【参考方案1】:

如果您知道自己在 Windows 上运行,那么取消引用空指针会导致访问冲突是完全没问题的 - Windows 提供比 C++ 语言更强大的保证。 C++ 说取消引用空指针是未定义行为,但 Windows 将此定义为访问冲突(就 C++ 而言,这是完全可以接受的,因为访问冲突是未定义行为的一种可能结果)。

来自Managing Virtual Memory:

Windows NT 在每个进程的地址空间中都建立了保护措施。每个进程的高低 65,536 字节均由系统永久保留。地址空间的这些部分被保留用于捕获杂散指针——试图在 0000000016-0000FFFF16 或 7FFF000016范围内寻址内存的指针>-7FFFFFFF16。并非巧合的是,只需忽略这些地址中的低四个半字节(最右边的两个字节),就很容易检测到该范围内的指针。本质上,如果高四位为 000016 或 7FFF16,则指针无效;所有其他值都表示有效地址。

内存的第一页始终映射为PAGE_NOACCESS,因此如果您尝试读取或写入空指针(或空指针 +/-64 KB 内的任何指针),您将始终引发访问冲突异常。

【讨论】:

以上是关于故意使我的 Windows 应用程序崩溃的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

Firebase Crashlytics 未报告崩溃

为啥在 C 中使用错误的格式说明符会使我的程序在 Windows 7 上崩溃?

为啥 __inbyte 会使我的软件崩溃?

SNMP 扩展使我的 php 5.6.7 和 5.6.10 (windows 8) 崩溃

_tableView reloadData 使我的应用程序崩溃

Log.d(String, String) 使我的程序崩溃?