Skip to content

Anonymous-object formatting shares its recursion limit across threads #223

Closed

Description

@dimensionscape

Formatting an anonymous object in one thread can replace an unrelated thread's output with "...". The recursion limit is shared by the entire process instead of tracking recursion within each formatting call chain.

Regression coverage first: test/regression/AnonConcurrentString in the existing Main.hx/build.hxml/stdout.txt layout. A worker formats a five-level anonymous object whose leaf toString signals a lock and waits. Once the worker reaches that leaf, the main thread formats a separate {x: 1} object and compares it with the same object's output before the worker started. Release the worker and wait for completion. All waits have deadlines.

Confirmed on Linux x86_64 with Haxe 4.3.3:

other thread preserves anon string: false

The unrelated small object formats as "..." while the worker is paused inside the nested formatting call. This reproduction deliberately coordinates the threads, so it does not require a probabilistic stress run.

src/hx/Anon.cpp declares a process-global static int _hx_toString_depth. Anon_obj::toString increments and decrements it around recursive formatting, returning "..." at depth 5. Each thread therefore consumes the same recursion budget. Uncoordinated simultaneous formatting also reads and modifies this plain integer without synchronization, which is an additional source-level race.

Keep recursion tracking local to the formatting thread or context, with exception-safe restoration. Preserve the existing bound for recursive values within one thread, and add a throwing custom toString case to check restoration.

This affects ordinary anonymous objects used in logs, diagnostics and data structures. It is separate from user objects deliberately returning "..." in their own toString. No runtime implementation changes are included.

Activity

  1. added a commit that references this issue on Oct 20, 2026
    b262bc9
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions