recoilphp / dev

Development and debugging tools for Recoil applications.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Can't see how to get the trace

langabi opened this issue · comments

I'm trying to use this for a Recoil application I'm debugging. It looks super useful! It's just really hard to see where to start. In particular, the "examples" folder is I think out of date, now that the Autoloader gets automatically loaded.

So from what I can see, I'm getting the instrumentation loaded and run (the Autoloader is being called for each application class that is loaded), but I don't know how to get the instrumented stack trace. I'm still getting the default PHP stack trace on an exception.

Any tips how to use this package? A quickstart in the README would be amazing. Happy to write it once I've worked it out myself!

Apologies for the lack of documentation. I have just run the examples and confirmed that they are still working. You are right about the autoloader being applied automatically, but the example itself doesn't make use of that feature (it probably needs its own composer.json so it can require recoil/dev properly).

One thing that is important but easy to miss is the use Generator as Coroutine alias, and its use as a return type hint. The instrumentor only looks at functions with such type hints so that it can avoid instrumenting "normal" generator functions.

That should be all that is necessary. When an exception is thrown you should then see a meaningful stack trace, rather than the internals of the Recoil kernel. I've included the output of the examples below in case you have any trouble running then, just so you know what to look for:

❯ ./examples/uninstrumented

Fatal error: Uncaught Exception: <FAILURE> in /Users/james/grit/github.com/recoilphp/dev/examples/include.php:44
Stack trace:
#0 /Users/james/grit/github.com/recoilphp/dev/examples/include.php(39): Recoil\Dev\Examples\Fail::fail(106)
#1 [internal function]: Recoil\Dev\Examples\Fail::failer(105)
#2 /Users/james/grit/github.com/recoilphp/dev/vendor/recoil/kernel/src/StrandTrait.php(134): Generator->send(NULL)
#3 /Users/james/grit/github.com/recoilphp/dev/vendor/recoil/kernel/src/StrandTrait.php(391): Recoil\ReferenceKernel\ReferenceStrand->start()
#4 /Users/james/grit/github.com/recoilphp/dev/vendor/recoil/recoil/src/ReferenceApi.php(47): Recoil\ReferenceKernel\ReferenceStrand->send()
#5 /Users/james/grit/github.com/recoilphp/dev/vendor/recoil/recoil/src/EventQueue.php(78): Recoil\ReferenceKernel\ReferenceApi->Recoil\ReferenceKernel\{closure}()
#6 /Users/james/grit/github.com/recoilphp/dev/vendor/recoil/recoil/src/ReferenceKernel.php(92): Recoil\ReferenceKernel\EventQueue->tick()
#7 /Users/james/grit/github.com/recoilphp/de in /Users/james/grit/github.com/recoilphp/dev/vendor/recoil/api/src/Exception/StrandException.php on line 25
❯ ./examples/instrumented

Fatal error: Uncaught Exception: <FAILURE> in /Users/james/grit/github.com/recoilphp/dev/examples/include.php:44
Stack trace:
#0 /Users/james/grit/github.com/recoilphp/dev/examples/include.php(39): Recoil\Dev\Examples\Fail::fail(106)
#1 /Users/james/grit/github.com/recoilphp/dev/examples/include.php(30): Recoil\Dev\Examples\Fail::failer(105)
#2 /Users/james/grit/github.com/recoilphp/dev/examples/include.php(33): Recoil\Dev\Examples\Fail->Recoil\Dev\Examples\{closure}(104)
#3 /Users/james/grit/github.com/recoilphp/dev/examples/include.php(22): Recoil\Dev\Examples\Fail::inner(103)
#4 /Users/james/grit/github.com/recoilphp/dev/examples/include.php(13): Recoil\Dev\Examples\middle(102)
#5 /Users/james/grit/github.com/recoilphp/dev/examples/include.php(16): Recoil\Dev\Examples\{closure}(101)
#6 Unknown(0): Recoil\Dev\Examples\outer(100)
#7 {main}

I hope this helps, please let me know either way!

Thanks! This was SUPER useful. I've now get everything working, ultimately there were two issues:

  • I had missed the critical requirement that coroutines need to be explicitly labelled with "Coroutine" return type hint
  • I use various PHP7.4 syntax elements in some files, which causes problems with the version of nikic/PHP-Parser that is used (v3), which in turn causes the files in question to be silent ignored for instrumentation, on line 189 of StreamWrapper.php.

To solve the second problem, I force installed v4 of nikic/PHP-Parser, and on line vendor/recoil/dev/src/Instrumentation/Instrumentor.php:123, changed $node->type to $node->flags. I can't guarantee that this is the only breaking change with v4, but for me at least, the traces are now working perfectly.

But to summarise: your comment above would be a great addition to the README.md. Along with a version upgrade of nikic/PHP-Parser, and slightly less silent failure on line 189 of StreamWapper.php.

I'm not sure if a pull request would be helpful? I worry there's lots else I don't understand.

Thanks for providing actionable feedback! I'll update the README, and the other changes are simple enough for me to try without a PR.

Thanks, that was fast! Closing ticket.