Skip to content

Fix manual Throwable getTrace() empty on construct (#9905) - #10297

Merged
PurHur merged 1 commit into
masterfrom
agent/issue-9905-throwable-manual-construct-trace
Jun 20, 2026
Merged

PurHur merged 1 commit into
masterfrom
agent/issue-9905-throwable-manual-construct-trace

Conversation

@PurHur

@PurHur PurHur commented Jun 20, 2026

Copy link
Copy Markdown
Owner

Summary

  • Snapshot caller stack in Throwable::__construct as manualConstructTrace so getTrace() returns array(1) when an exception is constructed inside a user function without being thrown (Zend zend_exceptions.c parity).
  • captureOnThrow clears the manual snapshot and still fills trace on throw; rethrow with existing trace unchanged.
  • ExceptionGetTrace resolves manual snapshot when trace property is still empty.

Closes #9905

php-src reference

  • Zend/zend_exceptions.c — trace capture on manual construct vs throw

PHP implementation

  • lib/VM/ExceptionTrace.php — captureOnManualConstruct, resolveTraceVariable
  • lib/VM/ExceptionSupport.php — hook construct paths
  • lib/VM/Builtin/ExceptionGetTrace.php — resolve snapshot
  • lib/VM/ObjectEntry.php — manualConstructTrace field

Verification

./script/docker-exec.sh -- bash -lc '
php test/repro-maintainer/throwable_trace_matrix.php
php bin/vm.php test/repro-maintainer/throwable_trace_matrix.php
php vendor/bin/phpunit test/compliance/VMTest.php --filter "throwable_manual_construct_trace|throwable_get_trace"
'

Output (VM after fix):

Exception::getTrace array(1)
Error::getTrace array(1)
TypeError::getTrace array(1)
OK (2 tests, 2 assertions)

Made with Cursor

Snapshot the constructing call frame when Throwable::__construct runs so
getTrace() returns array(1) inside user functions like Zend; throw still
overwrites via captureOnThrow and clears the manual snapshot on rethrow.

Co-authored-by: Cursor <cursoragent@cursor.com>
@PurHur
PurHur merged commit ffee743 into master Jun 20, 2026
@PurHur
PurHur deleted the agent/issue-9905-throwable-manual-construct-trace branch June 20, 2026 03:50
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.

Regression: Throwable::getTrace() empty on manual construct — re-#7159 (zend_exceptions.c)

1 participant