在 WIN32 与 WIN64 中配置浮点单元上下文

2024-06-24

我正在尝试编写一个未处理的异常过滤器(请参阅 SetUnhandledExceptionFilter())以与 Windows SEH 一起使用来报告无效的浮点操作。我想捕获异常,打印堆栈跟踪,然后禁用浮点异常并使用生成的非有限或非数字值恢复执行。

我编写了下面的简单程序来演示捕获异常并恢复执行的能力。请注意 #ifdef _WIN64 的使用,因为 ContextRecord 的定义会根据目标体系结构而变化(WIN32 使用“FloatSave”,WIN64 使用“FltSave”)。

#include "stdafx.h"
#include <float.h>
#include <Windows.h>

double zero = 0.0;
LONG WINAPI myfunc(EXCEPTION_POINTERS * ExceptionInfo){
    /* clear the exception */
    unsigned int stat = _clear87();

    /* disable fp exceptions*/
    unsigned int ctrl1 = _control87(_MCW_EM, _MCW_EM);

    /* Disable and clear fp exceptions in the exception context */
    #if _WIN64
        ExceptionInfo->ContextRecord->FltSave.ControlWord = ctrl1;
        ExceptionInfo->ContextRecord->FltSave.StatusWord = 0;
    #else
        ExceptionInfo->ContextRecord->FloatSave.ControlWord = ctrl1;
        ExceptionInfo->ContextRecord->FloatSave.StatusWord = 0;
    #endif

    printf("#########Caught Ya#####!\n");

    return EXCEPTION_CONTINUE_EXECUTION;
}


int _tmain(int argc, _TCHAR* argv[])
{
    double a;

    /* enable fp exceptions*/
    _controlfp(0, _MCW_EM);

    /* Setup our unhandled exception filter */
    SetUnhandledExceptionFilter(myfunc);

    /* do something bad */
    a = 5.0 / zero;

    printf("a = %f\n",a);

    return 0;
}

当作为 WIN32 .exe 运行时,上述程序按预期运行,并输出:

#########Caught Ya#####!
a = -1.#IND00

但是,当作为 WIN64 .exe 运行时,程序会进入无限循环,不断重新捕获浮点异常:

#########Caught Ya#####!
#########Caught Ya#####!
#########Caught Ya#####!
#########Caught Ya#####!
#########Caught Ya#####!
#########Caught Ya#####!
...

这似乎表明我没有成功配置浮点单元,我想这与 WIN32 和 WIN64 之间 ContextRecord 的不同定义有关,但我还没有找到任何关于如何准确配置浮点单元的好的相关文档设置浮点上下文。

关于如何正确设置 WIN64 浮点上下文有什么想法吗?

提前致谢


我现在有一个有效的例子。感谢@IInspectable 为我指明了正确的方向(SSE)。问题是 MxCsr 寄存器需要在 ExecutionContext 中设置。请注意,调用 controlfp 确实正确设置了 MxCsr 寄存器,但是,当过滤器函数返回时,所有寄存器都将重置为 ExceptionInfo 中给出的上下文。诀窍是在该上下文中覆盖 MxCsr,下面的代码就是这样做的。

我对 MxCsr 在上下文中的两个位置仍然有点困惑。 controlfp() 似乎将两者设置在一起并设置为相同的值(如调试器中观察到的)。

#include "stdafx.h"
#include <float.h>
#include <Windows.h>
#include <xmmintrin.h>

double zero = 0.0;
LONG WINAPI myfunc(EXCEPTION_POINTERS * ExceptionInfo){
    /* clear the exception */
    unsigned int stat = _clearfp();

    /* disable all fp exceptions*/
    unsigned int ctrlwrd;
    errno_t err =  _controlfp_s(&ctrlwrd, _MCW_EM, _MCW_EM);

    /* Disable and clear the exceptions in the exception context */
    #if _WIN64
        /* Get current context to get the values of MxCsr register, which was
         * set by the calls to _controlfp above, we need to copy these into
         * the exception context so that exceptions really stay disabled.
         * References:
         *    https://msdn.microsoft.com/en-us/library/yxty7t75.aspx
         *    https://software.intel.com/en-us/articles/x87-and-sse-floating-point-assists-in-ia-32-flush-to-zero-ftz-and-denormals-are-zero-daz
         */
        CONTEXT myContext;
        RtlCaptureContext(&myContext);

        ExceptionInfo->ContextRecord->FltSave.ControlWord = ctrlwrd;
        ExceptionInfo->ContextRecord->FltSave.StatusWord = 0;
        ExceptionInfo->ContextRecord->FltSave.MxCsr = myContext.FltSave.MxCsr;
        ExceptionInfo->ContextRecord->FltSave.MxCsr_Mask = myContext.FltSave.MxCsr_Mask;
        ExceptionInfo->ContextRecord->MxCsr = myContext.MxCsr;
    #else
        ExceptionInfo->ContextRecord->FloatSave.ControlWord = ctrlwrd;
        ExceptionInfo->ContextRecord->FloatSave.StatusWord = 0;
    #endif

    printf("#########Caught Ya#####!\n");

    return EXCEPTION_CONTINUE_EXECUTION;
}

int _tmain(int argc, _TCHAR* argv[])
{
    double a;

    /* Enable fp exceptions */
    _controlfp_s(0, 0, _MCW_EM);

    /* Setup our unhandled exception filter */
    SetUnhandledExceptionFilter(myfunc);

    /* do something bad */
    a = 5.0 / zero;

    printf("a = %f\n",a);
    return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 WIN32 与 WIN64 中配置浮点单元上下文 的相关文章

  • 在flex中调用Win32 API设置窗口显示亲和力

    我使用 Adob e Air 创建了一个 Flex 桌面应用程序 我需要保护应用程序不被捕获 通过改变应用程序的窗口显示亲和力 可以保护应用程序不被捕获 如何在flex中使用win API 还有其他方法可以保护窗口不被捕获吗 首先你必须确保
  • 适用于 Windows 的 D-Bus 等效项

    有人知道 Windows 的 Linux D Bus 机制吗 Thanks 选择你的毒药 http msdn microsoft com en us library aa365574 28VS 85 29 aspx http msdn mi
  • 在 WIN32 与 WIN64 中配置浮点单元上下文

    我正在尝试编写一个未处理的异常过滤器 请参阅 SetUnhandledExceptionFilter 以与 Windows SEH 一起使用来报告无效的浮点操作 我想捕获异常 打印堆栈跟踪 然后禁用浮点异常并使用生成的非有限或非数字值恢复执
  • 最常见的已检查和未检查 Java 异常? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 据我了解 如果不逐一查找 API 文档 就无法找出方法抛出了哪些异常 由于这是不可能的 我想反向研究并询问您在处理时遇到的最常见的异常
  • C++ 析构函数中的异常

    从其他线程 我知道我们不应该在析构函数中抛出异常 但对于下面的例子来说 它确实有效 这是否意味着我们只能在一个实例的析构函数中抛出异常 我们应该如何理解这个代码示例 include
  • 如何使用 Windows API 从麦克风录制 wav 声音?

    如何使用 Windows API 从麦克风录制 wav 声音 您可以使用一系列的waveInXXX Windows API 来录制音频 即waveInOpen waveInPrepareHeader waveInAddBuffer wave
  • GCC -fstack-check 选项在 C 中引发什么异常

    根据 gcc 文档 fstack check 生成代码以验证您没有超出堆栈边界 请注意 此开关实际上并不导致检查完成 而是执行检查 操作系统必须这样做 该切换会导致代码生成 以确保操作系统看到正在扩展的堆栈 我的假设是这个额外的代码将生成异
  • 如何区分触摸板生成的 WM_MOUSE*** 消息和鼠标设备生成的 WM_MOUSE*** 消息?

    我试过了GetMessageExtraInfo 这里提到 检测WM MOUSEMOVE是否是由触摸 笔引起的 https stackoverflow com questions 29857587 detect if wm mousemove
  • 双除以零:为什么结果不一致?

    为什么结果是 double a 0 0 0 0 double b 0 0 0 NaN 但结果例如 double e 0 1 0 0 double e 12 0 0 0 double f 1 0 0 0 Infinity 我明白那个doubl
  • 是否可以确定哪个键盘发送了按键?

    我有一个 Windows Media Center 遥控器 Windows 将其识别为键盘 当我使用 Windows Media Center 运行多显示器设置并在一个屏幕上播放视频时 遥控器的输入将与常规键盘一起定向到活动窗口 因此 当我
  • 使用具有不同参数的 Jackson for List 将 JSON 映射到 pojo

    JSON 格式 0 cast showname woh pagle type Episodes video src video mp4 DRM False 这里的问题是我遇到以下异常 org codehaus jackson map Jso
  • 使用 C 序列化 double 和 float

    如何在 C 中序列化双精度数和浮点数 我有以下用于序列化短整型 整数和字符的代码 unsigned char serialize char unsigned char buffer char value buffer 0 value ret
  • 超出 WCF 最大并发会话数

    我的公司申请遇到了问题 我将总结系统的关键要素 我公司的系统几年来一直在 Windows XP 和 7 Home Pro Basic 机器上运行 它是用 NET 4 0 编写的 基于 WCF 它使用默认的限制值 MaxConcurrentS
  • 大负数的指数

    如何在 Python 上计算 np exp 28000 等数字 答案大约是5E 12161 有人告诉我 由于双精度浮点格式 我只能计算 gt 1e 2048 的数字 Try mpmath http mpmath org 用于任意精度的浮点运
  • 核心数据:解决一个奇怪的 EXC_BAD_ACCESS 错误

    我在核心数据方面面临着一个非常奇怪的问题 我们来描述一下 定义 假设我有两个模型 ModelA and ModelB 在数据模型中ModelA有参考ModelB作为一对多关联 因此ModelB与 具有一对一关联ModelA Update 当
  • IExceptionLogger 是否不再需要 Web API 2 中的 ExceptionFilterAttribute?

    根据官方文档关于实施的讨论IExceptionLogger http www asp net web api overview testing and debugging web api global error handling http
  • 用于在 XML 中存储设置的 C++ 库

    在我开始编写自己的设置库之前 我想尝试找到一个现有的设置库 我在 google 上搜索并发现了很多 C 或 MFC 的内容 但没有找到使用普通 C STL 的内容 我想要一些允许通过密钥访问的东西 例如 mySettings Root Su
  • CryptAcquireContext——未解析的外部

    我正在链接第三方库 Poco C 并从链接器获取以下未解决的符号错误 它似乎无法找到 CryptAcquireContextW CryptReleaseContext 和 CryptGenRandom 根据微软信息在这里 http msdn
  • C++ win32 从资源加载字符串

    好吧 我最近决定将应用程序中的每个字符串放入 STRINGTABLE 中 这样我就可以轻松翻译成不同的语言 我知道如何使用 LoadString api 但这涉及我为要加载的每个字符串使用不同的变量 如果我的应用程序有 100 个字符串 那
  • spring-boot中自定义404错误页面

    我正在尝试为 SpringMvc Spring boot 版本 1 5 1 中的无效 URL 创建自定义错误页面 为了禁用默认的白标错误页面 我有 应用程序属性 spring thymeleaf cache false server err

随机推荐

  • 绘制渐变圆

    我正在尝试重现带有渐变圆圈的 Stephen Few 图形 该图形演示了光线从上方出现的硬连线假设 以下是圆圈 我怎样才能重新创建这个 画圆圈还不错 但添加渐变是我遇到的问题 我认为网格可能会创造出更清晰的东西 但这可能是我的误解 从画圆圈
  • 以编程方式在 Chrome 扩展中启用内容脚本

    我开发了一个 chrome 扩展 它工作得非常好 的一部分manifest json看起来像这样 content scripts js js script js css css style css matches http localhos
  • PyCharm 中的 TensorFlow Python 警告 - 在 __init__.py 中找不到引用 __version__

    我正在使用 if tf version lt x x x PyCharm 中的声明 可以在许多 TensorFlow GitHub 示例中找到 如下所示 tensorflow version test py import tensorflo
  • Ionic CSS 类分配

    我正在设计我的应用程序 熟悉基本的主题组件 SASS 等 但有一件突出且没有意义的事情是为什么当我在正在运行的应用程序中预览源代码时会添加大量额外的 CSS 类 就我而言 我只是想更改菜单标题背景 在我的 app html 文件中 我有
  • 如果您的 UIScrollView 已经处于该缩放级别,zoomToRect 不会执行任何操作

    我想我在 UIScrollView 中发现了一个错误 但我想检查其他人是否观察到同样的事情以及它是否是预期的行为 我有一个 UIScrollView 并尝试使用 ZoomToRect 设置它正在查看的内容 效果很好 如果我然后拖动视图 使其
  • 防止 ES6 模板字符串中的换行

    ESLint 第 403 行超过最大行长度 120 max len 我有一个很长的字符串 是使用 ES6 模板字符串构建的 但我希望它没有换行符 var string Let me be the throws Exception to yo
  • 我可以在程序内更改堆栈大小限制吗?

    我可以通过传递配置 GHC 编译的 Haskell 程序的最大堆栈大小 RTS Kn到它 在哪里n是某个数字 有没有办法在程序内更改此设置 我想对各种函数的堆栈消耗进行基准测试 因此尝试在各种限制下运行它 捕获StackOverflow例外
  • SCNNode 静态主体与 .dae 导致问题

    我在 Blender 中构建了一个景观模型 导出到 dae 并添加到我的 xcode 项目中 我已经加载了场景 然后将子项 景观网格 附加到我的景观节点 这加载完美 然而 当我将静态物理体附加到 landscspeNode 时 我的 Her
  • Cython 中固定大小的字节串序列

    我是 Cython 的新手 对 C 的经验很少 所以请耐心等待 我想存储固定大小的不可变字节对象序列 该对象看起来像 obj b abc b 1234 b 元组中的元素是不可变的 但它们的长度是任意的 我尝试的是以下内容 cdef char
  • 使用 Nexus 3 代理私有 docker 注册表

    是否可以使用 nexus oss 3 代理在 docker 发行版上运行的私有 docker 注册表 我能够成功代理 docker hub 但是当我尝试代理我自己的内部注册表时 我最终会遇到图像未找到错误 2016 08 31 15 58
  • C 和 Windows API 之间有什么关系?

    我查看了有关 SO 的其他一些问题 不清楚 c 是构建在 WINAPI 之上 之下还是旁边 例如 有人可以用纯 c 语言编写一些能够打开窗口的东西 或者他们需要使用 windows api 吗 我注意到打开文件 fopen 的 c 库 版本
  • MySQL 和 PHP - 插入 NULL 而不是空字符串

    我有一个 MySQL 语句 它将一些变量插入数据库 我最近添加了 2 个可选字段 intLat intLng 现在 如果未输入这些值 我将传递一个空字符串作为值 如何将显式 NULL 值传递给 MySQL 如果为空 query INSERT
  • 为什么注解属性Rest.rootUrl的值必须是常量表达式?

    我在用着Android 注解框架 https github com excilys androidannotations 专门用于休息整合 我有以下代码 主机配置接口 public interface Host public String
  • C++中调用错误模板函数原型问题

    我目前正在制作自定义矢量容器 以便更好地理解真正的 STL 容器 我遇到了 插入 功能的问题 这是我的矢量容器中 插入 的两个原型 1 template
  • 如何根据一列的字符串相似度链接两个数据框

    我有两个数据框 都有一个 ID 和一个列Name包含字符串 它们可能看起来像这样 数据框 DF 1 DF 2 ID Name ID Name 1 56 aaeessa 1 12 H P paRt 1 2 98 1o7v9sM 2 76 aa
  • 接收任何键盘输入并与 Unity 上的 Switch 语句一起使用

    我不想使用 if 语句 为了简单性和性能 我想使用 switch case 并执行该方法 我希望检测到所有键盘输入 但是有没有什么方法可以传递按键信息呢 我目前的做法是 Update is called once per frame voi
  • Angular 4.x + Cordova:FileReader 无提示失败(白屏死机)

    我有一个 Angular 4 3 Cordova 应用程序 曾经运行得很好 但现在 我在应用程序启动时出现黑屏 并且什么也没有发生 经过一段时间的挖掘 我意识到它来自哪里 我的主页受保护CanActivate守卫将检查一些文件系统持久的首选
  • Rails ActiveRecord 按日期将结果分组到子集合中

    我正在尝试在 Rails 3 1 中执行 ActiveRecord 查询 其中我将结果排序到分组项目的子集合中 在本例中按日期分组 我认为我的代码可以最好地解释它 这是我的方法 它有效 但发出 4 个查询才能完成工作 这样做似乎效率不太高
  • Chrome 和 Firefox 之间的差异:重新加载运行 Javascript 游戏的页面

    我对 Javascript 和 Web 编程总体来说是新手 所以这可能是一个愚蠢的错误 尽管如此 我在寻找相关信息时遇到了问题 我正在用 Javascript 开发一个游戏 玩家可以通过点击并让他们的化身走到不同的建筑物 物体来四处走动并从
  • 在 WIN32 与 WIN64 中配置浮点单元上下文

    我正在尝试编写一个未处理的异常过滤器 请参阅 SetUnhandledExceptionFilter 以与 Windows SEH 一起使用来报告无效的浮点操作 我想捕获异常 打印堆栈跟踪 然后禁用浮点异常并使用生成的非有限或非数字值恢复执