Skip to content

The current frame doesn't appear in stack traces in PHP 7 #115

Open
@joshuabenuck

Description

@joshuabenuck

Description

PHP 7's zend_fetch_debug_backtrace() implementation differs in practice from PHP 5 by not including the current execution data as the first frame in the stack trace when the executor is in a user function.

This results in the user not getting a stack trace when an error occurs in the global scope:

<?php

$a = '';
echo $a['foo'];

The error is reported, but with a completely empty stack trace. Similarly, errors deep in large functions will be hard to trace because the current line number isn't included.

Steps to Reproduce

Create a file named new_relic_test.php with the following contents.

<?php
    require('LearnNewrelicTest.class.php');
    $learn = new LearnNewrelicTest();
    $learn->addMultipleCourse();
    ?>

Create a second file named LearnNewrelicTest.class.php with the following contents

<?php

    class LearnNewrelicTest {
        public function getCRMUserList() {
            $items = null;
            foreach($items as $item){
            }
        }
        public function addMultipleCourse() {
          $this->getCRMUserList();
        }
    }

Run the first php file using a a PHP 7.2 command line

$ php --version
    PHP 7.2.13 (cli) (built: Dec  7 2018 10:43:44) ( NTS )
    Copyright (c) 1997-2018 The PHP Group
    Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
        with Zend OPcache v7.2.13, Copyright (c) 1999-2018, by Zend Technologies
    $ php new_relic_test.php 

    Warning: Invalid argument supplied for foreach() in 
    /path/to/LearnNewrelicTest.class.php on line 6

Observe the contents of JSON posted to the error_event_data endpoint – specifically the key named stack_trace

Expected:

{"stack_trace":
      [
        " in LearnNewrelicTest::getCRMUserList called at \/path\/to\/LearnNewrelicTest.class.php (6)",      
        " in LearnNewrelicTest::getCRMUserList called at \/path\/to\/LearnNewrelicTest.class.php (10)",
        " in LearnNewrelicTest::addMultipleCourse called at \/path\/to\/new_relic_test.php (4)"
      ]
    }

Actual:

{"stack_trace":
      [   
        " in LearnNewrelicTest::getCRMUserList called at \/path\/to\/LearnNewrelicTest.class.php (10)",
        " in LearnNewrelicTest::addMultipleCourse called at \/path\/to\/new_relic_test.php (4)"
      ]
    }

i.e. the stack trace is missing the frame that actually points to the error the line is on.

Metadata

Metadata

Assignees

No one assigned

    Labels

    CHCommunity HerobugSomething isn't workinghelp wantedExtra attention is wanted. We would love community assistance!

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions