|
| 1 | +--- |
| 2 | +title: Troubleshooting |
| 3 | +--- |
| 4 | + |
| 5 | +Almost every "the debugger does not work" report is one of three things: it is not |
| 6 | +running, it is running but cannot reach your editor, or it reaches your editor and |
| 7 | +the breakpoints do not match your files. This page walks those in order. |
| 8 | + |
| 9 | +## Start here: is it loaded? |
| 10 | + |
| 11 | +Before anything else, confirm the debugger is present in the PHP that is actually |
| 12 | +running your code: |
| 13 | + |
| 14 | +```bash |
| 15 | +php -v |
| 16 | +``` |
| 17 | + |
| 18 | +You are looking for a line like this among the ones that follow the version: |
| 19 | + |
| 20 | +``` |
| 21 | + with PHP Debugger v0.3.0, Copyright (c) 2002-2026, by Derick Rethans |
| 22 | +``` |
| 23 | + |
| 24 | +If it is not there, nothing else on this page will help until it is. |
| 25 | + |
| 26 | +**Using the interpreter with the debugger built in?** Then that line is always |
| 27 | +present, so its absence means you are running a *different* PHP from the one you |
| 28 | +think. Check with `which php`, and remember that your web server, your container |
| 29 | +and your shell can each have their own. |
| 30 | + |
| 31 | +**Using the extension?** Look above the version output for a loading error. A line |
| 32 | +starting `Failed loading` names the problem directly — a path that does not exist, |
| 33 | +or a build that does not match this PHP. An extension has to be built for the same |
| 34 | +PHP version, and the same thread-safety and debug settings; a mismatch will not |
| 35 | +load. If there is no error at all, the extension is simply not being loaded, so |
| 36 | +check that a `zend_extension=` line for it exists in a file this PHP actually reads |
| 37 | +— `php --ini` lists them. |
| 38 | + |
| 39 | +If none of that gets it loaded, start again from |
| 40 | +[Installation](../getting-started/installation.mdx), which covers each way of |
| 41 | +installing it and what that puts where. |
| 42 | + |
| 43 | +## Then ask the debugger |
| 44 | + |
| 45 | +With it loaded, ask the debugger what it thinks is going on before changing any |
| 46 | +settings. Put this somewhere the request will reach: |
| 47 | + |
| 48 | +```php |
| 49 | +php_debugger_info(); |
| 50 | +``` |
| 51 | + |
| 52 | +It prints a page telling you whether the debugger is loaded, what mode it is in, |
| 53 | +whether a session is active, and — if one is — which client it connected to. |
| 54 | + |
| 55 | +The part worth scrolling to is **Diagnostic Log**. It lists every warning and error |
| 56 | +the debugger raised during this request, with a link explaining each one. A refused |
| 57 | +connection, a rejected trigger value, an unreadable log file: they all show up here |
| 58 | +without you configuring anything first. |
| 59 | + |
| 60 | +If that page does not appear at all, the debugger is not loaded after all, whatever |
| 61 | +`php -v` seemed to say — most likely the request is being served by a different PHP |
| 62 | +from the one you checked. Go back to the section above. |
| 63 | + |
| 64 | +## Nothing happens at all |
| 65 | + |
| 66 | +No connection attempt, no error, nothing in your editor. |
| 67 | + |
| 68 | +**Check the mode.** `php_debugger.mode` has to be `debug`, which is the default. If |
| 69 | +something set it to `off`, the debugger does nothing and says nothing. |
| 70 | + |
| 71 | +**Check nothing else is loaded alongside it.** PHP Debugger takes the place of |
| 72 | +Xdebug and the two cannot both be loaded. A leftover `zend_extension=xdebug.so` |
| 73 | +line is the usual culprit — one of the two loses, and which one is not something to |
| 74 | +rely on. Look for it in every file, not just `php.ini`: distributions scatter |
| 75 | +`conf.d` snippets, and Docker images add their own. |
| 76 | + |
| 77 | +**Check a session is meant to start.** By default every request starts one. If |
| 78 | +`php_debugger.start_with_request` has been set to `trigger`, nothing happens |
| 79 | +without a trigger present; if it is `no`, nothing happens at all. See |
| 80 | +[starting the debugger](./starting-the-debugger.md). |
| 81 | + |
| 82 | +## It tries to connect but nothing arrives |
| 83 | + |
| 84 | +This is the common one, and the log answers it directly. Point it at a file: |
| 85 | + |
| 86 | +```ini |
| 87 | +php_debugger.log=/tmp/php-debugger.log |
| 88 | +``` |
| 89 | + |
| 90 | +Then make a single request and read what it wrote. At the default level there is a |
| 91 | +line for every connection attempt, saying where it tried and whether it worked, and |
| 92 | +that one line usually ends the investigation. |
| 93 | + |
| 94 | +**"Connecting to configured address/port" and then nothing** means the address is |
| 95 | +wrong or nothing is listening. Two things to confirm, in this order: that your |
| 96 | +editor is actually listening — most only listen while you have started a listening |
| 97 | +session, not merely because the editor is open — and that |
| 98 | +`php_debugger.client_host` names a machine your code can reach. Inside a container |
| 99 | +`localhost` is the container itself, which is the single most frequent cause. See |
| 100 | +[connecting to a client](./connecting-to-a-client.md). |
| 101 | + |
| 102 | +**No connection line at all** means the debugger never got as far as trying. Go |
| 103 | +back to the section above — this is a session that never started, not a connection |
| 104 | +that failed. |
| 105 | + |
| 106 | +## It connects but breakpoints do not fire |
| 107 | + |
| 108 | +The session is live, stepping might even work, but your breakpoints are ignored. |
| 109 | + |
| 110 | +**Path mapping is the first suspect.** The debugger reports paths as the machine |
| 111 | +running your code sees them. When that is a container, or another machine, those |
| 112 | +are not the paths your editor knows, and a breakpoint set on |
| 113 | +`/home/you/project/src/Foo.php` means nothing to a debugger running |
| 114 | +`/var/www/src/Foo.php`. Your editor has a path |
| 115 | +mapping setting for exactly this; it needs to know that one directory corresponds |
| 116 | +to the other. Nothing about this is configured in `php.ini`. |
| 117 | + |
| 118 | +**The line may not be executable.** Blank lines, comments, closing braces and `use` |
| 119 | +statements are never reached. Most editors move the marker or mark the breakpoint |
| 120 | +unverified — if yours shows breakpoints as resolved or unresolved, trust that |
| 121 | +signal. |
| 122 | + |
| 123 | +**A condition may never be true.** An expression that cannot be evaluated in that |
| 124 | +scope counts as false and fails silently, so a typo in a condition looks exactly |
| 125 | +like a breakpoint that does not work. Remove the condition and see if it fires. |
| 126 | + |
| 127 | +**The file may not be the one running.** A stale OPcache copy, a deployed build |
| 128 | +rather than your working tree, a vendored duplicate of the class you think you are |
| 129 | +editing. Set a breakpoint on the first line of the file and, if it fires, look at |
| 130 | +the path the debugger reports. |
| 131 | + |
| 132 | +## It works, but everything is slow |
| 133 | + |
| 134 | +**Look for breakpoints you have forgotten.** Every one is checked on every request, |
| 135 | +and a list built up over an afternoon is not free. Delete rather than disable. |
| 136 | + |
| 137 | +**Check `php_debugger.on_demand_debugging_enabled`.** If it is on, every request is |
| 138 | +compiled with debugging instrumentation whether or not it is debugged, which costs |
| 139 | +roughly half the benefit of using this debugger at all. Turn it off unless you |
| 140 | +genuinely need to attach mid-request. |
| 141 | + |
| 142 | +## Still stuck |
| 143 | + |
| 144 | +Raise `php_debugger.log_level` to `10` and make one request. That level records the |
| 145 | +decisions leading up to a session — each trigger it checked for, each configuration |
| 146 | +value it resolved — so it answers "why did it not even try" rather than "why did |
| 147 | +the attempt fail". |
| 148 | + |
| 149 | +If you are certain the debugger and your editor are talking but disagreeing, level |
| 150 | +`5` logs every protocol message in both directions. It is verbose and it is the |
| 151 | +right tool for exactly one question: what was actually sent. |
| 152 | + |
| 153 | +Both are described on the [logging](./logging.md) page. A log from level `10`, with |
| 154 | +the request you made and what you expected, is also the most useful thing you can |
| 155 | +attach to a bug report. |
0 commit comments