Skip to content

Commit

Permalink
Merged pull request #360
Browse files Browse the repository at this point in the history
  • Loading branch information
derickr committed Dec 31, 2017
2 parents d6dd7dd + 506ebad commit adefecb
Show file tree
Hide file tree
Showing 16 changed files with 652 additions and 9 deletions.
2 changes: 1 addition & 1 deletion config.m4
Expand Up @@ -30,7 +30,7 @@ if test "$PHP_XDEBUG" != "no"; then

CPPFLAGS=$old_CPPFLAGS

PHP_NEW_EXTENSION(xdebug, xdebug.c xdebug_branch_info.c xdebug_code_coverage.c xdebug_com.c xdebug_compat.c xdebug_filter.c xdebug_handler_dbgp.c xdebug_handlers.c xdebug_llist.c xdebug_monitor.c xdebug_hash.c xdebug_private.c xdebug_profiler.c xdebug_set.c xdebug_stack.c xdebug_str.c xdebug_superglobals.c xdebug_tracing.c xdebug_trace_textual.c xdebug_trace_computerized.c xdebug_trace_html.c xdebug_var.c xdebug_xml.c usefulstuff.c, $ext_shared,,,,yes)
PHP_NEW_EXTENSION(xdebug, xdebug.c xdebug_branch_info.c xdebug_code_coverage.c xdebug_com.c xdebug_compat.c xdebug_gc_stats.c xdebug_filter.c xdebug_handler_dbgp.c xdebug_handlers.c xdebug_llist.c xdebug_monitor.c xdebug_hash.c xdebug_private.c xdebug_profiler.c xdebug_set.c xdebug_stack.c xdebug_str.c xdebug_superglobals.c xdebug_tracing.c xdebug_trace_textual.c xdebug_trace_computerized.c xdebug_trace_html.c xdebug_var.c xdebug_xml.c usefulstuff.c, $ext_shared,,,,yes)
PHP_SUBST(XDEBUG_SHARED_LIBADD)
PHP_ADD_MAKEFILE_FRAGMENT
fi
15 changes: 8 additions & 7 deletions config.w32
Expand Up @@ -4,13 +4,14 @@
ARG_WITH("xdebug", "Xdebug support", "no");

if (PHP_XDEBUG != 'no') {
var files = 'xdebug.c xdebug_branch_info.c xdebug_code_coverage.c ' +
'xdebug_com.c xdebug_compat.c xdebug_filter.c xdebug_handler_dbgp.c ' +
'xdebug_handlers.c xdebug_llist.c xdebug_monitor.c ' +
'xdebug_hash.c xdebug_private.c xdebug_profiler.c ' +
'xdebug_set.c xdebug_stack.c xdebug_str.c xdebug_superglobals.c ' +
'xdebug_tracing.c xdebug_trace_textual.c xdebug_trace_computerized.c ' +
'xdebug_trace_html.c xdebug_var.c xdebug_xml.c usefulstuff.c';
var files = 'xdebug.c xdebug_branch_info.c xdebug_code_coverage.c ' +
'xdebug_com.c xdebug_compat.c xdebug_filter.c xdebug_gc_stats.c ' +
'xdebug_handler_dbgp.c ' +
'xdebug_handlers.c xdebug_llist.c xdebug_monitor.c ' +
'xdebug_hash.c xdebug_private.c xdebug_profiler.c ' +
'xdebug_set.c xdebug_stack.c xdebug_str.c xdebug_superglobals.c ' +
'xdebug_tracing.c xdebug_trace_textual.c xdebug_trace_computerized.c ' +
'xdebug_trace_html.c xdebug_var.c xdebug_xml.c usefulstuff.c';

if (typeof(ZEND_EXTENSION) == 'undefined') {
EXTENSION('xdebug', files);
Expand Down
15 changes: 15 additions & 0 deletions php_xdebug.h
Expand Up @@ -117,6 +117,13 @@ PHP_FUNCTION(xdebug_get_profiler_filename);
PHP_FUNCTION(xdebug_dump_aggr_profiling_data);
PHP_FUNCTION(xdebug_clear_aggr_profiling_data);

/* gc stats functions */
PHP_FUNCTION(xdebug_start_gcstats);
PHP_FUNCTION(xdebug_stop_gcstats);
PHP_FUNCTION(xdebug_get_gcstats_filename);
PHP_FUNCTION(xdebug_get_gc_run_count);
PHP_FUNCTION(xdebug_get_gc_total_collected_roots);

/* misc functions */
PHP_FUNCTION(xdebug_dump_superglobals);
PHP_FUNCTION(xdebug_get_headers);
Expand Down Expand Up @@ -290,6 +297,14 @@ ZEND_BEGIN_MODULE_GLOBALS(xdebug)
zend_bool do_scream;
zend_bool in_at;

/* garbage stats */
zend_bool gc_stats_enable;
zend_bool gc_stats_enabled;
char *gc_stats_output_dir;
char *gc_stats_output_name;
FILE *gc_stats_file;
char *gc_stats_filename;

/* in-execution checking */
zend_bool in_execution;
zend_bool in_var_serialisation;
Expand Down
18 changes: 18 additions & 0 deletions tests/xdebug_gc_stats1.phpt
@@ -0,0 +1,18 @@
--TEST--
GC Stats: No memleak, return empty runs
--INI--
zend.enable_gc=1
xdebug.gc_stats_enable=1
--FILE--
<?php
echo file_get_contents(xdebug_get_gcstats_filename());
xdebug_stop_gcstats();
unlink(xdebug_get_gcstats_filename());
?>
--EXPECTF--
Garbage Collection Report
version: 1
creator: xdebug %d.%s (PHP %s)

Collected | Efficiency% | Duration | Memory Before | Memory After | Reduction% | Function
----------+-------------+----------+---------------+--------------+------------+---------
31 changes: 31 additions & 0 deletions tests/xdebug_gc_stats2.phpt
@@ -0,0 +1,31 @@
--TEST--
GC Stats: Run gc_collect_cyles(); and collect stats
--INI--
zend.enable_gc=1
xdebug.gc_stats_enable=1
--FILE--
<?php
var_dump(ini_get("xdebug.gc_stats_enable"));

for ($i = 0; $i < 100; $i++) {
$a = new stdClass();
$b = new stdClass();
$b->a = $a;
$a->b = $b;
unset($a, $b);
}
gc_collect_cycles();

echo file_get_contents(xdebug_get_gcstats_filename());
xdebug_stop_gcstats();
unlink(xdebug_get_gcstats_filename());
?>
--EXPECTF--
string(1) "1"
Garbage Collection Report
version: 1
creator: xdebug %d.%s (PHP %s)

Collected | Efficiency% | Duration | Memory Before | Memory After | Reduction% | Function
----------+-------------+----------+---------------+--------------+------------+---------
200 | 2.00 % | %s ms | %d | %d | %s % | gc_collect_cycles
36 changes: 36 additions & 0 deletions tests/xdebug_gc_stats3.phpt
@@ -0,0 +1,36 @@
--TEST--
GC Stats: Stats about trigger garbage collection automatically
--INI--
zend.enable_gc=1
xdebug.gc_stats_enable=1
--FILE--
<?php

gc_enable();

function foo()
{
bar();
}

function bar()
{
for ($i = 0; $i < 20000; $i++) {
$a = new stdClass();
$b = new stdClass();
$b->a = $a;
$a->b = $b;
unset($a, $b);
}
}

foo();

$lines = file(xdebug_get_gcstats_filename());
xdebug_stop_gcstats();
unlink(xdebug_get_gcstats_filename());

var_dump(count($lines) >= 6);
?>
--EXPECTF--
bool(true)
61 changes: 61 additions & 0 deletions tests/xdebug_gc_stats4.phpt
@@ -0,0 +1,61 @@
--TEST--
GC Stats: Class with garbage
--INI--
zend.enable_gc=1
xdebug.gc_stats_enable=1
--FILE--
<?php

function foo()
{
bar();
}

function bar()
{
for ($i = 0; $i < 20000; $i++)
{
$a = new stdClass();
$b = new stdClass();
$b->a = $a;
$a->b = $b;
unset($a, $b);
}
}

class Garbage
{
public function produce()
{
$foo = new stdClass();

for ($i = 0; $i < 20000; $i++)
{
$a = new stdClass();
$b = new stdClass();
$b->foo = $foo;
$b->a = $a;
$a->b = $b;
unset($a, $b);
}

unset($foo);
gc_collect_cycles();
}
}

foo();
(new Garbage())->produce();

$data = file_get_contents(xdebug_get_gcstats_filename());
xdebug_stop_gcstats();
unlink(xdebug_get_gcstats_filename());

var_dump(substr_count($data, "bar") >= 3);
var_dump(substr_count($data, "Garbage::produce") >= 4);
var_dump(substr_count($data, "gc_collect_cycles") == 1);
?>
--EXPECTF--
bool(true)
bool(true)
bool(true)
46 changes: 46 additions & 0 deletions tests/xdebug_gc_stats5.phpt
@@ -0,0 +1,46 @@
--TEST--
GC Stats: Start with xdebug_start_gcstats()
--INI--
zend.enable_gc=1
xdebug.gc_stats_enable=0
--FILE--
<?php

var_dump(ini_get("xdebug.gc_stats_enable"));

for ($i = 0; $i < 100; $i++)
{
$a = new stdClass();
$b = new stdClass();
$b->a = $a;
$a->b = $b;
unset($a, $b);
}
gc_collect_cycles();

xdebug_start_gcstats();

for ($i = 0; $i < 100; $i++)
{
$a = new stdClass();
$b = new stdClass();
$b->a = $a;
$a->b = $b;
unset($a, $b);
}
gc_collect_cycles();

echo file_get_contents(xdebug_get_gcstats_filename());
xdebug_stop_gcstats();
unlink(xdebug_get_gcstats_filename());
?>
--EXPECTF--
string(1) "0"
Garbage Collection Report
version: 1
creator: xdebug %d.%s (PHP %s)

Collected | Efficiency% | Duration | Memory Before | Memory After | Reduction% | Function
----------+-------------+----------+---------------+--------------+------------+---------
200 | 2.00 % | %s ms | %d | %d | %s % | gc_collect_cycles

21 changes: 21 additions & 0 deletions tests/xdebug_gc_stats6.phpt
@@ -0,0 +1,21 @@
--TEST--
GC Stats: Start with xdebug_start_gcstats() and filename
--INI--
zend.enable_gc=1
xdebug.gc_stats_enable=0
--FILE--
<?php
var_dump(xdebug_get_gcstats_filename());

$filename = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'gcstats.txt';
$actual = xdebug_start_gcstats($filename);

var_dump($actual === $filename);
var_dump(xdebug_get_gcstats_filename());
xdebug_stop_gcstats();
unlink(xdebug_get_gcstats_filename());
?>
--EXPECTF--
bool(false)
bool(true)
string(%d) "%sgcstats.txt"
22 changes: 22 additions & 0 deletions tests/xdebug_gc_stats7.phpt
@@ -0,0 +1,22 @@
--TEST--
GC Stats: userland statistic functions
--INI--
zend.enable_gc=1
--FILE--
<?php

for ($i = 0; $i < 100; $i++) {
$a = new stdClass();
$b = new stdClass();
$b->a = $a;
$a->b = $b;
unset($a, $b);
}
gc_collect_cycles();

printf("runs: %d\n", xdebug_get_gc_run_count());
printf("collected: %d\n", xdebug_get_gc_total_collected_roots());
?>
--EXPECTF--
runs: 1
collected: 200
59 changes: 59 additions & 0 deletions tests/xdebug_gc_stats8.phpt
@@ -0,0 +1,59 @@
--TEST--
GC Stats: Closure with garbage
--INI--
zend.enable_gc=1
xdebug.gc_stats_enable=1
--FILE--
<?php

function foo()
{
bar();
}

function bar()
{
for ($i = 0; $i < 20000; $i++)
{
$a = new stdClass();
$b = new stdClass();
$b->a = $a;
$a->b = $b;
unset($a, $b);
}
}

$closure = function() {
$foo = new stdClass();

for ($i = 0; $i < 20000; $i++)
{
$a = new stdClass();
$b = new stdClass();
$b->foo = $foo;
$b->a = $a;
$a->b = $b;
unset($a, $b);
}

unset($foo);
gc_collect_cycles();
};

foo();
$closure();

$data = file_get_contents(xdebug_get_gcstats_filename());
xdebug_stop_gcstats();
unlink(xdebug_get_gcstats_filename());

var_dump(substr_count($data, "bar") >= 3);
var_dump(substr_count($data, "{closure:") >= 4);
var_dump(substr_count($data, "xdebug_gc_stats8.php:20-35}") >= 4);
var_dump(substr_count($data, "gc_collect_cycles") == 1);
?>
--EXPECTF--
bool(true)
bool(true)
bool(true)
bool(true)

0 comments on commit adefecb

Please sign in to comment.