Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Break on property change in Xdebug

Tags:

php

xdebug

I'm trying to find out where a certain property of a certain object gets modified. Due to PHP's highly dynamic nature ($o->$prop = $val and such) this is practically impossible to do by simple code analysis. Is there a way to start a debugging session and break at the line where the property gets modified? (Adding a magic __set with a conditional xdebug_break() call to the class might help in simple cases, but if the class or one of its ancestors already has a magic setter, it can get very complicated, so that's not a good solution either.)

like image 360
Tgr Avatar asked Feb 15 '13 18:02

Tgr


2 Answers

According to the xdebug documentation, it seems like there should be a way to break on a variable change. http://xdebug.org/docs-dbgp.php#breakpoints

watch: break on write of the variable or address defined by the expression argument

But the source code indicates that the documentation is ahead of its actual functionality: https://github.com/xdebug/xdebug/blob/master/xdebug_handler_dbgp.c#L875

if (strcmp(CMD_OPTION('t'), "watch") == 0) {
        RETURN_RESULT(XG(status), XG(reason), XDEBUG_ERROR_BREAKPOINT_TYPE_NOT_SUPPORTED);
    }

I wasn't actually able to find the string 'watch' anywhere else in the repo, so my assumption is that it's currently unsupported.

There appears to be the bug in Xdebug's bug tracker:

http://bugs.xdebug.org/view.php?id=514

like image 144
Mixologic Avatar answered Sep 30 '22 00:09

Mixologic


Declare the property that you are trying to debug as private, and create a __set method. Inside of that, you'll be able to find your answer.

class subject extends something {
    private $field;

    public function __set($key, $value) {
        if ($key == 'field') {
            debug_print_backtrace(); exit;
        }

        if (method_exists(get_parent_class($this), '__set')) {
            return parent::__set($key, $value);
        }

        return $this->$key = $value;
    }
}

Edit: this is another phenomenal reason for getters and setters :)

like image 31
Colin M Avatar answered Sep 29 '22 23:09

Colin M