mORMot2 DailyDaily read of upstream commits

Exception history is rebuilt while OpenSSL gets another I/O correction

The exception-interception path is substantially rebuilt after upstream identified a random GPF and unsafe memory/threading model in the previous last-exception storage. The sequence finishes with corrected newest-first retrieval and bounded per-exception stack storage. OpenSSL Send/Receive retry handling and setup-error reporting receive two final follow-ups, while FPC gains better stack capture and an ARM32 deterministic-seed repair.

TL;DR

  • Land on build 2.4.17082 at 03ab5c85c4b2982c96b7f38d683dbff85e016f77.
  • GetLastException and GetLastExceptions now use a locked 16-entry ring with a private stack copy for every exception.
  • OpenSSL retries only WANT_READ/WANT_WRITE, applies a five-second bound and reports setup failures without misusing SSL_get_error.
  • The public class method TDebugFile.AddLog is removed; external callers must migrate to the remaining location or StackTrace APIs.
  • KEEP_STACKFRAMES can preserve project stack-frame settings, mainly for FPC POSIX debugging, at a documented performance cost.
  • FPC Windows consumes the RTL-captured exception stack, and FPC ARM32 gets stable QWord storage for TLecuyer.SeedGenerator.

Upgrade advice

Land on build 2.4.17082. Upgrade promptly if production uses exception interception, GetLastException/GetLastExceptions or asynchronous OpenSSL sockets; test concurrent exception bursts, newest-first Depth limits, certificate/setup failures and opposite-direction WANT transitions. Grep for TDebugFile.AddLog because the public class method was removed. Enable KEEP_STACKFRAMES only where FPC POSIX diagnostics justify its documented performance cost. The raw payload has no superseded_by markers, so no avoid window is asserted.

Build2.4.17065 → 2.4.17082
Commits17
Lines+498 -536
Read5 min

17 of 17 entries · 17 commits upstream

Stories
# Entry Category Units
1 High Last-exception storage is rebuilt to remove a random GPF and unsafe sharing mormot.core.log replaces the old shared stack and index with a TLightLock-protected 16-slot ring. Each TSynLogExceptionInfo owns up to 16 filtered addresses, clears EInstance/EStack references and copies Message while the exception is still valid. Fixes mormot.core.log 8298b7c1+143-124

core: rewritten last exception in-memory storage

Impact

Concurrent exception interception no longer exposes one exception’s stack through shared mutable storage or retains an invalid exception instance. Upstream identifies the previous design as causing a random GPF and unsafe memory/threading behavior.

Public API

  • TSynLogStackTraceadded — A public fixed array stores up to MAX_STACK_TRACE filtered addresses per exception.
  • TSynLogExceptionInfo.StackTraceadded — Each returned exception record now owns its copied stack addresses.
  • PSynLogExceptionInfoadded — A public pointer alias for TSynLogExceptionInfo is introduced.

Arnaud Bouchez · 17:23 UTC · view the commit on GitHub →

2 High Disk exception logs reuse the safely copied history stack SynLogException now writes the precomputed filtered frames produced before the history-ring copy instead of resolving a second stack inside the file-writer path. The nested writer try/except is simplified while the writer lock remains protected by finally. Fixes mormot.core.log ff2fda39+46-67

core: rewritten exception logging code

Impact

The in-memory history and disk line describe the same call stack, and symbol lookup no longer runs twice in the unstable exception context. Upstream states this avoids most symbol-resolution instability.

Arnaud Bouchez · 17:24 UTC · view the commit on GitHub →

3 High Latest-exception retrieval returns the correct slot and newest-first depth GetLastException reads Infos[Next - 1], wrapping zero to the array length. GetLastExceptions now walks backward from Next, stops at empty entries, applies Depth to the newest records and returns them latest-first. Fixes mormot.core.log efe676a8+28-36

core: GetLastException/GetLastExceptions fixes

Impact

Consumers no longer receive the next unwritten slot as the latest exception, and Depth no longer selects or orders the wrong side of the ring. Delphi Win32 manual fallback is also limited explicitly to WIN32DELPHI.

Arnaud Bouchez · 18:18 UTC · view the commit on GitHub →

4 High OpenSSL setup failures no longer ask the I/O error API for context The former TOpenSslNetTls.Check is renamed CheckRes and passes nil instead of fSsl to CheckFailed for context/setup return codes. Certificate, key, cipher, hostname and set_fd checks use it, while a missing peer certificate raises a direct EOpenSslNetTls message. Fixes mormot.lib.openssl11 03ab5c85+21-20

lib: introducing TOpenSslNetTls.CheckRes

Impact

Configuration and certificate failures report the return-code context that actually failed instead of deriving an unrelated SSL_get_error from the live SSL object. This is the final head of the edition’s OpenSSL sequence.

Arnaud Bouchez · 19:48 UTC · view the commit on GitHub →

5 High OpenSSL retries reject non-WANT errors immediately WaitRetry becomes a TOpenSslNetTls member, maps only SSL_ERROR_WANT_READ and SSL_ERROR_WANT_WRITE to matching socket events, raises CheckFailed for every other error and keeps the five-second deadline. CheckProc, Receive and Send pass the actual SSL result into it. Fixes mormot.lib.openssl11 f3b1fe74+18-16

lib: another fixed to TOpenSslNetTls.Send/Receive

Impact

Fatal TLS errors are no longer treated as generic socket readiness waits, and asynchronous opposite-direction WANT transitions remain bounded. Failed handshakes and I/O should surface their real OpenSSL error sooner.

Arnaud Bouchez · 19:33 UTC · view the commit on GitHub →

6 Medium Public TDebugFile.AddLog is removed during symbol-writer consolidation The public static class function TDebugFile.AddLog is removed. The former protected AppendLog becomes an instance AddLog used internally, gains nil/no-address guards and filters more exception-interception frames. Breaking changes mormot.core.log aa3f2ade+25-28

core: rewritten TDebugFile.AddLog method

Impact

Application code that called TDebugFile.AddLog no longer compiles. Internal stack logging keeps equivalent writer behavior through the cached TDebugFile instance.

Migration required

Grep for TDebugFile.AddLog. Use FindLocationShort or FindLocation for one address, or a StackTrace overload for a captured call stack, then append that text to your writer.

Public API

  • TDebugFile.AddLogremoved — The public static writer helper is no longer exposed.

Arnaud Bouchez · 17:20 UTC · view the commit on GitHub →

7 Medium Current debug-symbol loading becomes a one-time atomic initialization TDebugFile.CurrentDebugFile replaces a nil/sentinel check with DebugFileCurrentSearched.TryLock and resolves DebugFileRegister only once. The cached pointer remains an aligned atomic read for all later callers. Fixes mormot.core.log b619f4a2+9-14

core: atomic TDebugFile.CurrentDebugFile initialization

Impact

Concurrent first use no longer races through repeated current-executable debug-file discovery. Public behavior remains a TDebugFile instance or nil when symbols are unavailable.

Arnaud Bouchez · 17:13 UTC · view the commit on GitHub →

8 Medium Exception interception switches away from the family being disabled SearchHandleException receives an ignore pointer, and TSynLogFamily.SetLevel passes self when selecting a replacement family. TSynLogThreads.Safe is kept first while Count moves before managed arrays to preserve AArch64 alignment. Fixes mormot.core.log 0043300f+12-7

core: refined exception interception initialization

Impact

Disabling exception handling on the active log family can hand interception to another enabled family instead of selecting the one being disabled again. The record layout keeps its lock alignment on AArch64.

Arnaud Bouchez · 17:24 UTC · view the commit on GitHub →

9 Medium KEEP_STACKFRAMES preserves project stack-frame settings for diagnostics mormot.defines.inc declares KEEP_STACKFRAMES and stops forcing {$W-} when it is set. Exception interception and stack-trace sections in mormot.core.log and mormot.core.os also preserve the project setting instead of toggling frames locally. New features mormot.defines+3 bab77b73+48-12

core: introducing new KEEP_STACKFRAMES conditional

Impact

FPC POSIX builds can retain stack frames where unwinding data is unavailable, improving diagnostics. It is disabled by default, documented as unsuitable for Delphi Win32 and has a measurable performance cost.

Worth a look

Enable KEEP_STACKFRAMES only for targets that need the extra diagnostics, then benchmark hot paths and verify frame quality.

Public API

  • KEEP_STACKFRAMESadded — A public compile-time conditional can keep the project’s stack-frame generation setting.

Arnaud Bouchez · 17:08 UTC · view the commit on GitHub →

10 Medium FPC Windows exceptions retain the RTL-captured call stack The Windows LogExcept handler reads FPC exception parameters 2 and 3 when the captured frame count is below 63, placing the RTL stack pointer and count in TSynLogExceptionContext. Nested interception is disabled before context construction and restored afterward. Compiler & platform mormot.core.os.windows 134e87da+45-33

core: include the stack trace captured by FPC RTL

Impact

FPC Windows exception logs can use the stack captured at the actual raise site instead of reconstructing it later. The pointer remains valid only inside the exception handler and is copied by later commits in this edition.

Arnaud Bouchez · 17:09 UTC · view the commit on GitHub →

11 Medium FPC ARM32 deterministic seeding uses stable local QWord storage mormot.core.base copies the QWord argument of TLecuyer.SeedGenerator into a local tmp before passing its address to the pointer overload. The same commit changes ESChannel and ESynLabeledEdit to inherit from ExceptionWithProps. Compiler & platform mormot.core.base+2 039b0ff8+8-5

core: try to fix FPC arm32 TLecuyer.Seed()

Impact

FPC ARM32 no longer depends on the addressability of a by-value 64-bit parameter when producing deterministic random sequences. Existing exception handlers remain source-compatible, while the two exception classes gain the inherited property-aware behavior.

Public API

  • ESChannelbehaviour-changed — The public exception class now descends from ExceptionWithProps instead of Exception.
  • ESynLabeledEditbehaviour-changed — The public UI exception class now descends from ExceptionWithProps.

Arnaud Bouchez · 06:48 UTC · view the commit on GitHub →

12 Medium StackTrace overloads share one frame-capture and symbol path TDebugFile.AppendCallerShort now captures RawStackTrace and delegates to AppendLocationsShort. The writer StackTrace overload resolves CurrentDebugFile once, and TSynLog.AddStackTrace uses that overload for all compiler branches instead of separate Delphi/FPC implementations. Under the hoodinterp mormot.core.log f661c29c+32-126

core: refactored TDebugFile.StackTrace overloaded methods

Impact

Stack formatting follows one implementation across Delphi and FPC, reducing divergent filtering behavior. Application signatures are unchanged, but exact frame lists may differ after the consolidation.

Worth a look

If tooling parses symbolized stack text, compare representative Delphi and FPC exception logs after upgrading.

Arnaud Bouchez · 17:24 UTC · view the commit on GitHub →

13 Low Delphi Win32 manual stack walk suppresses duplicate addresses ManualStackTrace now calls IntegerScanExists before accepting a candidate return address, so the same address is not emitted more than once. The upstream subject explicitly notes that false positives still remain. Fixes mormot.core.log 307fb2df+4-3

core: small Delphi Win32 stack trace cleanup

Impact

Delphi Win32 fallback traces contain fewer duplicate frames, but callers should not treat the heuristic output as fully reliable.

Arnaud Bouchez · 17:21 UTC · view the commit on GitHub →

14 Low Raw frame arrays gain a bounded short-symbol formatter TDebugFile.AppendLocationsShort accepts a PPtrUIntArray, frame count and depth, skips adjacent duplicate addresses and appends only symbols resolved by a matching TDebugFile until the ShortString is full. New features mormot.core.log 7c45e354+26-29

core: new TDebugFile.AppendLocationsShort method

Impact

Callers with an already captured frame array can format it without recapturing the current stack or allocating a managed string.

Public API

  • TDebugFile.AppendLocationsShortadded — A public bounded formatter for captured address arrays is available.

Arnaud Bouchez · 17:20 UTC · view the commit on GitHub →

15 Low Unix timestamps gain a fixed-size ISO date-time formatter mormot.core.datetime adds UnixTimeToShort. It converts TUnixTime through TSynSystemTime.FromUnixTime and writes a TShort31 with ToIsoDateTimeShort; FirstTimeChar defaults to a space. New features mormot.core.datetime 9e8264b4+13-2

core: new UnixTimeToShort() wrapper function

Impact

Callers can format an epoch timestamp as compact ISO date-time text without allocating a managed string. Existing date helpers are unchanged.

Public API

  • UnixTimeToShortadded — A public TUnixTime-to-TShort31 formatter with configurable FirstTimeChar is available.

Arnaud Bouchez · 17:06 UTC · view the commit on GitHub →

16 Low System-information caching stops sharing the global OS lock mormot.core.os adds _SysInfoSafe and uses it around the one-second RetrieveSysInfo cache instead of OSSafe. The POSIX comment now states that the path is a one-second cache or a single syscall. Performance mormot.core.os+2 f8d9a295+9-8

core: tuned RetrieveSysInfo() locking

Impact

Frequent system-info logging no longer contends with unrelated users of OSSafe. Return values and the one-second cache interval are unchanged.

Arnaud Bouchez · 06:49 UTC · view the commit on GitHub →

17 Low Number benchmark detects generator overruns before copying BenchmarkNumbers records the output limit, checks p + length before MoveFast, hashes the generated buffer once and includes that hash when later parsing assertions fail. Tests test.core.base cd7fa5b7+11-6

tests: completed BenchmarkNumbers tests

Impact

Production code is unchanged. The slow numerical test now fails safely and reports deterministic evidence if TLecuyer produces an unexpected distribution.

Arnaud Bouchez · 06:50 UTC · view the commit on GitHub →

Upstream activity commits per day · last 60 days
Commits977
Active days44/60
Busiest2026-09-30
Peak60
2026-08-15: 0 commits2026-08-16: 0 commits2026-08-17: 0 commits2026-08-18: 0 commits2026-08-19: 0 commits2026-08-20: 0 commits2026-08-21: 0 commits2026-08-22: 0 commits2026-08-23: 0 commits2026-08-24: 0 commits2026-08-25: 0 commits2026-08-26: 0 commits2026-08-27: 26 commits2026-08-28: 11 commits2026-08-29: 10 commits2026-08-30: 1 commit2026-08-31: 23 commits2026-09-01: 0 commits2026-09-02: 20 commits2026-09-03: 29 commits2026-09-04: 35 commits2026-09-05: 13 commits2026-09-06: 0 commits2026-09-07: 0 commits2026-09-08: 23 commits2026-09-09: 10 commits2026-09-10: 17 commits2026-09-11: 23 commits2026-09-12: 14 commits2026-09-13: 9 commits2026-09-14: 7 commits2026-09-15: 4 commits2026-09-16: 24 commits2026-09-17: 26 commits2026-09-18: 21 commits2026-09-19: 59 commits2026-09-20: 13 commits2026-09-21: 5 commits2026-09-22: 34 commits2026-09-23: 17 commits2026-09-24: 57 commits2026-09-25: 22 commits2026-09-26: 26 commits2026-09-27: 0 commits2026-09-28: 2 commits2026-09-29: 19 commits2026-09-30: 60 commits2026-10-01: 26 commits2026-10-02: 30 commits2026-10-03: 32 commits2026-10-04: 15 commits2026-10-05: 1 commit2026-10-06: 26 commits2026-10-07: 37 commits2026-10-08: 27 commits2026-10-09: 35 commits2026-10-10: 33 commits2026-10-11: 9 commits2026-10-12: 11 commits2026-10-13: 35 commits
2026-08-152026-10-13