立即处理可能影响正在运行的系统已审查 build 2.4.17066 至 2.4.17082 的全部 17 个 non-merge commit:新增 498 行、删除 536 行。忽略 mormot.commit.inc 与 mormot.commit-num.inc 的纯版本变更。没有 commit 带 superseded_by;顺序来自直接检查的同 unit follow-up,不声明避开区间。
异常历史记录重构,OpenSSL 再获 I/O 修复
上游确认旧的最近异常存储存在随机 GPF 与不安全的内存/threading 模型后,异常拦截路径被大幅重构。最终实现修正了 newest-first 读取,并为每个异常保存有界 stack。OpenSSL Send/Receive 重试与 setup 错误报告得到两个最终修复,FPC 同时改进 stack 捕获并修复 ARM32 确定性 seed。
要点
- 应采用 build 2.4.17082 的 03ab5c85c4b2982c96b7f38d683dbff85e016f77。
- GetLastException 与 GetLastExceptions 现在使用带锁的 16-entry ring,并为每个异常保存独立 stack 副本。
- OpenSSL 仅重试 WANT_READ/WANT_WRITE,设置五秒上限,并在 setup 失败时不再误用 SSL_get_error。
- 公开 class method TDebugFile.AddLog 已移除;外部调用方必须迁移到保留的 location 或 StackTrace API。
- KEEP_STACKFRAMES 可保留项目 stack-frame 设置,主要用于 FPC POSIX 调试,但有明确的性能成本。
- FPC Windows 使用 RTL 捕获的异常 stack,FPC ARM32 则为 TLecuyer.SeedGenerator 提供稳定的 QWord 存储。
升级建议
请采用 build 2.4.17082。若生产环境使用异常拦截、GetLastException/GetLastExceptions 或异步 OpenSSL socket,应尽快升级;测试并发异常、newest-first Depth、证书/setup 失败及相反方向 WANT 转换。搜索 TDebugFile.AddLog,因为公开 class method 已移除。仅在 FPC POSIX 诊断值得其性能成本时启用 KEEP_STACKFRAMES。原始 payload 没有 superseded_by 标记,因此不声明避开区间。
17 条中的 17 条 · 上游 17 次提交
1
高
最近异常存储重构,消除随机 GPF 与不安全共享
mormot.core.log 用 TLightLock 保护的 16-slot ring 取代旧的共享 stack/index。每个 TSynLogExceptionInfo 保存最多 16 个过滤地址,清除 EInstance/EStack 引用,并在异常仍有效时复制 Message。
修复
mormot.core.log
8298b7c1+143-124
core: rewritten last exception in-memory storage
影响
并发异常拦截不再通过共享可变存储暴露其他异常的 stack,也不再保留失效异常 instance。上游明确指出旧设计会造成随机 GPF 及不安全的 memory/threading 行为。
建议升级
启用异常拦截的服务应升级到 build 2.4.17080,并压力测试并发异常及 GetLastException/GetLastExceptions 读取。
公开 API
TSynLogStackTraceadded — 新增公开固定数组,每个异常保存最多 MAX_STACK_TRACE 个过滤地址。TSynLogExceptionInfo.StackTraceadded — 每个返回的异常记录现在拥有自己的 stack 地址副本。PSynLogExceptionInfoadded — 新增 TSynLogExceptionInfo 的公开 pointer alias。
2
高
磁盘异常日志复用安全复制的历史 stack
SynLogException 现在写入历史 ring 复制前预计算的过滤 frame,不再在文件 writer 路径中解析第二份 stack。嵌套 try/except 被简化,writer lock 仍由 finally 保护。
修复
mormot.core.log
ff2fda39+46-67
core: rewritten exception logging code
影响
内存历史与磁盘日志描述同一 call stack,符号解析不再于不稳定异常上下文中执行两次。上游说明这可避免大多数符号解析不稳定。
建议升级
异常密集服务应升级到 build 2.4.17080,并在并发失败下比较磁盘 trace 与 GetLastExceptionText。
3
高
最近异常读取修正 slot,并按 newest-first 应用 depth
GetLastException 读取 Infos[Next - 1],Next 为零时回绕到数组长度。GetLastExceptions 从 Next 向后遍历,遇空项停止,对最新记录应用 Depth,并按 latest-first 返回。
修复
mormot.core.log
efe676a8+28-36
core: GetLastException/GetLastExceptions fixes
影响
调用方不再把下一个未写 slot 当作最新异常,Depth 也不再选择或排序 ring 的错误一侧。Delphi Win32 手动 fallback 还被明确限制到 WIN32DELPHI。
建议升级
采用该历史重构的最终修复,并在并发异常下测试 Depth=1、ring 大小及更大值。
4
高
OpenSSL setup 失败不再向 I/O 错误 API 查询上下文
原 TOpenSslNetTls.Check 重命名为 CheckRes,在处理 context/setup 返回码时向 CheckFailed 传 nil 而非 fSsl。证书、密钥、cipher、hostname 与 set_fd 检查均使用它;缺少 peer certificate 时直接抛出 EOpenSslNetTls。
修复
mormot.lib.openssl11
03ab5c85+21-20
lib: introducing TOpenSslNetTls.CheckRes
影响
配置与证书失败现在报告真正失败的返回码上下文,不再从活动 SSL 对象推导无关的 SSL_get_error。这是本版 OpenSSL 序列的最终 head。
建议升级
采用该 build,并验证无效/缺失证书、错误私钥、cipher 配置与 hostname 验证会产生可操作错误。
5
高
OpenSSL 重试立即拒绝非 WANT 错误
WaitRetry 改为 TOpenSslNetTls 成员,仅把 SSL_ERROR_WANT_READ/WRITE 映射到对应 socket 事件,其他错误直接抛出 CheckFailed,并保留五秒期限。CheckProc、Receive、Send 传入实际 SSL result。
修复
mormot.lib.openssl11
f3b1fe74+18-16
lib: another fixed to TOpenSslNetTls.Send/Receive
影响
致命 TLS 错误不再被当成通用 socket readiness 等待,相反方向 WANT 转换仍有界。握手/I/O 失败应更快暴露真实 OpenSSL 错误。
建议升级
升级到 build 2.4.17082,并测试 SSL_connect、SSL_accept、Send、Receive 的 WANT_READ、WANT_WRITE、timeout 与终止失败。
6
中
符号写入合并时移除了公开 TDebugFile.AddLog
公开 static class function TDebugFile.AddLog 被移除。原 protected AppendLog 改为内部 instance AddLog,新增 nil/零地址保护,并过滤更多异常拦截 frame。
破坏性变更
mormot.core.log
aa3f2ade+25-28
core: rewritten TDebugFile.AddLog method
影响
调用 TDebugFile.AddLog 的应用代码将无法编译。内部 stack 日志通过缓存的 TDebugFile instance 保持等效 writer 行为。
需要迁移
搜索 TDebugFile.AddLog。单地址改用 FindLocationShort/FindLocation,call stack 改用 StackTrace overload,再将文本追加到 writer。
公开 API
TDebugFile.AddLogremoved — 公开 static writer helper 不再暴露。
7
中
当前调试符号加载变为一次性原子初始化
TDebugFile.CurrentDebugFile 用 DebugFileCurrentSearched.TryLock 取代 nil/sentinel 检查,只解析一次 DebugFileRegister。后续调用只进行对齐的原子 pointer 读取。
修复
mormot.core.log
b619f4a2+9-14
core: atomic TDebugFile.CurrentDebugFile initialization
影响
并发首次调用不再重复竞争当前可执行文件的 debug-file 发现。公开行为仍为返回 TDebugFile,或在无符号时返回 nil。
建议升级
可能在启动或异常突发时并发初始化符号查找的日志密集服务应升级。
8
中
异常拦截切换时跳过正在禁用的 family
SearchHandleException 新增 ignore pointer,TSynLogFamily.SetLevel 选择替代 family 时传入 self。TSynLogThreads.Safe 保持首字段,Count 移到 managed array 前以维持 AArch64 对齐。
修复
mormot.core.log
0043300f+12-7
core: refined exception interception initialization
影响
禁用当前 log family 的异常处理时,可切换到另一启用 family,而不会再次选中正在禁用的 family。AArch64 上 lock 对齐保持不变。
建议升级
使用多个 TSynLogFamily 的应用应测试异常发生时启用/禁用 HandleExceptions。
9
中
KEEP_STACKFRAMES 保留项目 stack-frame 设置
mormot.defines.inc 声明 KEEP_STACKFRAMES,定义后不再强制 {$W-}。mormot.core.log 与 mormot.core.os 的异常拦截和 stack-trace 区段也保留项目设置。
新功能
mormot.defines+3
bab77b73+48-12
core: introducing new KEEP_STACKFRAMES conditional
影响
FPC POSIX build 可在缺少 unwinding 数据时保留 stack frame,从而改进诊断。该选项默认关闭,不适用于 Delphi Win32,并有可测性能成本。
值得一看
仅在确需额外诊断的目标启用 KEEP_STACKFRAMES,并对 hot path 与 frame 质量进行基准测试。
公开 API
KEEP_STACKFRAMESadded — 新增公开编译 conditional,可保留项目的 stack-frame 生成设置。
10
中
FPC Windows 异常保留 RTL 捕获的 call stack
Windows LogExcept handler 在 frame 数低于 63 时读取 FPC 异常参数 2/3,并把 RTL stack pointer 与 count 写入 TSynLogExceptionContext。构建上下文前禁用嵌套拦截,之后恢复。
编译器与平台
mormot.core.os.windows
134e87da+45-33
core: include the stack trace captured by FPC RTL
影响
FPC Windows 异常日志可使用实际 raise 点捕获的 stack,而非稍后重建。该 pointer 仅在异常 handler 内有效,并由本版后续 commit 复制。
建议升级
依赖异常 stack 的 FPC Windows 服务应采用完整序列至 build 2.4.17080,并比较符号化 frame。
11
中
FPC ARM32 确定性 seed 改用稳定的本地 QWord
mormot.core.base 将 TLecuyer.SeedGenerator 的 QWord 参数复制到本地 tmp,再把地址传给 pointer overload。同一 commit 还让 ESChannel 与 ESynLabeledEdit 继承 ExceptionWithProps。
编译器与平台
mormot.core.base+2
039b0ff8+8-5
core: try to fix FPC arm32 TLecuyer.Seed()
影响
FPC ARM32 生成确定性随机序列时不再依赖按值传递的 64-bit 参数地址。现有异常处理代码保持兼容,两种异常类获得继承的 property-aware 行为。
建议升级
FPC ARM32 用户应重新构建,并将 TLecuyer.SeedGenerator 输出与另一受支持目标比较。
公开 API
ESChannelbehaviour-changed — 该公开异常类现在继承 ExceptionWithProps,而非 Exception。ESynLabeledEditbehaviour-changed — 该公开 UI 异常类现在继承 ExceptionWithProps。
12
中
StackTrace overload 统一 frame 捕获与符号路径
TDebugFile.AppendCallerShort 捕获 RawStackTrace 后委托给 AppendLocationsShort。writer StackTrace overload 只解析一次 CurrentDebugFile,TSynLog.AddStackTrace 在所有 compiler 分支统一使用它。
内部重构interp
mormot.core.log
f661c29c+32-126
core: refactored TDebugFile.StackTrace overloaded methods
影响
Delphi 与 FPC 的 stack 格式化使用同一实现,减少过滤差异。应用签名未变,但合并后具体 frame 列表可能不同。
值得一看
若工具会解析符号化 stack 文本,请在升级后比较有代表性的 Delphi/FPC 异常日志。
13
低
Delphi Win32 手动 stack walk 抑制重复地址
ManualStackTrace 在接受候选返回地址前调用 IntegerScanExists,避免重复输出同一地址。上游 subject 明确指出仍有许多 false positive。
修复
mormot.core.log
307fb2df+4-3
core: small Delphi Win32 stack trace cleanup
影响
Delphi Win32 fallback trace 的重复 frame 更少,但调用方仍不应把启发式输出视为完全可靠。
14
低
原始 frame 数组新增有界短符号格式化
TDebugFile.AppendLocationsShort 接受 PPtrUIntArray、frame count 与 depth,跳过相邻重复地址,只追加可由匹配 TDebugFile 解析的符号,直到 ShortString 填满。
新功能
mormot.core.log
7c45e354+26-29
core: new TDebugFile.AppendLocationsShort method
影响
已有捕获 frame 数组的调用方可直接格式化,无需再次捕获当前 stack 或分配 managed string。
公开 API
TDebugFile.AppendLocationsShortadded — 新增用于已捕获地址数组的公开有界 formatter。
15
低
Unix 时间戳新增固定大小 ISO 日期时间格式化
mormot.core.datetime 新增 UnixTimeToShort。它通过 TSynSystemTime.FromUnixTime 转换 TUnixTime,再由 ToIsoDateTimeShort 写入 TShort31;FirstTimeChar 默认为空格。
新功能
mormot.core.datetime
9e8264b4+13-2
core: new UnixTimeToShort() wrapper function
影响
调用方可将 epoch 格式化为紧凑 ISO 日期时间文本,而无需分配 managed string。现有日期 helper 不变。
公开 API
UnixTimeToShortadded — 新增公开 TUnixTime-to-TShort31 formatter,可配置 FirstTimeChar。
16
低
系统信息缓存不再共享全局 OS 锁
mormot.core.os 新增 _SysInfoSafe,用它保护一秒 RetrieveSysInfo cache,而不再使用 OSSafe。POSIX 注释说明该路径为一秒缓存或单次 syscall。
性能
mormot.core.os+2
f8d9a295+9-8
core: tuned RetrieveSysInfo() locking
影响
频繁的系统信息日志不再与 OSSafe 的其他使用者争用。返回值与一秒缓存间隔不变。
17
低
数字 benchmark 在复制前检测 generator 越界
BenchmarkNumbers 记录输出上限,在 MoveFast 前检查 p + length,只计算一次生成 buffer 的 hash,并在后续 parsing 断言失败时输出该 hash。
测试
test.core.base
cd7fa5b7+11-6
tests: completed BenchmarkNumbers tests
影响
生产代码未变。若 TLecuyer 产生异常分布,慢速数值测试现在会安全失败并报告确定性证据。