Skip to main content
The trace command shows the current call stack, revealing how execution reached the current point in your code. Unlike wtf, which shows exception backtraces, trace shows the stack trace from the current execution context.

Syntax

trace [options]

Options

--include-psy
flag
Alias: -pInclude PsySH internal frames in the call stack. By default, PsySH’s own function calls are hidden for clarity.
--num
integer
Alias: -nLimit output to the specified number of stack frames
--grep
pattern
Filter stack frames by pattern (supports regular expressions)
--insensitive
flag
Alias: -iMake grep search case-insensitive
--invert
flag
Alias: -vInvert grep match (show frames that don’t match)

Usage Examples

Basic Stack Trace

>>> function level3() {
...     trace
... }
>>> function level2() {
...     level3()
... }
>>> function level1() {
...     level2()
... }
>>> level1()
 0: level3()
    at eval():2
 1: level2()
    at eval():5
 2: level1()
    at eval():8
 3: eval()
The trace shows the call stack from innermost (current) to outermost (entry point).

Limit Number of Frames

>>> trace -n 5
>>> trace --num 10
Shows only the first 5 or 10 frames.
>>> trace -n 3
 0: currentFunction()
 1: caller()
 2: topLevelCaller()

Include PsySH Internals

By default, PsySH filters out its own internal calls:
>>> trace
 0: myFunction()
 1: eval()
With --include-psy, you see the complete stack:
>>> trace --include-psy
>>> trace -p
 0: myFunction()
    at eval():1
 1: eval()
 2: Psy\Shell->execute()
    at /vendor/psy/psysh/src/Shell.php:542  
 3: Psy\ExecutionLoop\Loop->run()
    at /vendor/psy/psysh/src/ExecutionLoop/Loop.php:87
 4: Psy\Shell->run()
    at /vendor/psy/psysh/src/Shell.php:345
 ... (many more PsySH internal frames)
Including PsySH internals can be useful for debugging PsySH itself or understanding its execution flow.

Filter Stack Frames

>>> trace --grep /MyApp/
>>> trace --grep /Controller/  
Shows only frames matching the pattern.
>>> trace --grep /App\\/
 2: App\UserController->store()
 5: App\Services\UserService->create()
 8: App\Repositories\UserRepository->save()

Case-Insensitive Filter

>>> trace --grep /database/ -i
>>> trace --grep /controller/ --insensitive

Invert Filter

>>> trace --grep /Psy/ --invert
Shows all frames except those containing “Psy”.

Understanding the Output

Each stack frame shows:
  N: ClassName->methodName($arg1, $arg2)
     at /path/to/file.php:123
  • N - Frame number (0 is current, increasing numbers go up the stack)
  • ClassName->methodName - The method or function being called
  • at /path/to/file.php:123 - Where the call was made from

Frame Types

// Instance method call
 0: MyClass->instanceMethod()

// Static method call  
 1: MyClass::staticMethod()

// Function call
 2: someFunction()

// Closure/anonymous function
 3: {closure}()

// Eval'd code
 4: eval()

Practical Use Cases

Debug Deep Call Chains

>>> trace
See how you ended up at the current point:
 0: App\Services\OrderProcessor->process()
 1: App\Http\Controllers\OrderController->store()
 2: Illuminate\Routing\Controller->callAction()
 3: Illuminate\Routing\ControllerDispatcher->dispatch()
 ...

Find Who Called a Function

function debugMe() {
    trace
    // ... rest of function
}
When debugMe() is called, you’ll see the complete call path.

Verify Execution Path

>>> trace --grep /Controller/
Confirm which controllers are in the call stack.

Limit Deep Stacks

>>> trace -n 10
When dealing with very deep recursion or long call chains, limit output to the most relevant frames.

Comparison with wtf

Featuretracewtf
PurposeCurrent call stackException backtrace
When to useDebug execution flowDebug errors
ShowsHow you got hereWhat went wrong
ContextAny timeAfter an exception
>>> function foo() { trace; }
>>> foo()
 0: foo()
 1: eval()

Debugging Patterns

Trace from Specific Point

class UserService {
    public function create($data) {
        trace  // Insert trace to see call stack
        // ... rest of method
    }
}

Compare Execution Paths

>>> firstPath()
>>> trace --num 5

>>> secondPath()
>>> trace --num 5
Compare which functions are called in different scenarios.

Filter Application Code

>>> trace --grep /^App\\/ -n 10
Show only your application’s stack frames, ignoring framework code.

Tips

Use trace to understand recursion:
function factorial($n) {
    if ($n === 1) trace;
    return $n === 1 ? 1 : $n * factorial($n - 1);
}

>>> factorial(5)
 0: factorial(1)
 1: factorial(2)  
 2: factorial(3)
 3: factorial(4)
 4: factorial(5)
Combine with grep to focus on specific classes:
>>> trace --grep /Service/ -n 10
Shows service layer calls only.
Compare with and without PsySH internals:
>>> trace -n 5          # Clean view
>>> trace -p -n 20      # See PsySH machinery  
Very deep recursion may produce overwhelming output:
>>> trace               # Could be hundreds of frames!
>>> trace -n 10         # Better - just the recent calls

Advanced Usage

Regular Expression Filtering

>>> trace --grep "/Controller|Service/"
Shows frames containing either “Controller” or “Service”.
>>> trace --grep "/^(?!Illuminate)/"
Shows frames NOT starting with “Illuminate” (excludes Laravel framework).

Focused Debugging

>>> trace --grep /Repository/ -n 3
Find the 3 most recent repository calls.

See Also

  • wtf - View exception backtraces
  • whereami - Show current code location
  • show —ex - View exception code context

Build docs developers (and LLMs) love