Skip to content

Limit BlueScreen agent argument dumps - #618

Open
janlanger wants to merge 19 commits into
nette:masterfrom
slevomat:fix-agent-dump-limits
Open

Limit BlueScreen agent argument dumps#618
janlanger wants to merge 19 commits into
nette:masterfrom
slevomat:fix-agent-dump-limits

Conversation

@janlanger

Copy link
Copy Markdown
  • bug fix / new feature? bug fix
  • BC break? no
  • doc PR: no

BlueScreen agent output currently dumps stack trace arguments without applying the same item and string limits that the HTML dump uses. In practice this can produce extremely large .md exception logs when a stack frame contains a large root array or object graph.

A real case was a hydration frame with a large result. The MD file grew to ~100 MB because the agent dump expanded the whole argument list.

This change fixes that in two parts:

  • BlueScreen::getAgentDumper() now respects maxLength and maxItems
  • stack trace arguments in agent.phtml are dumped with their argument name as the dumper key, so the existing Dumper::ITEMS limiting also applies to large root values

@dg
dg force-pushed the master branch 2 times, most recently from 1731e8d to efbf873 Compare July 18, 2026 02:16
@jkuchar

jkuchar commented Jul 31, 2026

Copy link
Copy Markdown

Independent confirmation of this, from production: we hit the same defect and filed #620 before finding this PR — closing that one as a duplicate. Two things from our side that may help move this along, because the impact is worse than a large .md.

It is a fatal, not just a big file. One stack frame holding a list of domain objects exhausted a 128 MB PHP-FPM worker inside Dumper/Describer.php. The worker dies, and the unrelated request it happened to be serving dies with it. Measured on Tracy 2.12.0 / PHP 8.5.7, N small objects in a single trace argument, peak memory the render allocates:

N render() (HTML) renderAgent() (.md)
5 000 27.37 MB total render, .md 681 kB
20 000 +2.01 MB, 148 kB output +106.97 MB, 2.79 MB output
50 000 +3.89 MB, 148 kB output +266.81 MB

With memory_limit=128M the process dies from ~22 000 objects. Turning BlueScreen::$maxDepth/$maxLength/$maxItems to the floor changes nothing, for exactly the reason this PR fixes: those values never reach the agent dumper.

Debugger::$reservedMemorySize does not save it, and enlarging it makes things worse. The reserve is released in shutdownHandler()/exceptionHandler(), so a bluescreen rendered from application code — ours goes through a Monolog handler bridging into Tracy\Logger during an ordinary request — never gets it. And since it is a plain string held for the whole request, raising it just lowers the threshold:

reserve N=5 000 N=12 000 N=20 000
500 kB (default) ok ok ok
8 MB ok ok fatal
64 MB ok fatal fatal

One residual this PR does not cover, in case it is worth a second commit: BlueScreen::findGeneratorsAndFibers()Helpers::traverseValue() walks everything reachable from the exception with no depth or item limit at all, and runs before either template. With the markdown copy taken out of the picture entirely, our reproducer still dies at ~210 000 objects, inside Helpers.php. Much further out than the case this PR fixes, but structurally the same shape.

Happy to test a build of this against the original reproducer if that helps.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants