Mapping C++ trace to PHP code
You get C++ trace when:
debug_backtrace()
is called from any place of your code (its return value differs from PHP)- a runtime warning is triggered (its trace is output to error logs)
Using this trace and unstripped binary, you can match it with PHP trace quite precisely.
Step 1: use addr2line to get C++ location
C++ trace looks like this:
0x5bb974
0x4ad80d
0x4ad094
...
You can use each of these addresses as an argument to addr2line
Linux utility:
$ addr2line -e /path/to/unstripped/kphp/server/binary 0x5bb974
/var/build/kphp/o_76/demoService.cpp:342
Having C++ location and codegenerated sources, locate an exact PHP line.
Step 2: use C++ location to get PHP line
While codegenerating C++ sources, KPHP inserts PHP code as comments to C++ sources:
//11: function run() {
void f$SomeClass$$run(class_instance<C$SomeClass> const &v$this) {
array < mixed > v$arg;
//12: $arg = $this->a;
v$arg = v$this->a;
//13: if (!is_array($arg)) {
if (!f$is_array(v$arg)) {
//14: $arg = [$arg];
SAFE_SET_OP (v$arg, =, array < array < mixed > >::create(v$arg), array < array < mixed > >);
//15: }
};
/* ... */
}
Thus, having a C++ line, you step upper until //\d+: comment is met, and it's the corresponding PHP line.
How to organize error monitoring in a KPHP project
When there are many servers with KPHP instances, it's a bit complicated to collect errors from all servers.
This documentation describes a possible approach, though it’s not the only way.
- Store unstripped binaries in a single place, use only stripped binaries for production
- Use JSON logs: it's more handy than stderr
- Optionally, call
kphp_set_context_on_error()
from PHP code to provide more info to JSON logs - On each KPHP server, organize a daemon, which pushes new errors from JSON files to single storage (Clickhouse / MySQL / etc.)
- On the server, where an unstripped binary is stored, organize a daemon, that checks for new errors in this storage, decrypts cached traces with addr2line (better also launched daemonized), and pushes fulfilled errors to Sentry or some other place
- Use Sentry or some other UI to view aggregated errors, filter them, assign, etc.
- Organize versioning in a way to easier filter out newly occurring errors with your UI
- Don't forget to collect logs from master processes' stderr (not related to PHP code)
- Use the same UI to aggregate PHP errors / JS errors / etc.