• 忘掉天地
  • 仿佛也想不起自己
bingliaolongBingliaolong  2026-08-31 23:29 Aet 隐藏边栏 |   抢沙发  1 
文章评分 1 次,平均分 5.0

windows异常

Windows异常是什么

  1. CPU 执行写内存指令时发现地址无效,产生异常

  1. 异常产生后,Windows 会构造
    1. EXCEPTION_RECORD:异常码、异常地址、附加参数
    2. CONTEXT:异常发生时的寄存器状态,例如 RIP/RSP/RAX

  1. 常见异常码
异常 含义
EXCEPTION_ACCESS_VIOLATION 非法内存访问
EXCEPTION_INT_DIVIDE_BY_ZERO 整数除零
EXCEPTION_ILLEGAL_INSTRUCTION 执行非法指令
EXCEPTION_BREAKPOINT 触发断点
EXCEPTION_STACK_OVERFLOW 栈溢出
EXCEPTION_ARRAY_BOUNDS_EXCEEDED 数组越界异常
0xE06D7363 MSVC C++ 异常常见异常码

SEH:结构化异常处理

  1. Structured Exception Handling,结构化异常处理
  2. 和函数调用栈绑定

  1. MSVC 专用关键字
    1. 它不是标准 C++ 语法

  1. __except 的过滤表达式

  1. 获取异常详细信息

  1. __finally

  1. 为什么说 SEH 是“栈式的”

  1. 需要注意实现差异:
    1. 32x86 传统实现常通过线程异常处理链管理
    2. 64Windows 主要使用 .pdata/.xdata 中的函数表和展开信息

VEH:向量化异常处理

  1. 概述
    1. 进程级异常观察器
    2. Vectored Exception Handling,向量化异常处理
  2. VEH 不使用 __try/__except,而是注册一个全局回调

  1. 注册函数

  1. VEH 处理器通常返回

  1. VEH 没有对应某一个函数作用域,它是:
    1. 进程级注册
    2. 可以看到进程中不同线程产生的异常
    3. 不依赖异常发生函数是否写了 __try
    4. SEH 栈处理器之前得到通知
  2. 因此可以把 VEH 理解成:
    1. Windows 正式沿调用栈寻找 SEH 处理器以前,先调用一组进程级异常回调

VEHSEH 的执行顺序

  1. 流程

  1. 示例

  1. 如果 VEH 返回 EXCEPTION_CONTINUE_EXECUTION
    1. 则表示 VEH 声称已经修复问题,系统不会继续搜索 SEH
  2. 但是如果没有真正修复异常原因,程序可能立即在原位置再次异常
    1. 因此不能为了“让程序不崩溃”就随便返回 EXCEPTION_CONTINUE_EXECUTION

两者最核心的区别

对比项 VEH SEH
全称 Vectored Exception Handling Structured Exception Handling
使用方式 注册回调函数 __try/__except
作用范围 整个进程 当前代码作用域和调用栈
是否绑定函数栈帧
执行时机 SEH 搜索之前 沿调用栈搜索时
是否适合局部恢复 通常不适合 比较适合
是否适合统一监控 适合 不方便
常见用途 调试器、监控、Hook、崩溃记录 局部处理系统异常
生命周期管理 必须主动移除 离开作用域自然消失
  1. 直白地记
    1. VEH 是进程入口处的“全局异常观察器”
    2. SEH 是函数调用栈上的“局部异常处理器”

第一次机会和第二次机会异常

  1. 在调试器中经常能看到

  1. 第一次机会
    1. 异常刚刚发生,Windows 首先通知调试器
    2. 如果程序自己的 VEH/SEH 可以处理,程序可以继续运行
    3. Visual Studio 中看到“发生异常”后停住,有时只是因为调试器选择在第一次机会异常时中断

  1. 第二次机会
    1. 如果 VEHSEH 都没有处理
    2. 第二次机会异常通常意味着程序马上要崩溃

SEHC++异常 try/catch 的关系

  1. 标准 C++ 异常

  1. SEH

  1. 不是同一套语言机制
C++ 异常 Windows SEH
try/catch/throw __try/__except
标准 C++ Windows/MSVC 专用
主要处理程序主动抛出的错误 主要处理硬件和系统级异常
有明确的对象类型 主要通过异常码区分
自动执行 C++ 栈展开语义 行为受编译选项和平台机制影响
  1. MSVC 底层会借助 Windows 异常分发机制实现 C++ 异常,但这不意味着二者在语言层面等价

windows异常和C++异常谁先触发

  1. Windows + MSVC 下,不能简单理解为“Windows 异常和 C++ 异常各触发一次”
  2. 更准确地说:
    1. MSVCC++ 异常底层借助 Windows 异常分发机制实现,所以底层 Windows 异常分发先发生,之后才进入对应的 C++ catch
  3. 主动 throw

  1. 访问违规等硬件异常时

  1. 能否进入 C++ catch(...),取决于编译选项
    1. /EHsc:通常不会把访问违规交给 C++ catch(...)
    2. /EHa:允许 catch(...) 捕获 SEH 异常,但通常不建议捕获访问违规后继续运行

如果同时存在 SEHC++ catch

  1. 究竟哪个处理,不是简单由“SEHC++ 快”决定,而要看:
    1. 哪个处理器在调用栈上更靠近异常点
    2. 是否匹配异常类型
    3. SEH 过滤器返回什么
    4. MSVC 的异常编译选项
    5. 是否继续搜索
  2. VEH 比栈式 SEHC++ catch 更早

Windows其他

消息队列

exe包大小最大多少

  1. 现代 Windows 上一个能够被正常加载执行的 64EXE(PE32+)
    1. 它的加载映像大小理论上最大是 2 GB,准确说必须小于或不超过 Windows/链接器允许的 2 GB 边界
    2. 微软明确规定,PE32+ 虽然使用 64 位地址空间,但 EXE/DLL 的单个可执行映像仍限制在 2 GB
  2. 磁盘上的 EXE 文件大小
    1. 是资源管理器看到的文件大小

文件系统 单文件理论上限
FAT32 4 GiB,实际最大为 4 GiB - 1 byte
NTFS 格式理论值 2^64 - 1 字节,实际受 Windows版本、卷大小等限制
exFAT 格式理论值 2^64 - 1 字节

  1. 加载映像大小
    1. Windows 加载 EXE 后,各个节按照内存对齐映射

  1. 为什么 64EXE 仍限制在 2 GB
    1. 为了让映像中的代码、静态数据、字符串、导入表等可以方便地通过相对地址访问,Windows 将单个 x64 EXE/DLL 映像限制为 2 GB

EXE/DLL文件最大大小

  1. 磁盘文件大小首先受文件系统限制

    1. fat32 4gb-1
    2. ntfs 2^64-1,实际还受 Windows版本、卷大小等限制
    3. exFat 2^64-1,实际同样受实现和存储设备限制
  2. Windows 可执行文件还受 PE 格式限制

    1. 现代64PE32+ EXE/DLL,可加载映像最大约为 2 GiB
    2. 可以在 PE 映像后追加 overlay 数据,使磁盘上的 EXE 超过4 GiB

单线程怎么用异步方式处理多个下载请求

NSIS

  1. WOW32

智能指针

  1. shared_ptr
  2. weak_ptr

函数

声明:本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

bingliaolong
Bingliaolong 关注:0    粉丝:0
Everything will be better.

发表评论

表情 格式 链接 私密 签到
扫一扫二维码分享