Skip to content

Instantly share code, notes, and snippets.

@nikic
Created July 3, 2020 14:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nikic/af1bce18e2d9d57407212af70f80b712 to your computer and use it in GitHub Desktop.
Save nikic/af1bce18e2d9d57407212af70f80b712 to your computer and use it in GitHub Desktop.
commit 0f2f28953cc4a8cdeb0d82fc6264ffe1ba7aeb5c
Author: Nikita Popov <nikita.ppv@gmail.com>
Date: Tue Jun 30 11:08:24 2020 +0200
Leak trace mode
diff --git a/Zend/zend.c b/Zend/zend.c
index 2765f8c3ea..52a7ab0fd7 100644
--- a/Zend/zend.c
+++ b/Zend/zend.c
@@ -35,6 +35,7 @@
#include "zend_attributes.h"
static size_t global_map_ptr_last = 0;
+ZEND_API FILE *leak_log_file;
#ifdef ZTS
ZEND_API int compiler_globals_id;
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index 5d619437f5..6c2251ae52 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -3479,6 +3479,7 @@ static zend_always_inline void i_init_func_execute_data(zend_op_array *op_array,
zend_init_cvs(num_args, op_array->last_var EXECUTE_DATA_CC);
EX(run_time_cache) = RUN_TIME_CACHE(op_array);
+ EX(opline) = opline;
EG(current_execute_data) = execute_data;
}
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c
index d62f104f22..e2be0d0780 100644
--- a/Zend/zend_execute_API.c
+++ b/Zend/zend_execute_API.c
@@ -560,7 +560,7 @@ ZEND_API uint32_t zend_get_executed_lineno(void) /* {{{ */
ex->opline->lineno == 0 && EG(opline_before_exception)) {
return EG(opline_before_exception)->lineno;
}
- return ex->opline->lineno;
+ return ex->opline ? ex->opline->lineno : 0;
} else {
return 0;
}
diff --git a/Zend/zend_types.h b/Zend/zend_types.h
index 7796979ed8..3941185261 100644
--- a/Zend/zend_types.h
+++ b/Zend/zend_types.h
@@ -1148,19 +1148,28 @@ static zend_always_inline uint32_t zend_gc_refcount(const zend_refcounted_h *p)
return p->refcount;
}
+BEGIN_EXTERN_C()
+ZEND_API const char *zend_get_executed_filename(void);
+ZEND_API uint32_t zend_get_executed_lineno(void);
+ZEND_API extern FILE *leak_log_file;
+END_EXTERN_C()
+
static zend_always_inline uint32_t zend_gc_set_refcount(zend_refcounted_h *p, uint32_t rc) {
p->refcount = rc;
+ fprintf(leak_log_file, "[%p] set %u @ %s:%d\n", p, p->refcount, zend_get_executed_filename(), zend_get_executed_lineno());
return p->refcount;
}
static zend_always_inline uint32_t zend_gc_addref(zend_refcounted_h *p) {
ZEND_RC_MOD_CHECK(p);
+ fprintf(leak_log_file, "[%p] inc %u @ %s:%d\n", p, p->refcount, zend_get_executed_filename(), zend_get_executed_lineno());
return ++(p->refcount);
}
static zend_always_inline uint32_t zend_gc_delref(zend_refcounted_h *p) {
ZEND_ASSERT(p->refcount > 0);
ZEND_RC_MOD_CHECK(p);
+ fprintf(leak_log_file, "[%p] dec %u @ %s:%d\n", p, p->refcount, zend_get_executed_filename(), zend_get_executed_lineno());
return --(p->refcount);
}
diff --git a/sapi/cli/php_cli.c b/sapi/cli/php_cli.c
index dfda90fb8e..d61575257f 100644
--- a/sapi/cli/php_cli.c
+++ b/sapi/cli/php_cli.c
@@ -1229,6 +1229,8 @@ int main(int argc, char *argv[])
setmode(_fileno(stderr), O_BINARY); /* make the stdio mode be binary */
#endif
+ leak_log_file = fopen("leak_log", "w");
+
while ((c = php_getopt(argc, argv, OPTIONS, &php_optarg, &php_optind, 1, 2))!=-1) {
switch (c) {
case 'c':
@@ -1392,6 +1394,7 @@ out:
* exiting.
*/
cleanup_ps_args(argv);
+ fflush(leak_log_file);
exit(exit_status);
}
/* }}} */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment