Git Product home page Git Product logo

php-meminfo's Introduction

MEMINFO

PHP Meminfo is a PHP extension that gives you insights on the PHP memory content.

Its main goal is to help you understand memory leaks: by looking at data present in memory, you can better understand your application behaviour.

One of the main sources of inspiration for this tool is the Java jmap tool with the -histo option (see man jmap).

Build

Compatibility

PHP 7.x, 8.0.

For older versions of PHP, you can use the following releases:

  • 5.6: PHP Meminfo v1.1
  • 5.5: PHP Meminfo v1.0.5 (may work with PHP 5.3 and PHP 5.4 but not tested)

Compilation instructions

Compilation

From the root of the extension directory:

$ phpize
$ ./configure --enable-meminfo
$ make
$ make install

Enabling the extension

Add the following line to your php.ini:

extension=meminfo.so

Installing analyzers

Analyzers allow to analyze a memory dump (see below).

$ cd analyzer
$ composer install

Usage

Dumping memory content

meminfo_dump(fopen('/tmp/my_dump_file.json', 'w'));

This function generates a dump of the PHP memory in a JSON format. This dump can be later analyzed by the provided analyzers.

This function takes a stream handle as a parameter. It allows you to specify a file (ex fopen('/tmp/file.txt', 'w'), as well as to use standard output with the php://stdout stream.

Displaying a summary of items in memory

$ bin/analyzer summary <dump-file>

Arguments:
  dump-file             PHP Meminfo Dump File in JSON format

Example

$ bin/analyzer summary /tmp/my_dump_file.json
+----------+-----------------+-----------------------------+
| Type     | Instances Count | Cumulated Self Size (bytes) |
+----------+-----------------+-----------------------------+
| string   | 132             | 7079                        |
| MyClassA | 100             | 7200                        |
| array    | 10              | 720                         |
| integer  | 5               | 80                          |
| float    | 2               | 32                          |
| null     | 1               | 16                          |
+----------+-----------------+-----------------------------+

Displaying a list of objects with the largest number of children

$ bin/analyzer top-children [options] [--] <dump-file>

Arguments:
  dump-file             PHP Meminfo Dump File in JSON format

Options:
  -l, --limit[=LIMIT]   limit [default: 5]

Example

$ bin/analyzer top-children /tmp/my_dump_file.json
+-----+----------------+----------+
| Num | Item ids       | Children |
+-----+----------------+----------+
| 1   | 0x7ffff4e22fe0 | 1000000  |
| 2   | 0x7fffe780e5c8 | 11606    |
| 3   | 0x7fffe9714ef0 | 11602    |
| 4   | 0x7fffeab63ca0 | 3605     |
| 5   | 0x7fffd3161400 | 2400     |
+-----+----------------+----------+

Querying the memory dump to find specific objects

$ bin/analyzer query [options] [--] <dump-file>

Arguments:
  dump-file              PHP Meminfo Dump File in JSON format

Options:
  -f, --filters=FILTERS  Filter on an attribute. Operators: =, ~. Example: class~User (multiple values allowed)
  -l, --limit=LIMIT      Number of results limit (default 10).
  -v                     Increase the verbosity

Example

$ bin/analyzer query -v -f "class=MyClassA" -f "is_root=0" /tmp/php_mem_dump.json
+----------------+-------------------+------------------------------+
| Item ids       | Item data         | Children                     |
+----------------+-------------------+------------------------------+
| 0x7f94a1877008 | Type: object      | myObjectName: 0x7f94a185cca0 |
|                | Class: MyClassA   |                              |
|                | Object Handle: 1  |                              |
|                | Size: 72 B        |                              |
|                | Is root: No       |                              |
+----------------+-------------------+------------------------------+
| 0x7f94a1877028 | Type: object      | myObjectName: 0x7f94a185cde0 |
|                | Class: MyClassA   |                              |
|                | Object Handle: 2  |                              |
|                | Size: 72 B        |                              |
|                | Is root: No       |                              |
+----------------+-------------------+------------------------------+
| 0x7f94a1877048 | Type: object      | myObjectName: 0x7f94a185cf20 |
|                | Class: MyClassA   |                              |
...

Displaying the reference path

The reference path is the path between a specific item in memory (identified by its pointer address) and all the intermediary items up to the one item that is attached to a variable still alive in the program.

This path shows which items are responsible for the memory leak of the specific item provided.

$ bin/analyzer ref-path <item-id> <dump-file>

Arguments:
  item-id               Item Id in 0xaaaaaaaa format
  dump-file             PHP Meminfo Dump File in JSON format

Options:
  -v                     Increase the verbosity

Example

$ bin/analyzer ref-path -v 0x7f94a1877068 /tmp/php_mem_dump.json
Found 1 paths
Path from 0x7f94a1856260
+--------------------+
| Id: 0x7f94a1877068 |
| Type: object       |
| Class: MyClassA    |
| Object Handle: 4   |
| Size: 72 B         |
| Is root: No        |
| Children count: 1  |
+--------------------+
         ^
         |
         3
         |
         |
+---------------------+
| Id: 0x7f94a185cb60  |
| Type: array         |
| Size: 72 B          |
| Is root: No         |
| Children count: 100 |
+---------------------+
         ^
         |
    second level
         |
         |
+--------------------+
| Id: 0x7f94a185ca20 |
| Type: array        |
| Size: 72 B         |
| Is root: No        |
| Children count: 1  |
+--------------------+
         ^
         |
    first level
         |
         |
+---------------------------+
| Id: 0x7f94a1856260        |
| Type: array               |
| Size: 72 B                |
| Is root: Yes              |
| Execution Frame: <GLOBAL> |
| Symbol Name: myRootArray  |
| Children count: 1         |
+---------------------------+

A workflow to find and understand memory leaks using PHP Meminfo

Hunting down memory leaks

Other memory debugging tools for PHP

  • XDebug (https://xdebug.org/) With the trace feature and the memory delta option (tool see XDebug documentation), you can trace function memory usage. You can use the provided script to get an aggregated view (TODO link)

  • PHP Memprof (https://github.com/arnaud-lb/php-memory-profiler) Provides aggregated data about memory usage by functions. Far less resource intensive than a full trace from XDebug.

Troubleshooting

"A lot of memory usage is reported by the memory_usage entry, but the cumulative size of the items in the summary is far lower than the memory usage"

A lot of memory is used internally by the Zend Engine itself to compile PHP files, to run the virtual machine, to execute the garbage collector, etc... Another part of the memory is usually taken by PHP extensions themselves. And the remaining memory usage comes from the PHP data structures from your program.

In some cases, several hundred megabytes can be used internally by some PHP extensions. Examples are the PDO extension and MySQLi extension. By default, when executing a SQL query they will buffer all the results inside the PHP memory: http://php.net/manual/en/mysqlinfo.concepts.buffering.php

In case of very large number of results, this will consume a lot of memory, and this memory usage is not caused by the data you have in your objects or array manipulated by your program, but by the way the extension works.

This is only one example, but the same can happen with image manipulation extensions, that will use a lot of memory to transform images.

All the extensions are using the Zend Memory Manager, so that they will not exceed the maximum memory limit set for the PHP process. So their memory usage is included in the information provided by memory_get_usage().

But PHP Meminfo is only able to get information on memory used by the data structure from the PHP program, not from the extensions themselves.

Hence the difference between those numbers, which can be quite big.

"Call to undefined function" when calling meminfo_dump

This means the extension is not enabled.

Check the PHP Info output and look for the MemInfo data.

To see the PHP Info output, just create a page calling the phpinfo(); function, and load it from your browser, or call php -i from the command line.

Why most tests are "skipped"?

While doing a make test, some tests will need JSON capabilities. But the compilation system generates a clean env by removing all configuration directives that load extensions. So if JSON capabilites are packaged as a separate extension (instead of being compiled directly in the PHP runtime), the tests will be skipped.

You may run them with the run-tests.php generated after the make test command, by providing the php executable:

$ TEST_PHP_EXECUTABLE=$(which php) $(which php) run-tests.php -d extension=$PWD/modules/meminfo.so

In this case your tests will run with your local PHP configuration, including the loading of the JSON extension.

Please note this is not required when working with PHP 8 as the JSON functions are now usually complied in PHP directly.

Credits

Thanks to Derick Rethans for his inspirational work on the essential XDebug. See http://www.xdebug.org/

php-meminfo's People

Contributors

ahocquard avatar avallac avatar benmorel avatar bitone avatar cmb69 avatar drbyte avatar edorian avatar fitn avatar gquemener avatar greg0ire avatar jdecool avatar juchi avatar lyrixx avatar mathieuk avatar mauriau avatar max-voloshin avatar mbonneau avatar ovr avatar pierallard avatar tony2001 avatar wyrihaximus avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

php-meminfo's Issues

Memory leak not displayed in the dump

First of all, this is a great extension, thank you. Is making my life really easier.

But here my issue... (looks rather similar to #54).
As you pointed in #54 there might be an extension leak... or this extension is not able to detect some memory content.

However, running this:

for ($i = 0; $i<100; $i++){
  $func();
  echo round(memory_get_usage()/1024/1024, 6).PHP_EOL;
  gc_collect_cycles();
}
echo round(memory_get_usage()/1024/1024, 6).PHP_EOL;
meminfo_dump(fopen('dump_file_z.json', 'w'));

$func is a closure that runs a complete symfony 3.4 app.

Independently from how many iterations does the for loop, the dumped file looks always the same, but memory usage goes up ~2MB on each loop iteration (reaching my current 500MB memory limit).

Here the dump:

root@dad957857bb5:/opt/php-meminfo/analyzer# bin/analyzer summary dump.json 
+-------------------------------+-----------------+-----------------------------+
| Type                          | Instances Count | Cumulated Self Size (bytes) |
+-------------------------------+-----------------+-----------------------------+
| string                        | 1090            | 63384                       |
| array                         | 492             | 35424                       |
| integer                       | 281             | 4496                        |
| boolean                       | 39              | 624                         |
| null                          | 8               | 128                         |
| unknown                       | 5               | 80                          |
| Composer\Autoload\ClassLoader | 1               | 72                          |
| DateTimeZone                  | 1               | 72                          |
| Predis\Response\Status        | 1               | 72                          |
+-------------------------------+-----------------+-----------------------------+

Any idea on what could be?

[enhancement] Provide JSON output

It would be awesome if extension could provide JSON output.
It gives an opportunity to build a dashboard with some visualization of the collected data for better usability.
Thanks!

Provide a simpler view for the reference path

For now, reference path is displayed using a cumbersome format. For example:

--------------------+
| Id: 0x7f94a1877068 |
| Type: object       |
| Class: MyClassA    |
| Object Handle: 4   |
| Size: 72 B         |
| Is root: No        |
| Children count: 1  |
+--------------------+
         ^
         |
         3
         |
         |
+---------------------+
| Id: 0x7f94a185cb60  |
| Type: array         |
| Size: 72 B          |
| Is root: No         |
| Children count: 100 |
+---------------------+
         ^
         |
    second level
         |
         |
+--------------------+
| Id: 0x7f94a185ca20 |
| Type: array        |
| Size: 72 B         |
| Is root: No        |
| Children count: 1  |
+--------------------+
         ^
         |
    first level
         |
         |
+---------------------------+
| Id: 0x7f94a1856260        |
| Type: array               |
| Size: 72 B                |
| Is root: Yes              |
| Execution Frame: <GLOBAL> |
| Symbol Name: myRootArray  |
| Children count: 1         |
+---------------------------+

This could be reduced to:
$myRootArray['first level']['second level'][3]

Diff two JSON files

Attempting to hunt down a memory leak using the following code:

meminfo_dump(fopen('before.json', 'w'));
echo gc_collect_cycles();
meminfo_dump(fopen('after.json', 'w'));

Now I can't easily compare those two files. A diff command would be a great addition to see what has changed.

What you mean under "forever in memory"?

Hi, trying to understand this slide:
https://speakerd.s3.amazonaws.com/presentations/8f6d8303502241cab85a320a2bb1db2d/slide_27.jpg

What you mean under "forever in memory"?

If I try next:

class MyClass{}

function buildObjects() {
    $objectA = new MyClass();
    $objectB = new MyClass();

    $objectA->b = $objectB;
    $objectB->a = $objectA;

    return $objectA;
}

$leakHolder = [];
for ($i = 0; $i < 200; $i++) {

    $object = buildObjects();
    $leakHolder[] = $object;
}

unset($leakHolder);
unset($object);
meminfo_dump(fopen('/tmp/php_mem_dump'.$i.'.json','w'));

With iterations: 200, 2 000, 20 000, 200 000


Result always the same:

| Type    | Instances Count | Cumulated Self Size (bytes) |
+---------+-----------------+-----------------------------+
| string  | 82              | 4643                        |
| array   | 9               | 648                         |
| integer | 4               | 64                          |
| unknown | 2               | 32                          |
| float   | 1               | 16                          |
+---------+-----------------+-----------------------------+

What you mean under "always stay in memory"?

As I understand memory will leak until not start cycle GC or until I not run gc_collect_cycles().
We can find only what developer forget to unset.

Take into account unreferencable circular references

A source of (perceived) memory leaks will be circular references (especially to objects) that haven't been picked up by the GC yet. php-meminfo should provide insight into objects that aren't currently referencable from the PHP userland but are still active in memory.

Example script where php-meminfo doesn't report the existance of the objects:

<?php

class X {
        function __construct($y) {
                $this->y = $y;
        }
}

class Y {
        function __construct() {
                $this->x = new X($this);
        }

}

function test() {
        return new Y;
}

test();

meminfo_dump(fopen('dump.json', 'w'));

The output will be:

{
  "header" : {
    "memory_usage" : 393120,
    "memory_usage_real" : 2097152,
    "peak_memory_usage" : 428880,
    "peak_memory_usage_real" : 2097152
  },
  "items": {
    "0x7f8ea4260100" : {
        "type" : "array",
        "size" : "72",
        "symbol_name" : "_GET",
        "is_root" : true,
        "frame" : "<GLOBAL>"
,
        "children" : {

        }

    },
    "0x7f8ea4260120" : {
        "type" : "array",
        "size" : "72",
        "symbol_name" : "_POST",
        "is_root" : true,
        "frame" : "<GLOBAL>"
,
        "children" : {

        }

    },
    "0x7f8ea4260140" : {
        "type" : "array",
        "size" : "72",
        "symbol_name" : "_COOKIE",
        "is_root" : true,
        "frame" : "<GLOBAL>"
,
        "children" : {

        }

    },
    "0x7f8ea4260160" : {
        "type" : "array",
        "size" : "72",
        "symbol_name" : "_FILES",
        "is_root" : true,
        "frame" : "<GLOBAL>"
,
        "children" : {

        }

    },
    "0x7f8ea4260180" : {
        "type" : "array",
        "size" : "72",
        "symbol_name" : "argv",
        "is_root" : true,
        "frame" : "<GLOBAL>"
,
        "children" : {
            "0":"0x7f8ea4266008"
        }

    },
    "0x7f8ea4266008" : {
        "type" : "string",
        "size" : "25",
        "is_root" : false


    },
    "0x7f8ea42601a0" : {
        "type" : "integer",
        "size" : "16",
        "symbol_name" : "argc",
        "is_root" : true,
        "frame" : "<GLOBAL>"


    },
    "0x7f8ea42601c0" : {
        "type" : "array",
        "size" : "72",
        "symbol_name" : "_ENV",
        "is_root" : true,
        "frame" : "<GLOBAL>"
,
        "children" : {

        }

    },
    "0x7f8ea42601e0" : {
        "type" : "array",
        "size" : "72",
        "symbol_name" : "_REQUEST",
        "is_root" : true,
        "frame" : "<GLOBAL>"
,
        "children" : {

        }

    },
    "0x7f8ea4260200" : {
        "type" : "array",
        "size" : "72",
        "symbol_name" : "_SERVER",
        "is_root" : true,
        "frame" : "<GLOBAL>"
,
        "children" : {
            "XDG_SESSION_ID":"0x7f8ea4260b00",
            "HOSTNAME":"0x7f8ea4260b20",
            "SELINUX_ROLE_REQUESTED":"0x7f8ea4260b40",
            "TERM":"0x7f8ea4260b60",
            "SHELL":"0x7f8ea4260b80",
            "HISTSIZE":"0x7f8ea4260ba0",
            "SSH_CLIENT":"0x7f8ea4260bc0",
            "PERL5LIB":"0x7f8ea4260be0",
            "SELINUX_USE_CURRENT_RANGE":"0x7f8ea4260c00",
            "QTDIR":"0x7f8ea4260c20",
            "OLDPWD":"0x7f8ea4260c40",
            "QTINC":"0x7f8ea4260c60",
            "PERL_MB_OPT":"0x7f8ea4260c80",
            "SSH_TTY":"0x7f8ea4260ca0",
            "QT_GRAPHICSSYSTEM_CHECKED":"0x7f8ea4260cc0",
            "USER":"0x7f8ea4260ce0",
            "LS_COLORS":"0x7f8ea4260d00",
            "SSH_AUTH_SOCK":"0x7f8ea4260d20",
            "MAIL":"0x7f8ea4260d40",
            "PATH":"0x7f8ea4260d60",
            "PWD":"0x7f8ea4260d80",
            "LANG":"0x7f8ea4260da0",
            "MODULEPATH":"0x7f8ea4260dc0",
            "LOADEDMODULES":"0x7f8ea4260de0",
            "KDEDIRS":"0x7f8ea4260e00",
            "SELINUX_LEVEL_REQUESTED":"0x7f8ea4260e20",
            "HISTCONTROL":"0x7f8ea4260e40",
            "SHLVL":"0x7f8ea4260e60",
            "HOME":"0x7f8ea4260e80",
            "PERL_LOCAL_LIB_ROOT":"0x7f8ea4260ea0",
            "LOGNAME":"0x7f8ea4260ec0",
            "QTLIB":"0x7f8ea4260ee0",
            "SSH_CONNECTION":"0x7f8ea4260f00",
            "LC_CTYPE":"0x7f8ea4260f20",
            "MODULESHOME":"0x7f8ea4260f40",
            "LESSOPEN":"0x7f8ea4260f60",
            "XDG_RUNTIME_DIR":"0x7f8ea4260f80",
            "QT_PLUGIN_PATH":"0x7f8ea4260fa0",
            "PERL_MM_OPT":"0x7f8ea4260fc0",
            "BASH_FUNC_module()":"0x7f8ea4260fe0",
            "_":"0x7f8ea4261000",
            "PHP_SELF":"0x7f8ea4261020",
            "SCRIPT_NAME":"0x7f8ea4261040",
            "SCRIPT_FILENAME":"0x7f8ea4261060",
            "PATH_TRANSLATED":"0x7f8ea4261080",
            "DOCUMENT_ROOT":"0x7f8ea42610a0",
            "REQUEST_TIME_FLOAT":"0x7f8ea42610c0",
            "REQUEST_TIME":"0x7f8ea42610e0",
            "argv":"0x7f8ea4261100",
            "argc":"0x7f8ea4261120"
        }

    },
    "0x7f8ea4260b00" : {
        "type" : "string",
        "size" : "18",
        "is_root" : false


    },
    "0x7f8ea4260b20" : {
        "type" : "string",
        "size" : "37",
        "is_root" : false


    },
    "0x7f8ea4260b40" : {
        "type" : "string",
        "size" : "16",
        "is_root" : false


    },
    "0x7f8ea4260b60" : {
        "type" : "string",
        "size" : "30",
        "is_root" : false


    },
    "0x7f8ea4260b80" : {
        "type" : "string",
        "size" : "25",
        "is_root" : false


    },
    "0x7f8ea4260ba0" : {
        "type" : "string",
        "size" : "20",
        "is_root" : false


    },
    "0x7f8ea4260bc0" : {
        "type" : "string",
        "size" : "33",
        "is_root" : false


    },
    "0x7f8ea4260be0" : {
        "type" : "string",
        "size" : "46",
        "is_root" : false


    },
    "0x7f8ea4260c00" : {
        "type" : "string",
        "size" : "16",
        "is_root" : false


    },
    "0x7f8ea4260c20" : {
        "type" : "string",
        "size" : "33",
        "is_root" : false


    },
    "0x7f8ea4260c40" : {
        "type" : "string",
        "size" : "29",
        "is_root" : false


    },
    "0x7f8ea4260c60" : {
        "type" : "string",
        "size" : "41",
        "is_root" : false


    },
    "0x7f8ea4260c80" : {
        "type" : "string",
        "size" : "50",
        "is_root" : false


    },
    "0x7f8ea4260ca0" : {
        "type" : "string",
        "size" : "26",
        "is_root" : false


    },
    "0x7f8ea4260cc0" : {
        "type" : "string",
        "size" : "17",
        "is_root" : false


    },
    "0x7f8ea4260ce0" : {
        "type" : "string",
        "size" : "23",
        "is_root" : false


    },
    "0x7f8ea4260d00" : {
        "type" : "string",
        "size" : "1725",
        "is_root" : false


    },
    "0x7f8ea4260d20" : {
        "type" : "string",
        "size" : "47",
        "is_root" : false


    },
    "0x7f8ea4260d40" : {
        "type" : "string",
        "size" : "39",
        "is_root" : false


    },
    "0x7f8ea4260d60" : {
        "type" : "string",
        "size" : "154",
        "is_root" : false


    },
    "0x7f8ea4260d80" : {
        "type" : "string",
        "size" : "31",
        "is_root" : false


    },
    "0x7f8ea4260da0" : {
        "type" : "string",
        "size" : "27",
        "is_root" : false


    },
    "0x7f8ea4260dc0" : {
        "type" : "string",
        "size" : "63",
        "is_root" : false


    },
    "0x7f8ea4260de0" : {
        "type" : "string",
        "size" : "16",
        "is_root" : false


    },
    "0x7f8ea4260e00" : {
        "type" : "string",
        "size" : "20",
        "is_root" : false


    },
    "0x7f8ea4260e20" : {
        "type" : "string",
        "size" : "16",
        "is_root" : false


    },
    "0x7f8ea4260e40" : {
        "type" : "string",
        "size" : "26",
        "is_root" : false


    },
    "0x7f8ea4260e60" : {
        "type" : "string",
        "size" : "17",
        "is_root" : false


    },
    "0x7f8ea4260e80" : {
        "type" : "string",
        "size" : "29",
        "is_root" : false


    },
    "0x7f8ea4260ea0" : {
        "type" : "string",
        "size" : "36",
        "is_root" : false


    },
    "0x7f8ea4260ec0" : {
        "type" : "string",
        "size" : "23",
        "is_root" : false


    },
    "0x7f8ea4260ee0" : {
        "type" : "string",
        "size" : "37",
        "is_root" : false


    },
    "0x7f8ea4260f00" : {
        "type" : "string",
        "size" : "43",
        "is_root" : false


    },
    "0x7f8ea4260f20" : {
        "type" : "string",
        "size" : "21",
        "is_root" : false


    },
    "0x7f8ea4260f40" : {
        "type" : "string",
        "size" : "34",
        "is_root" : false


    },
    "0x7f8ea4260f60" : {
        "type" : "string",
        "size" : "41",
        "is_root" : false


    },
    "0x7f8ea4260f80" : {
        "type" : "string",
        "size" : "30",
        "is_root" : false


    },
    "0x7f8ea4260fa0" : {
        "type" : "string",
        "size" : "61",
        "is_root" : false


    },
    "0x7f8ea4260fc0" : {
        "type" : "string",
        "size" : "48",
        "is_root" : false


    },
    "0x7f8ea4260fe0" : {
        "type" : "string",
        "size" : "57",
        "is_root" : false


    },
    "0x7f8ea4261000" : {
        "type" : "string",
        "size" : "28",
        "is_root" : false


    },
    "0x7f8ea4261020" : {
        "type" : "string",
        "size" : "25",
        "is_root" : false


    },
    "0x7f8ea4261040" : {
        "type" : "string",
        "size" : "25",
        "is_root" : false


    },
    "0x7f8ea4261060" : {
        "type" : "string",
        "size" : "25",
        "is_root" : false


    },
    "0x7f8ea4261080" : {
        "type" : "string",
        "size" : "25",
        "is_root" : false


    },
    "0x7f8ea42610a0" : {
        "type" : "string",
        "size" : "16",
        "is_root" : false


    },
    "0x7f8ea42610c0" : {
        "type" : "float",
        "size" : "16",
        "is_root" : false


    },
    "0x7f8ea42610e0" : {
        "type" : "integer",
        "size" : "16",
        "is_root" : false


    },
    "0x7f8ea4261100" : {
        "type" : "array",
        "size" : "72",
        "is_root" : false
,
        "children" : {
            "0":"0x7f8ea4266008"
        }

    },
    "0x7f8ea4261120" : {
        "type" : "integer",
        "size" : "16",
        "is_root" : false


    }
}
}

Method "meminfo_size_info" undefined

Hello,

The method « meminfo_size_info » is in the GitHub documentation but it is considered as undefined when I call it. The others functions work well.
Any idea ?

Fabien

Don't see memory leack in memory dump

Hi, I have memory leack in my workers.

I have done memory_get_usage() on each iteration:
50183840
91469968
95433592
99533688
103630880
107729448
..
378392128

Also I have done memory dump by meminfo:
meminfo_dump(fopen('/home/dmitriy/phpmem/my_dump_file_'.$i.'.json', 'w'));

But when I compare files with 2 and 43 iteration almost nothing changed.

I attached two files fith 2 and 43 iteration.
https://drive.google.com/open?id=1amDpzmyIel0QWdYqZp64F-f5L5fisqvC

Any ideas, why I don't see anything?

Wrong frame name for PHP 7

With the following code::

<?php
unset($_GET);
unset($_FILES);
unset($_POST);
unset($_SERVER);
unset($_COOKIE);
unset($argv);
unset($argc);

function test() {
    $a = "test";
    meminfo_dump(fopen('php://stdout', 'w'));
}   

test();

When executed with the PHP 7 version of the extension provides the following result:

{
"items": {
    "0x7f347ea57180" : {
        "type" : "unknown",
        "size" : "16",
        "symbol_name" : "argv",
        "is_root" : true,
        "frame" : "test()"
    },
    "0x7f347ea571a0" : {
        "type" : "unknown",
        "size" : "16",
        "symbol_name" : "argc",
        "is_root" : true,
        "frame" : "test()"
  }
}

The a variable is not present and the argv and argc variables are defined at the wrong frame.

Comparing to the execution with the PHP 5 version of the extension:

{
  "items": {
    "0x7fc6ca961158" : {
        "type" : "string",
        "size" : "28",
        "symbol_name" : "a",
        "is_root" : true,
        "frame" : "test()"
    }
}

Add value field

Hello,

meminfo_info_dump lacks the value field to generate some useful reports, pls merge my pull request #29 (it contains the fix and tests from #30 issue) because without this fix we can't gather reports in a row. It takes ~1000mb memory to get at least ~30 reports for the php app when it usually takes ~ 100mb of memory for its objects.

Thanks.

Brew install fails

Hey,

first of all thanks for creating this package.

But my issue is that I can not install it with brew.

$ brew install php71-meminfo 
Error: No available formula with the name "php71-meminfo" 
==> Searching for a previously deleted formula (in the last month)...
Error: No previously deleted formula found.
==> Searching for similarly named formulae...
==> Searching local taps...
Error: No similarly named formulae found.
==> Searching taps...
==> Searching taps on GitHub...
Error: No formulae found in taps.

I alos tried
brew install php72-meminfo
brew install php-meminfo

Generate the list of all dependencies between items in memory

To really understand where a memory leak comes from, it's the needed to know the object graph dependency.

It's possible to generate such a graph by getting the list of all existing memory item association. This list can have a very simple format:
node1-node2
where node1 is a givrn item and node2 an item linked to the firs one

Starting from this list, a visualization software should be able to display the dependency graph that will allow to get to the root of a memory leak.

Implementation:

  • possible starting point to get in memory item:
    • garbage collectors root list
    • main symbol table
    • traversing the objects and their dependencies
      • var_dump and print_r (includes a protection to infinite recursion ) implementation

A simple object_handle_1 - object_handle_2 could be the first step, as easier to get from PHP internals structure.

Memory leak caused by meminfo_dump

Looks like meminfo_dump itself causes unreported memory leaks.

Background: I tried to trace back a memory leak to a suspected XMLDom issue by running a method call in a loop, but then noticed that the actual memory usage was caused by meminfo_dump in this specific case.

Isolated test code (part of a big Laravel command, but run in isolation):

    public function dummy()
	{
		
	}
	
	public function MemTest($iterations=1)
	{
		for ($iteration = 1; $iteration <= $iterations; $iteration++)
		{
			$this->dummy();
			// $this->LoadXML(...);
			$gc = gc_collect_cycles();
			printf("MemTest %02d - gc: %d, peak mem: %5.3f MiB\n", 
                             $iteration, $gc, memory_get_peak_usage(false)/1000000);
			meminfo_dump(fopen(sprintf('meminfo-test-%02d.json', $iteration), 'w'));			
		}
	}

This results in the following output:

Memtest - running 100 iterations...

MemTest 01 - gc: 0, peak mem: 13.677 MiB
MemTest 02 - gc: 0, peak mem: 15.172 MiB
MemTest 03 - gc: 0, peak mem: 15.501 MiB
MemTest 04 - gc: 0, peak mem: 15.827 MiB
MemTest 05 - gc: 0, peak mem: 16.153 MiB
MemTest 06 - gc: 0, peak mem: 16.479 MiB
MemTest 07 - gc: 0, peak mem: 16.805 MiB
MemTest 08 - gc: 0, peak mem: 17.131 MiB
^C

So about 330 kB wasted on each iteration.
See below for meminfo output for 1st and last iteration.

After commenting out the line meminfo_dump(...) the following - expected - output is returned:

Memtest - running 99 iterations...

MemTest 01 - gc: 0, peak mem: 13.676 MiB
MemTest 02 - gc: 0, peak mem: 13.676 MiB
MemTest 03 - gc: 0, peak mem: 13.676 MiB
MemTest 04 - gc: 0, peak mem: 13.676 MiB
MemTest 05 - gc: 0, peak mem: 13.676 MiB
MemTest 06 - gc: 0, peak mem: 13.676 MiB
MemTest 07 - gc: 0, peak mem: 13.676 MiB
...
MemTest 96 - gc: 0, peak mem: 13.676 MiB
MemTest 97 - gc: 0, peak mem: 13.676 MiB
MemTest 98 - gc: 0, peak mem: 13.676 MiB
MemTest 99 - gc: 0, peak mem: 13.676 MiB

Inspection of the meminfo dumps shows the same trend for overall memory usage but does not show any detail of where the memory went; this is consistent with the documentation which states that memory in extensions is not shown.

NOTE: this is based on a legacy version of PHP 7.0.30 which we need for an existing Laravel 5.5 based project; meminfo was built from source from the master branch today.

PHP 7.0.30 (cli) (built: May  9 2018 06:56:41) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2017 Zend Technologies
    with Xdebug v2.6.0, Copyright (c) 2002-2018, by Derick Rethans

meminfo summary, first iteration:

{
  "header" : {
    "memory_usage" : 13613016,
    "memory_usage_real" : 14680064,
    "peak_memory_usage" : 13677144,
    "peak_memory_usage_real" : 14680064
  },
Type Instances Count Cumulated Self Size (bytes)
string 6720 629831
array 1843 132696
boolean 1185 18960
null 1076 17216
integer 497 7952
Closure 231 16632
Symfony\Component\Console\Input\InputOption 112 8064
Symfony\Component\Console\Input\InputDefinition 83 5976
Illuminate\Routing\Route 68 4896
Symfony\Component\Console\Input\InputArgument 36 2592
unknown 15 240
Symfony\Component\Console\Formatter\OutputFormatterStyle 5 360

meminfo summary, final iteration:

{
  "header" : {
    "memory_usage" : 46240416,
    "memory_usage_real" : 48234496,
    "peak_memory_usage" : 47126928,
    "peak_memory_usage_real" : 48234496
  },
Type Instances Count Cumulated Self Size (bytes)
string 6703 629389
array 1821 131112
boolean 1185 18960
null 1076 17216
integer 497 7952
Closure 231 16632
Symfony\Component\Console\Input\InputOption 112 8064
Symfony\Component\Console\Input\InputDefinition 83 5976
Illuminate\Routing\Route 68 4896
Symfony\Component\Console\Input\InputArgument 36 2592
unknown 15 240
Symfony\Component\Console\Formatter\OutputFormatterStyle 5 360

Error with analyze dump memory

Hi! Trying to make memory dump:

gc_collect_cycles();
meminfo_dump(fopen('/home/dmitriy/phpmem/my_dump_file.json', 'w'));`

Then run analyzer and receive an error:

$ analyzer/bin/analyzer summary my_dump_file.json

[Symfony\Component\Serializer\Exception\UnexpectedValueException]  
Control character error, possibly incorrectly encoded    
$ ls -al
-rw-rw-r--  1 dmitriy dmitriy 8093889 Ноя 21 15:30 my_dump_file.json

In memory dump I have next item:

    "0x7f31bcb13620" : {
        "type" : "array",
        "size" : "72",
        "is_root" : false
,
        "children" : {
            "1|	":"0x7f31be24dca0"
        }

    }

Why dump create this "1| ":"0x7f31be24dca0" ?
This is not valid json.


Second question:

$ analyzer/bin/analyzer ref-path 0x7f254b257c20 my_dump_file100.json 

Found 2 paths
Path from 0x7f255ce562c0
0x7f254b257c20
      ^       
      |       
_entityManager
      |       
      |       
0x7f254b2d1d40
      ^       
      |       
runningCommand
      |       
      |       
0x7f255ce562c0

Path from 0x7f255ce562e0
0x7f254b257c20
      ^       
      |       
_entityManager
      |       
      |       
0x7f254b2d1d40
      ^       
      |       
runningCommand
      |       
      |       
0x7f255ce562c0
      ^       
      |       
 application  
      |       
      |       
0x7f255ce562e0

It is not, what I see here: https://github.com/BitOne/php-meminfo/blob/master/doc/hunting_down_memory_leaks.md#4-finding-references-to-the-leaked-object

How to understand with this output like you write in your example:

So the reason why our object is still in memory is because it's in an array, that is itself in another array that is in an final array. And the final array is directly linked to the variable declared in the frame and called myRootArray.

I think you need to add parameter -v in example:

$ bin/analyzer ref-path 0x7f94a1877068 /tmp/php_mem_dump.json

Duplication of objects with multiple references on PHP 7

From the following code:

<?php

unset($_GET);
unset($_FILES);
unset($_POST);
unset($_SERVER);
unset($_COOKIE);
unset($argv);
unset($argc);

$a = new StdClass();
$b = $a;

$b->test = "foo";

meminfo_dump(fopen('php://stdout', 'w'));

With PHP7, we get the following wrong result::

"items": {
    "0x7fc8d40571e0" : {
        "type" : "object",
        "size" : "72",
        "symbol_name" : "a",
        "is_root" : true,
        "frame" : "<GLOBAL>",
        "class" : "stdClass",
        "object_handle" : "1",
        "children" : {
            "test":"0x7fc8d405d660"
        }
    },
    "0x7fc8d405d660" : {
        "type" : "string",
        "size" : "19",
        "is_root" : false
    },
    "0x7fc8d4057200" : {
        "type" : "object",
        "size" : "72",
        "symbol_name" : "b",
        "is_root" : true,
        "frame" : "<GLOBAL>",
        "class" : "stdClass",
        "object_handle" : "1",
        "children" : {
            "test":"0x7fc8d405d660"
        }
    }
}

The object with handle 1 is duplicated for each reference.

The result with the PHP 5 version of the extension is correct:

"items": {
    "0x7f69b1095158" : {
        "type" : "object",
        "size" : "56",
        "symbol_name" : "a",
        "is_root" : true,
        "frame" : "<GLOBAL>",
        "class" : "stdClass",
        "object_handle" : "1",
        "children" : {
            "test":"0x7f69b10950f8"
        }
    },
    "0x7f69b10950f8" : {
        "type" : "string",
        "size" : "27",
        "is_root" : false
    }
}

Can't 'make' on php5 folder

The install works perfectly on the php7 folder but when it comes to php5, the make gives a lot of errors :

▲ php5 at master ✖ make
/bin/bash /home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/libtool --mode=compile cc  -I. -I/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5 -DPHP_ATOM_INC -I/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/include -I/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/main -I/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5 -I/usr/include/php/20170718 -I/usr/include/php/20170718/main -I/usr/include/php/20170718/TSRM -I/usr/include/php/20170718/Zend -I/usr/include/php/20170718/ext -I/usr/include/php/20170718/ext/date/lib  -DHAVE_CONFIG_H  -g -O2   -c /home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c -o meminfo.lo 
libtool: compile:  cc -I. -I/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5 -DPHP_ATOM_INC -I/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/include -I/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/main -I/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5 -I/usr/include/php/20170718 -I/usr/include/php/20170718/main -I/usr/include/php/20170718/TSRM -I/usr/include/php/20170718/Zend -I/usr/include/php/20170718/ext -I/usr/include/php/20170718/ext/date/lib -DHAVE_CONFIG_H -g -O2 -c /home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c  -fPIC -DPIC -o .libs/meminfo.o
In file included from /home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:6:0:
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/php_meminfo.h:16:36: error: unknown type name ‘zend_object_handle’
 const char * meminfo_get_classname(zend_object_handle handle TSRMLS_DC);
                                    ^
In file included from /usr/include/php/20170718/main/php.h:465:0,
                 from /home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:5:
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c: In function ‘zif_meminfo_dump’:
/usr/include/php/20170718/main/php_streams.h:263:53: warning: passing argument 1 of ‘zend_fetch_resource2_ex’ from incompatible pointer type [-Wincompatible-pointer-types]
  if (((xstr) = (php_stream*)zend_fetch_resource2_ex((pzval), \
                                                     ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:63:5: note: in expansion of macro ‘php_stream_from_zval’
     php_stream_from_zval(stream, &zval_stream);
     ^
In file included from /usr/include/php/20170718/Zend/zend_API.h:28:0,
                 from /usr/include/php/20170718/main/php.h:40,
                 from /home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:5:
/usr/include/php/20170718/Zend/zend_list.h:66:16: note: expected ‘zval * {aka struct _zval_struct *}’ but argument is of type ‘zval ** {aka struct _zval_struct **}’
 ZEND_API void *zend_fetch_resource2_ex(zval *res, const char *resource_type_name, int resource_type, int resource_ty
                ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:77:37: error: ‘zend_execute_data {aka struct _zend_execute_data}’ has no member named ‘op_array’
     while (exec_frame && !exec_frame->op_array) {
                                     ^
In file included from /usr/include/php/20170718/Zend/zend_globals.h:28:0,
                 from /usr/include/php/20170718/Zend/zend_compile.h:702,
                 from /usr/include/php/20170718/Zend/zend_modules.h:26,
                 from /usr/include/php/20170718/Zend/zend_API.h:27,
                 from /usr/include/php/20170718/main/php.h:40,
                 from /home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:5:
/usr/include/php/20170718/Zend/zend_globals_macros.h:46:33: error: ‘zend_executor_globals {aka struct _zend_executor_globals}’ has no member named ‘active_symbol_table’
 # define EG(v) (executor_globals.v)
                                 ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:88:24: note: in expansion of macro ‘EG’
         symbol_table = EG(active_symbol_table);
                        ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c: At top level:
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:124:36: error: unknown type name ‘zend_object_handle’
 const char * meminfo_get_classname(zend_object_handle handle TSRMLS_DC)
                                    ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c: In function ‘meminfo_browse_zvals_from_symbol_table’:
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:154:56: warning: passing argument 2 of ‘zend_hash_get_current_data_ex’ from incompatible pointer type [-Wincompatible-pointer-types]
     while (zend_hash_get_current_data_ex(symbol_table, (void **) &zval_to_dump, &pos) == SUCCESS) {
                                                        ^
In file included from /usr/include/php/20170718/Zend/zend.h:34:0,
                 from /usr/include/php/20170718/main/php.h:36,
                 from /home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:5:
/usr/include/php/20170718/Zend/zend_hash.h:205:30: note: expected ‘HashPosition * {aka unsigned int *}’ but argument is of type ‘void **’
 ZEND_API zval* ZEND_FASTCALL zend_hash_get_current_data_ex(HashTable *ht, HashPosition *pos);
                              ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:154:12: error: too many arguments to function ‘zend_hash_get_current_data_ex’
     while (zend_hash_get_current_data_ex(symbol_table, (void **) &zval_to_dump, &pos) == SUCCESS) {
            ^
In file included from /usr/include/php/20170718/Zend/zend.h:34:0,
                 from /usr/include/php/20170718/main/php.h:36,
                 from /home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:5:
/usr/include/php/20170718/Zend/zend_hash.h:205:30: note: declared here
 ZEND_API zval* ZEND_FASTCALL zend_hash_get_current_data_ex(HashTable *ht, HashPosition *pos);
                              ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:156:52: warning: passing argument 2 of ‘zend_hash_get_current_key_ex’ from incompatible pointer type [-Wincompatible-pointer-types]
         zend_hash_get_current_key_ex(symbol_table, &key, &key_len, &num_key, 0, &pos);
                                                    ^
In file included from /usr/include/php/20170718/Zend/zend.h:34:0,
                 from /usr/include/php/20170718/main/php.h:36,
                 from /home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:5:
/usr/include/php/20170718/Zend/zend_hash.h:202:30: note: expected ‘zend_string ** {aka struct _zend_string **}’ but argument is of type ‘char **’
 ZEND_API int   ZEND_FASTCALL zend_hash_get_current_key_ex(const HashTable *ht, zend_string **str_index, zend_ulong *
                              ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:156:58: warning: passing argument 3 of ‘zend_hash_get_current_key_ex’ from incompatible pointer type [-Wincompatible-pointer-types]
         zend_hash_get_current_key_ex(symbol_table, &key, &key_len, &num_key, 0, &pos);
                                                          ^
In file included from /usr/include/php/20170718/Zend/zend.h:34:0,
                 from /usr/include/php/20170718/main/php.h:36,
                 from /home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:5:
/usr/include/php/20170718/Zend/zend_hash.h:202:30: note: expected ‘zend_ulong * {aka long unsigned int *}’ but argument is of type ‘uint * {aka unsigned int *}’
 ZEND_API int   ZEND_FASTCALL zend_hash_get_current_key_ex(const HashTable *ht, zend_string **str_index, zend_ulong *
                              ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:156:68: warning: passing argument 4 of ‘zend_hash_get_current_key_ex’ from incompatible pointer type [-Wincompatible-pointer-types]
         zend_hash_get_current_key_ex(symbol_table, &key, &key_len, &num_key, 0, &pos);
                                                                    ^
In file included from /usr/include/php/20170718/Zend/zend.h:34:0,
                 from /usr/include/php/20170718/main/php.h:36,
                 from /home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:5:
/usr/include/php/20170718/Zend/zend_hash.h:202:30: note: expected ‘HashPosition * {aka unsigned int *}’ but argument is of type ‘ulong * {aka long unsigned int *}’
 ZEND_API int   ZEND_FASTCALL zend_hash_get_current_key_ex(const HashTable *ht, zend_string **str_index, zend_ulong *
                              ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:156:9: error: too many arguments to function ‘zend_hash_get_current_key_ex’
         zend_hash_get_current_key_ex(symbol_table, &key, &key_len, &num_key, 0, &pos);
         ^
In file included from /usr/include/php/20170718/Zend/zend.h:34:0,
                 from /usr/include/php/20170718/main/php.h:36,
                 from /home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:5:
/usr/include/php/20170718/Zend/zend_hash.h:202:30: note: declared here
 ZEND_API int   ZEND_FASTCALL zend_hash_get_current_key_ex(const HashTable *ht, zend_string **str_index, zend_ulong *
                              ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c: In function ‘meminfo_visit_item’:
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:170:41: warning: passing argument 2 of ‘zend_hash_exists’ from incompatible pointer type [-Wincompatible-pointer-types]
     if (zend_hash_exists(visited_items, item_label, strlen(item_label))) {
                                         ^
In file included from /usr/include/php/20170718/Zend/zend.h:34:0,
                 from /usr/include/php/20170718/main/php.h:36,
                 from /home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:5:
/usr/include/php/20170718/Zend/zend_hash.h:193:34: note: expected ‘zend_string * {aka struct _zend_string *}’ but argument is of type ‘const char *’
 ZEND_API zend_bool ZEND_FASTCALL zend_hash_exists(const HashTable *ht, zend_string *key);
                                  ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:170:9: error: too many arguments to function ‘zend_hash_exists’
     if (zend_hash_exists(visited_items, item_label, strlen(item_label))) {
         ^
In file included from /usr/include/php/20170718/Zend/zend.h:34:0,
                 from /usr/include/php/20170718/main/php.h:36,
                 from /home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:5:
/usr/include/php/20170718/Zend/zend_hash.h:193:34: note: declared here
 ZEND_API zend_bool ZEND_FASTCALL zend_hash_exists(const HashTable *ht, zend_string *key);
                                  ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:173:98: error: macro "zend_hash_update" passed 6 arguments, but takes just 3
         zend_hash_update(visited_items, item_label, strlen(item_label), &isset, sizeof(int), NULL);
                                                                                                  ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:173:9: error: ‘zend_hash_update’ undeclared (first use in this function)
         zend_hash_update(visited_items, item_label, strlen(item_label), &isset, sizeof(int), NULL);
         ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:173:9: note: each undeclared identifier is reported only once for each function it appears in
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c: In function ‘meminfo_hash_dump’:
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:194:46: warning: passing argument 2 of ‘zend_hash_get_current_data_ex’ from incompatible pointer type [-Wincompatible-pointer-types]
     while (zend_hash_get_current_data_ex(ht, (void **) &zval, &pos) == SUCCESS) {
                                              ^
In file included from /usr/include/php/20170718/Zend/zend.h:34:0,
                 from /usr/include/php/20170718/main/php.h:36,
                 from /home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:5:
/usr/include/php/20170718/Zend/zend_hash.h:205:30: note: expected ‘HashPosition * {aka unsigned int *}’ but argument is of type ‘void **’
 ZEND_API zval* ZEND_FASTCALL zend_hash_get_current_data_ex(HashTable *ht, HashPosition *pos);
                              ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:194:12: error: too many arguments to function ‘zend_hash_get_current_data_ex’
     while (zend_hash_get_current_data_ex(ht, (void **) &zval, &pos) == SUCCESS) {
            ^
In file included from /usr/include/php/20170718/Zend/zend.h:34:0,
                 from /usr/include/php/20170718/main/php.h:36,
                 from /home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:5:
/usr/include/php/20170718/Zend/zend_hash.h:205:30: note: declared here
 ZEND_API zval* ZEND_FASTCALL zend_hash_get_current_data_ex(HashTable *ht, HashPosition *pos);
                              ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:202:50: warning: passing argument 2 of ‘zend_hash_get_current_key_ex’ from incompatible pointer type [-Wincompatible-pointer-types]
         switch (zend_hash_get_current_key_ex(ht, &key, &key_len, &num_key, 0, &pos)) {
                                                  ^
In file included from /usr/include/php/20170718/Zend/zend.h:34:0,
                 from /usr/include/php/20170718/main/php.h:36,
                 from /home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:5:
/usr/include/php/20170718/Zend/zend_hash.h:202:30: note: expected ‘zend_string ** {aka struct _zend_string **}’ but argument is of type ‘char **’
 ZEND_API int   ZEND_FASTCALL zend_hash_get_current_key_ex(const HashTable *ht, zend_string **str_index, zend_ulong *
                              ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:202:56: warning: passing argument 3 of ‘zend_hash_get_current_key_ex’ from incompatible pointer type [-Wincompatible-pointer-types]
         switch (zend_hash_get_current_key_ex(ht, &key, &key_len, &num_key, 0, &pos)) {
                                                        ^
In file included from /usr/include/php/20170718/Zend/zend.h:34:0,
                 from /usr/include/php/20170718/main/php.h:36,
                 from /home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:5:
/usr/include/php/20170718/Zend/zend_hash.h:202:30: note: expected ‘zend_ulong * {aka long unsigned int *}’ but argument is of type ‘uint * {aka unsigned int *}’
 ZEND_API int   ZEND_FASTCALL zend_hash_get_current_key_ex(const HashTable *ht, zend_string **str_index, zend_ulong *
                              ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:202:66: warning: passing argument 4 of ‘zend_hash_get_current_key_ex’ from incompatible pointer type [-Wincompatible-pointer-types]
         switch (zend_hash_get_current_key_ex(ht, &key, &key_len, &num_key, 0, &pos)) {
                                                                  ^
In file included from /usr/include/php/20170718/Zend/zend.h:34:0,
                 from /usr/include/php/20170718/main/php.h:36,
                 from /home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:5:
/usr/include/php/20170718/Zend/zend_hash.h:202:30: note: expected ‘HashPosition * {aka unsigned int *}’ but argument is of type ‘ulong * {aka long unsigned int *}’
 ZEND_API int   ZEND_FASTCALL zend_hash_get_current_key_ex(const HashTable *ht, zend_string **str_index, zend_ulong *
                              ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:202:17: error: too many arguments to function ‘zend_hash_get_current_key_ex’
         switch (zend_hash_get_current_key_ex(ht, &key, &key_len, &num_key, 0, &pos)) {
                 ^
In file included from /usr/include/php/20170718/Zend/zend.h:34:0,
                 from /usr/include/php/20170718/main/php.h:36,
                 from /home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:5:
/usr/include/php/20170718/Zend/zend_hash.h:202:30: note: declared here
 ZEND_API int   ZEND_FASTCALL zend_hash_get_current_key_ex(const HashTable *ht, zend_string **str_index, zend_ulong *
                              ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:207:94: error: macro "zend_unmangle_property_name" passed 4 arguments, but takes just 3
                     zend_unmangle_property_name(key, key_len - 1, &class_name, &property_name);
                                                                                              ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:207:21: error: ‘zend_unmangle_property_name’ undeclared (first use in this function)
                     zend_unmangle_property_name(key, key_len - 1, &class_name, &property_name);
                     ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:228:46: warning: passing argument 2 of ‘zend_hash_get_current_data_ex’ from incompatible pointer type [-Wincompatible-pointer-types]
     while (zend_hash_get_current_data_ex(ht, (void **) &zval, &pos) == SUCCESS) {
                                              ^
In file included from /usr/include/php/20170718/Zend/zend.h:34:0,
                 from /usr/include/php/20170718/main/php.h:36,
                 from /home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:5:
/usr/include/php/20170718/Zend/zend_hash.h:205:30: note: expected ‘HashPosition * {aka unsigned int *}’ but argument is of type ‘void **’
 ZEND_API zval* ZEND_FASTCALL zend_hash_get_current_data_ex(HashTable *ht, HashPosition *pos);
                              ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:228:12: error: too many arguments to function ‘zend_hash_get_current_data_ex’
     while (zend_hash_get_current_data_ex(ht, (void **) &zval, &pos) == SUCCESS) {
            ^
In file included from /usr/include/php/20170718/Zend/zend.h:34:0,
                 from /usr/include/php/20170718/main/php.h:36,
                 from /home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:5:
/usr/include/php/20170718/Zend/zend_hash.h:205:30: note: declared here
 ZEND_API zval* ZEND_FASTCALL zend_hash_get_current_data_ex(HashTable *ht, HashPosition *pos);
                              ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c: In function ‘meminfo_zval_dump’:
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:276:44: warning: implicit declaration of function ‘meminfo_get_classname’ [-Wimplicit-function-declaration]
         char_buf = meminfo_escape_for_json(meminfo_get_classname(zv->value.obj.handle TSRMLS_CC) TSRMLS_CC);
                                            ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:276:79: error: request for member ‘handle’ in something not a structure or union
         char_buf = meminfo_escape_for_json(meminfo_get_classname(zv->value.obj.handle TSRMLS_CC) TSRMLS_CC);
                                                                               ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:279:99: error: request for member ‘handle’ in something not a structure or union
         php_stream_printf(stream TSRMLS_CC, "        \"object_handle\" : \"%d\",\n", zv->value.obj.handle);
                                                                                                   ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:293:44: error: ‘zend_value {aka union _zend_value}’ has no member named ‘ht’
         meminfo_hash_dump(stream, zv->value.ht, 0, visited_items, first_element TSRMLS_CC);
                                            ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c: In function ‘meminfo_get_element_size’:
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:314:34: error: request for member ‘len’ in something not a structure or union
             size += zv->value.str.len;
                                  ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c: In function ‘meminfo_build_frame_label’:
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:340:27: error: ‘zend_execute_data {aka struct _zend_execute_data}’ has no member named ‘function_state’
     function_name = (frame->function_state.function->common.scope &&
                           ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:341:14: error: ‘zend_execute_data {aka struct _zend_execute_data}’ has no member named ‘function_state’
         frame->function_state.function->common.scope->trait_aliases) ?
              ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:343:26: error: ‘zend_execute_data {aka struct _zend_execute_data}’ has no member named ‘object’
                     frame->object ?
                          ^
In file included from /usr/include/php/20170718/Zend/zend.h:29:0,
                 from /usr/include/php/20170718/main/php.h:36,
                 from /home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:5:
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:344:40: error: ‘zend_execute_data {aka struct _zend_execute_data}’ has no member named ‘object’
                         Z_OBJCE_P(frame->object) :
                                        ^
/usr/include/php/20170718/Zend/zend_types.h:596:26: note: in definition of macro ‘Z_OBJ’
 #define Z_OBJ(zval)     (zval).value.obj
                          ^
/usr/include/php/20170718/Zend/zend_types.h:609:29: note: in expansion of macro ‘Z_OBJCE’
 #define Z_OBJCE_P(zval_p)   Z_OBJCE(*(zval_p))
                             ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:344:25: note: in expansion of macro ‘Z_OBJCE_P’
                         Z_OBJCE_P(frame->object) :
                         ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:345:30: error: ‘zend_execute_data {aka struct _zend_execute_data}’ has no member named ‘function_state’
                         frame->function_state.function->common.scope,
                              ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:346:26: error: ‘zend_execute_data {aka struct _zend_execute_data}’ has no member named ‘function_state’
                     frame->function_state.function) :
                          ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:347:22: error: ‘zend_execute_data {aka struct _zend_execute_data}’ has no member named ‘function_state’
                 frame->function_state.function->common.function_name;
                      ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:350:18: error: ‘zend_execute_data {aka struct _zend_execute_data}’ has no member named ‘object’
         if (frame->object) {
                  ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:351:22: error: ‘zend_execute_data {aka struct _zend_execute_data}’ has no member named ‘function_state’
             if (frame->function_state.function->common.scope) {
                      ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:352:35: error: ‘zend_execute_data {aka struct _zend_execute_data}’ has no member named ‘function_state’
                 class_name = frame->function_state.function->common.scope->name;
                                   ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:354:17: error: unknown type name ‘zend_uint’
                 zend_uint class_name_len;
                 ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:357:23: warning: implicit declaration of function ‘zend_get_object_classname’ [-Wimplicit-function-declaration]
                 dup = zend_get_object_classname(frame->object, &class_name, &class_name_len TSRMLS_CC);
                       ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:357:54: error: ‘zend_execute_data {aka struct _zend_execute_data}’ has no member named ‘object’
                 dup = zend_get_object_classname(frame->object, &class_name, &class_name_len TSRMLS_CC);
                                                      ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:364:25: error: ‘zend_execute_data {aka struct _zend_execute_data}’ has no member named ‘function_state’
         } else if (frame->function_state.function->common.scope) {
                         ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:365:31: error: ‘zend_execute_data {aka struct _zend_execute_data}’ has no member named ‘function_state’
             class_name = frame->function_state.function->common.scope->name;
                               ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c: In function ‘meminfo_escape_for_json’:
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:428:10: error: too many arguments to function ‘php_str_to_str’
     s1 = php_str_to_str((char *) s, strlen(s), "\\", 1, "\\\\", 2, &new_str_len);
          ^
In file included from /home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:9:0:
/usr/include/php/20170718/ext/standard/php_string.h:135:21: note: declared here
 PHPAPI zend_string *php_str_to_str(char *haystack, size_t length, char *needle,
                     ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:428:8: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
     s1 = php_str_to_str((char *) s, strlen(s), "\\", 1, "\\\\", 2, &new_str_len);
        ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:429:10: error: too many arguments to function ‘php_str_to_str’
     s2 = php_str_to_str(s1, strlen(s1), "\"", 1, "\\\"", 2, &new_str_len);
          ^
In file included from /home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:9:0:
/usr/include/php/20170718/ext/standard/php_string.h:135:21: note: declared here
 PHPAPI zend_string *php_str_to_str(char *haystack, size_t length, char *needle,
                     ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:429:8: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
     s2 = php_str_to_str(s1, strlen(s1), "\"", 1, "\\\"", 2, &new_str_len);
        ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:437:14: error: too many arguments to function ‘php_str_to_str’
         s3 = php_str_to_str(s2, strlen(s2), unescaped_char, 1, escaped_char, 6, &new_str_len);
              ^
In file included from /home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:9:0:
/usr/include/php/20170718/ext/standard/php_string.h:135:21: note: declared here
 PHPAPI zend_string *php_str_to_str(char *haystack, size_t length, char *needle,
                     ^
/home/dnd-von/Datas/projects/aelpim-mev/php-meminfo/extension/php5/meminfo.c:437:12: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
         s3 = php_str_to_str(s2, strlen(s2), unescaped_char, 1, escaped_char, 6, &new_str_len);
            ^
Makefile:193: recipe for target 'meminfo.lo' failed
make: *** [meminfo.lo] Error 1

And I have no idea how to fix this :/

The ./configure --enable-meminfo command works fine btw

[php7] Fail on struct_size_64bits.phpt

Hi,
I compiled the php-meminfo ext on my MacOS and GNU/Linux system and I have this fail on struct_size_64bits.phpt test :

$ ./tests/struct_size_64bits.sh 
Simple Zend Type size on this platform
  Zend Signed Integer (zend_long): 8 bytes.
  Zend Unsigned Integer (zend_ulong): 8 bytes.
  Zend Unsigned Char (zend_uchar): 1 bytes.
Structs size on this platform:
  Variable (zval): 16 bytes.
  Class (zend_class_entry): 504 bytes.
  Object (zend_object): 56 bytes.
$ php -v
PHP 7.1.7 (cli) (built: Jul 27 2017 23:05:35) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies

$ uname -a
Darwin Francis 14.5.0 Darwin Kernel Version 14.5.0: Sun Sep 25 22:07:15 PDT 2016; root:xnu-2782.50.9~1/RELEASE_X86_64 x86_64

Extension does not compile on Mac

Here's the output I get for make:

/bin/sh /Users/kix/Documents/Code/php/php-meminfo/extension/libtool --mode=compile cc  -I. -I/Users/kix/Documents/Code/php/php-meminfo/extension -DPHP_ATOM_INC -I/Users/kix/Documents/Code/php/php-meminfo/extension/include -I/Users/kix/Documents/Code/php/php-meminfo/extension/main -I/Users/kix/Documents/Code/php/php-meminfo/extension -I/usr/local/Cellar/php56/5.6.17/include/php -I/usr/local/Cellar/php56/5.6.17/include/php/main -I/usr/local/Cellar/php56/5.6.17/include/php/TSRM -I/usr/local/Cellar/php56/5.6.17/include/php/Zend -I/usr/local/Cellar/php56/5.6.17/include/php/ext -I/usr/local/Cellar/php56/5.6.17/include/php/ext/date/lib  -DHAVE_CONFIG_H  -g -O2   -c /Users/kix/Documents/Code/php/php-meminfo/extension/meminfo.c -o meminfo.lo
 cc -I. -I/Users/kix/Documents/Code/php/php-meminfo/extension -DPHP_ATOM_INC -I/Users/kix/Documents/Code/php/php-meminfo/extension/include -I/Users/kix/Documents/Code/php/php-meminfo/extension/main -I/Users/kix/Documents/Code/php/php-meminfo/extension -I/usr/local/Cellar/php56/5.6.17/include/php -I/usr/local/Cellar/php56/5.6.17/include/php/main -I/usr/local/Cellar/php56/5.6.17/include/php/TSRM -I/usr/local/Cellar/php56/5.6.17/include/php/Zend -I/usr/local/Cellar/php56/5.6.17/include/php/ext -I/usr/local/Cellar/php56/5.6.17/include/php/ext/date/lib -DHAVE_CONFIG_H -g -O2 -c /Users/kix/Documents/Code/php/php-meminfo/extension/meminfo.c  -fno-common -DPIC -o .libs/meminfo.o
/Users/kix/Documents/Code/php/php-meminfo/extension/meminfo.c:241:41: warning: format string is not a string literal (potentially insecure) [-Wformat-security]
    php_stream_printf(stream TSRMLS_CC, meminfo_info_dump_header(header, sizeof(header)));
                                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/kix/Documents/Code/php/php-meminfo/extension/meminfo.c:261:35: error: too few arguments to function call, single argument 'tsrm_ls' was not specified
        zend_rebuild_symbol_table();
        ~~~~~~~~~~~~~~~~~~~~~~~~~ ^
/usr/local/Cellar/php56/5.6.17/include/php/Zend/zend_API.h:525:1: note: 'zend_rebuild_symbol_table' declared here
ZEND_API void zend_rebuild_symbol_table(TSRMLS_D);
^
/usr/local/Cellar/php56/5.6.17/include/php/main/php_config.h:6:19: note: expanded from macro 'ZEND_API'
# define ZEND_API __attribute__ ((visibility("default")))
                  ^
/Users/kix/Documents/Code/php/php-meminfo/extension/meminfo.c:276:31: error: too few arguments to function call, single argument 'tsrm_ls' was not specified
    zend_rebuild_symbol_table();
    ~~~~~~~~~~~~~~~~~~~~~~~~~ ^
/usr/local/Cellar/php56/5.6.17/include/php/Zend/zend_API.h:525:1: note: 'zend_rebuild_symbol_table' declared here
ZEND_API void zend_rebuild_symbol_table(TSRMLS_D);
^
/usr/local/Cellar/php56/5.6.17/include/php/main/php_config.h:6:19: note: expanded from macro 'ZEND_API'
# define ZEND_API __attribute__ ((visibility("default")))
                  ^
/Users/kix/Documents/Code/php/php-meminfo/extension/meminfo.c:327:36: error: use of undeclared identifier 'tsrm_ls'
    zend_objects_store *objects = &EG(objects_store);
                                   ^
/usr/local/Cellar/php56/5.6.17/include/php/Zend/zend_globals_macros.h:45:16: note: expanded from macro 'EG'
# define EG(v) TSRMG(executor_globals_id, zend_executor_globals *, v)
               ^
/usr/local/Cellar/php56/5.6.17/include/php/TSRM/TSRM.h:164:57: note: expanded from macro 'TSRMG'
#define TSRMG(id, type, element)        (((type) (*((void ***) tsrm_ls))[TSRM_UNSHUFFLE_RSRC_ID(id)])->element)
                                                               ^
/Users/kix/Documents/Code/php/php-meminfo/extension/meminfo.c:392:30: error: use of undeclared identifier 'tsrm_ls'
    php_stream_printf(stream TSRMLS_CC, "        \"children\" : {\n");
                             ^
/usr/local/Cellar/php56/5.6.17/include/php/TSRM/TSRM.h:168:21: note: expanded from macro 'TSRMLS_CC'
#define TSRMLS_CC       , TSRMLS_C
                          ^
/usr/local/Cellar/php56/5.6.17/include/php/TSRM/TSRM.h:167:18: note: expanded from macro 'TSRMLS_C'
#define TSRMLS_C        tsrm_ls
                        ^
/Users/kix/Documents/Code/php/php-meminfo/extension/meminfo.c:398:38: error: use of undeclared identifier 'tsrm_ls'
            php_stream_printf(stream TSRMLS_CC, ",\n");
                                     ^
/usr/local/Cellar/php56/5.6.17/include/php/TSRM/TSRM.h:168:21: note: expanded from macro 'TSRMLS_CC'
#define TSRMLS_CC       , TSRMLS_C
                          ^
/usr/local/Cellar/php56/5.6.17/include/php/TSRM/TSRM.h:167:18: note: expanded from macro 'TSRMLS_C'
#define TSRMLS_C        tsrm_ls
                        ^
/Users/kix/Documents/Code/php/php-meminfo/extension/meminfo.c:410:46: error: use of undeclared identifier 'tsrm_ls'
                    php_stream_printf(stream TSRMLS_CC, "            \"%s\":\"%p\"", meminfo_escape_for_json(property_name), *zval );
                                             ^
/usr/local/Cellar/php56/5.6.17/include/php/TSRM/TSRM.h:168:21: note: expanded from macro 'TSRMLS_CC'
#define TSRMLS_CC       , TSRMLS_C
                          ^
/usr/local/Cellar/php56/5.6.17/include/php/TSRM/TSRM.h:167:18: note: expanded from macro 'TSRMLS_C'
#define TSRMLS_C        tsrm_ls
                        ^
/Users/kix/Documents/Code/php/php-meminfo/extension/meminfo.c:412:46: error: use of undeclared identifier 'tsrm_ls'
                    php_stream_printf(stream TSRMLS_CC, "            \"%s\":\"%p\"", meminfo_escape_for_json(key), *zval );
                                             ^
/usr/local/Cellar/php56/5.6.17/include/php/TSRM/TSRM.h:168:21: note: expanded from macro 'TSRMLS_CC'
#define TSRMLS_CC       , TSRMLS_C
                          ^
/usr/local/Cellar/php56/5.6.17/include/php/TSRM/TSRM.h:167:18: note: expanded from macro 'TSRMLS_C'
#define TSRMLS_C        tsrm_ls
                        ^
/Users/kix/Documents/Code/php/php-meminfo/extension/meminfo.c:417:42: error: use of undeclared identifier 'tsrm_ls'
                php_stream_printf(stream TSRMLS_CC, "            \"%ld\":\"%p\"", num_key, *zval );
                                         ^
/usr/local/Cellar/php56/5.6.17/include/php/TSRM/TSRM.h:168:21: note: expanded from macro 'TSRMLS_CC'
#define TSRMLS_CC       , TSRMLS_C
                          ^
/usr/local/Cellar/php56/5.6.17/include/php/TSRM/TSRM.h:167:18: note: expanded from macro 'TSRMLS_C'
#define TSRMLS_C        tsrm_ls
                        ^
/Users/kix/Documents/Code/php/php-meminfo/extension/meminfo.c:423:30: error: use of undeclared identifier 'tsrm_ls'
    php_stream_printf(stream TSRMLS_CC, "\n        }\n");
                             ^
/usr/local/Cellar/php56/5.6.17/include/php/TSRM/TSRM.h:168:21: note: expanded from macro 'TSRMLS_CC'
#define TSRMLS_CC       , TSRMLS_C
                          ^
/usr/local/Cellar/php56/5.6.17/include/php/TSRM/TSRM.h:167:18: note: expanded from macro 'TSRMLS_C'
#define TSRMLS_C        tsrm_ls
                        ^
/Users/kix/Documents/Code/php/php-meminfo/extension/meminfo.c:442:34: error: use of undeclared identifier 'tsrm_ls'
        php_stream_printf(stream TSRMLS_CC, "\n    },\n");
                                 ^
/usr/local/Cellar/php56/5.6.17/include/php/TSRM/TSRM.h:168:21: note: expanded from macro 'TSRMLS_CC'
#define TSRMLS_CC       , TSRMLS_C
                          ^
/usr/local/Cellar/php56/5.6.17/include/php/TSRM/TSRM.h:167:18: note: expanded from macro 'TSRMLS_C'
#define TSRMLS_C        tsrm_ls
                        ^
/Users/kix/Documents/Code/php/php-meminfo/extension/meminfo.c:447:30: error: use of undeclared identifier 'tsrm_ls'
    php_stream_printf(stream TSRMLS_CC, "    \"%s\" : {\n", zval_id);
                             ^
/usr/local/Cellar/php56/5.6.17/include/php/TSRM/TSRM.h:168:21: note: expanded from macro 'TSRMLS_CC'
#define TSRMLS_CC       , TSRMLS_C
                          ^
/usr/local/Cellar/php56/5.6.17/include/php/TSRM/TSRM.h:167:18: note: expanded from macro 'TSRMLS_C'
#define TSRMLS_C        tsrm_ls
                        ^
/Users/kix/Documents/Code/php/php-meminfo/extension/meminfo.c:448:30: error: use of undeclared identifier 'tsrm_ls'
    php_stream_printf(stream TSRMLS_CC, "        \"type\" : \"%s\",\n", zend_get_type_by_const(Z_TYPE_P(zv)));
                             ^
/usr/local/Cellar/php56/5.6.17/include/php/TSRM/TSRM.h:168:21: note: expanded from macro 'TSRMLS_CC'
#define TSRMLS_CC       , TSRMLS_C
                          ^
/usr/local/Cellar/php56/5.6.17/include/php/TSRM/TSRM.h:167:18: note: expanded from macro 'TSRMLS_C'
#define TSRMLS_C        tsrm_ls
                        ^
/Users/kix/Documents/Code/php/php-meminfo/extension/meminfo.c:449:30: error: use of undeclared identifier 'tsrm_ls'
    php_stream_printf(stream TSRMLS_CC, "        \"size\" : \"%ld\",\n", meminfo_get_element_size(zv));
                             ^
/usr/local/Cellar/php56/5.6.17/include/php/TSRM/TSRM.h:168:21: note: expanded from macro 'TSRMLS_CC'
#define TSRMLS_CC       , TSRMLS_C
                          ^
/usr/local/Cellar/php56/5.6.17/include/php/TSRM/TSRM.h:167:18: note: expanded from macro 'TSRMLS_C'
#define TSRMLS_C        tsrm_ls
                        ^
/Users/kix/Documents/Code/php/php-meminfo/extension/meminfo.c:453:38: error: use of undeclared identifier 'tsrm_ls'
            php_stream_printf(stream TSRMLS_CC, "        \"symbol_name\" : \"%s\",\n", meminfo_escape_for_json(symbol_name));
                                     ^
/usr/local/Cellar/php56/5.6.17/include/php/TSRM/TSRM.h:168:21: note: expanded from macro 'TSRMLS_CC'
#define TSRMLS_CC       , TSRMLS_C
                          ^
/usr/local/Cellar/php56/5.6.17/include/php/TSRM/TSRM.h:167:18: note: expanded from macro 'TSRMLS_C'
#define TSRMLS_C        tsrm_ls
                        ^
/Users/kix/Documents/Code/php/php-meminfo/extension/meminfo.c:455:34: error: use of undeclared identifier 'tsrm_ls'
        php_stream_printf(stream TSRMLS_CC, "        \"is_root\" : true,\n");
                                 ^
/usr/local/Cellar/php56/5.6.17/include/php/TSRM/TSRM.h:168:21: note: expanded from macro 'TSRMLS_CC'
#define TSRMLS_CC       , TSRMLS_C
                          ^
/usr/local/Cellar/php56/5.6.17/include/php/TSRM/TSRM.h:167:18: note: expanded from macro 'TSRMLS_C'
#define TSRMLS_C        tsrm_ls
                        ^
/Users/kix/Documents/Code/php/php-meminfo/extension/meminfo.c:456:34: error: use of undeclared identifier 'tsrm_ls'
        php_stream_printf(stream TSRMLS_CC, "        \"frame\" : \"%s\"\n", meminfo_escape_for_json(frame_label));
                                 ^
/usr/local/Cellar/php56/5.6.17/include/php/TSRM/TSRM.h:168:21: note: expanded from macro 'TSRMLS_CC'
#define TSRMLS_CC       , TSRMLS_C
                          ^
/usr/local/Cellar/php56/5.6.17/include/php/TSRM/TSRM.h:167:18: note: expanded from macro 'TSRMLS_C'
#define TSRMLS_C        tsrm_ls
                        ^
/Users/kix/Documents/Code/php/php-meminfo/extension/meminfo.c:458:34: error: use of undeclared identifier 'tsrm_ls'
        php_stream_printf(stream TSRMLS_CC, "        \"is_root\" : false\n");
                                 ^
/usr/local/Cellar/php56/5.6.17/include/php/TSRM/TSRM.h:168:21: note: expanded from macro 'TSRMLS_CC'
#define TSRMLS_CC       , TSRMLS_C
                          ^
/usr/local/Cellar/php56/5.6.17/include/php/TSRM/TSRM.h:167:18: note: expanded from macro 'TSRMLS_C'
#define TSRMLS_C        tsrm_ls
                        ^
/Users/kix/Documents/Code/php/php-meminfo/extension/meminfo.c:468:34: error: use of undeclared identifier 'tsrm_ls'
        php_stream_printf(stream TSRMLS_CC, ",\n");
                                 ^
/usr/local/Cellar/php56/5.6.17/include/php/TSRM/TSRM.h:168:21: note: expanded from macro 'TSRMLS_CC'
#define TSRMLS_CC       , TSRMLS_C
                          ^
/usr/local/Cellar/php56/5.6.17/include/php/TSRM/TSRM.h:167:18: note: expanded from macro 'TSRMLS_C'
#define TSRMLS_C        tsrm_ls
                        ^
/Users/kix/Documents/Code/php/php-meminfo/extension/meminfo.c:469:34: error: use of undeclared identifier 'tsrm_ls'
        php_stream_printf(stream TSRMLS_CC, "        \"class\" : \"%s\",\n", meminfo_escape_for_json(meminfo_get_classname(zv->value.obj.handle)));
                                 ^
/usr/local/Cellar/php56/5.6.17/include/php/TSRM/TSRM.h:168:21: note: expanded from macro 'TSRMLS_CC'
#define TSRMLS_CC       , TSRMLS_C
                          ^
/usr/local/Cellar/php56/5.6.17/include/php/TSRM/TSRM.h:167:18: note: expanded from macro 'TSRMLS_C'
#define TSRMLS_C        tsrm_ls
                        ^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
1 warning and 20 errors generated.
make: *** [meminfo.lo] Error 1

PHPStorm stub

FYI I've made a PR to add ext-meminfo to PHPStorm's stubs: JetBrains/phpstorm-stubs#593 As far as I can tell the signature of the method is correct (from what I could decipher from C), could you double check that if you have time?

meminfo_objects_summary() undefined

Hi! I'm trying to fix some script using this extension and referenced presentation. There is meminfo_objects_summary() function used on one of slides, but it seems there is no such function on my installation:

$ php -v
PHP 5.6.20 (cli) (built: Mar 31 2016 07:24:47) 
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
    with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2016, by Zend Technologies
    with Xdebug v2.3.3, Copyright (c) 2002-2015, by Derick Rethans

$ php -i | grep meminfo
/etc/php.d/meminfo.ini
meminfo

$ php -r '$funcs = get_defined_functions()["internal"]; $filtered = array_filter($funcs, function($name){return false !== strpos($name, "meminfo");}); var_dump($filtered);'
array(1) {
  [1963]=>
  string(12) "meminfo_dump"
}

What I'm doing wrong?

Invalid JSON for FFI objects

If FFI objects are dumped, invalid JSON is generated, note the trailing comma after "2329":

    "0x7f0c227017c0" : {
        "type" : "object",
        "size" : "72",
        "symbol_name" : "Amp\\Http\\Internal\\HPackNghttp2::deflatePtrType",
        "is_root" : true,
        "frame" : "<CLASS_STATIC_MEMBER>"
,
        "class" : "FFI\\CType",
        "object_handle" : "2329",

    },

meminfo_escape_for_json memory leak

Hello,

char * meminfo_escape_for_json(const char *s)
{
    int new_str_len;
    char *s1;

    s1 = php_str_to_str(s, strlen(s), "\\", 1, "\\\\", 2, &new_str_len);

    return  php_str_to_str(s1, strlen(s1), "\"", 1, "\\\"", 2, &new_str_len);
}

php_str_to_str allocates a new char * in memory that doesn't clear after.

pls see my tests that determine this problem:
#27

and my solution to it
#28

Thanks.

[php7] Fail on objects_summary.phpt

Hi,
I compiled the php-meminfo ext on my MacOS system and I have this fail on objects_summary.phpt test.

PS : The test works fine on my GNU/Linux system.

$ ./tests/objects_summary.sh 
Instances count by class:
rank         #instances   class
-----------------------------------------------------------------
$ php -v
PHP 7.1.7 (cli) (built: Jul 27 2017 23:05:35) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies

$ uname -a
Darwin Francis 14.5.0 Darwin Kernel Version 14.5.0: Sun Sep 25 22:07:15 PDT 2016; root:xnu-2782.50.9~1/RELEASE_X86_64 x86_64

PHP 7.3 support

Any php 7.3 support incoming? Switched to 7.3 and cant use meminfo from now.

meminfo_objects_summary VS meminfo_info_dump

Hello,

I’m probably missing something, but I'm in a case in which meminfo_objects_summary output shows many objects that I cannot find in meminfo_info_dump dump.

Here are my 5 first meminfo_objects_summary dump lines:

Instances count by class:
rank #instances class
-----------------------------------------------------------------
1 9288 DateTime
2 5957 AppBundle\Model\ProductOfferFeedImportExtractedProductOffer
3 5957 AppBundle\Model\ProductOffer
4 208 Symfony\Component\Console\Input\InputOption
5 107 Symfony\Component\Console\Input\InputDefinition

And when querying the meminfo_info_dump dump, no such item found:
devuser@osboxes:~/meminfo/php-meminfo/analyzer$ bin/analyzer query -f "class~ProductOfferFeedImportExtractedProductOffer" -v data/mem_dump_0.json
+----------+-----------+----------+
| Item ids | Item data | Children |
+----------+-----------+----------+

In addition: my meminfo_info_dump dump size is only 1,2M, and it should be really more...

Am I missing somthing obvious of how meminfo works ?

In objects list, display a configured property of the object

In a lot of cases, providing the object list with only the class name is not sufficient. Identifying a specific instance could be needed.

Even if there's no standard object identifier in PHP, standard conventions and the usage of tools like ORM pushes the use of common object property (for example id) to uniquely identify the objects.

By providing an optional object property name to meminfo_objects_list, we can display this property and identify the objects.

Create new tag

Hello,

First of all, thanks for this tool.

To simplify installation for Mac users, I create an homebrew (MacOS package manager) formula.

I notice, that there is some differences beetween the last tag (v0.3.0) and the master. Is it possible to create a new tag to allow Mac users to retrieve a recent version of this extension ?

Thanks.

Make fails on PHP 7.3 in Linux

When I follow the README instructions as such:

$ git clone ...
$ cd php-meminfo/extension/php7
$ phpize
$ make

On Ubuntu 18.04 I receive errors as such:

/bin/bash /home/ojrask/tmp/meminfo/php-meminfo/extension/php7/libtool --mode=compile cc  -I. -I/home/ojrask/tmp/meminfo/php-meminfo/extension/php7 -DPHP_ATOM_INC -I/home/ojrask/tmp/meminfo/php-meminfo/extension/php7/include -I/home/ojrask/tmp/meminfo/php-meminfo/extension/php7/main -I/home/ojrask/tmp/meminfo/php-meminfo/extension/php7 -I/usr/include/php/20190529 -I/usr/include/php/20190529/main -I/usr/include/php/20190529/TSRM -I/usr/include/php/20190529/Zend -I/usr/include/php/20190529/ext -I/usr/include/php/20190529/ext/date/lib  -DHAVE_CONFIG_H  -g -O2   -c /home/ojrask/tmp/meminfo/php-meminfo/extension/php7/meminfo.c -o meminfo.lo
mkdir .libs
 cc -I. -I/home/ojrask/tmp/meminfo/php-meminfo/extension/php7 -DPHP_ATOM_INC -I/home/ojrask/tmp/meminfo/php-meminfo/extension/php7/include -I/home/ojrask/tmp/meminfo/php-meminfo/extension/php7/main -I/home/ojrask/tmp/meminfo/php-meminfo/extension/php7 -I/usr/include/php/20190529 -I/usr/include/php/20190529/main -I/usr/include/php/20190529/TSRM -I/usr/include/php/20190529/Zend -I/usr/include/php/20190529/ext -I/usr/include/php/20190529/ext/date/lib -DHAVE_CONFIG_H -g -O2 -c /home/ojrask/tmp/meminfo/php-meminfo/extension/php7/meminfo.c  -fPIC -DPIC -o .libs/meminfo.o
/home/ojrask/tmp/meminfo/php-meminfo/extension/php7/meminfo.c: In function ‘zif_meminfo_dump’:
/home/ojrask/tmp/meminfo/php-meminfo/extension/php7/meminfo.c:61:66: warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘size_t {aka long unsigned int}’ [-Wformat=]
     php_stream_printf(stream TSRMLS_CC, "    \"memory_usage\" : %d,\n", zend_memory_usage(0));
                                                                 ~^      ~~~~~~~~~~~~~~~~~~~~
                                                                 %ld
/home/ojrask/tmp/meminfo/php-meminfo/extension/php7/meminfo.c:62:71: warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘size_t {aka long unsigned int}’ [-Wformat=]
     php_stream_printf(stream TSRMLS_CC, "    \"memory_usage_real\" : %d,\n", zend_memory_usage(1));
                                                                      ~^      ~~~~~~~~~~~~~~~~~~~~
                                                                      %ld
/home/ojrask/tmp/meminfo/php-meminfo/extension/php7/meminfo.c:63:71: warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘size_t {aka long unsigned int}’ [-Wformat=]
     php_stream_printf(stream TSRMLS_CC, "    \"peak_memory_usage\" : %d,\n", zend_memory_peak_usage(0));
                                                                      ~^      ~~~~~~~~~~~~~~~~~~~~~~~~~
                                                                      %ld
/home/ojrask/tmp/meminfo/php-meminfo/extension/php7/meminfo.c:64:76: warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘size_t {aka long unsigned int}’ [-Wformat=]
     php_stream_printf(stream TSRMLS_CC, "    \"peak_memory_usage_real\" : %d\n", zend_memory_peak_usage(1));
                                                                           ~^     ~~~~~~~~~~~~~~~~~~~~~~~~~
                                                                           %ld
/home/ojrask/tmp/meminfo/php-meminfo/extension/php7/meminfo.c: In function ‘meminfo_browse_class_static_members’:
/home/ojrask/tmp/meminfo/php-meminfo/extension/php7/meminfo.c:135:26: error: ‘zend_class_entry {aka struct _zend_class_entry}’ has no member named ‘static_members_table’; did you mean ‘static_members_table__ptr’?
         if (class_entry->static_members_table) {
                          ^~~~~~~~~~~~~~~~~~~~
                          static_members_table__ptr
/home/ojrask/tmp/meminfo/php-meminfo/extension/php7/meminfo.c:145:42: error: ‘zend_class_entry {aka struct _zend_class_entry}’ has no member named ‘static_members_table’; did you mean ‘static_members_table__ptr’?
                     prop = &class_entry->static_members_table[prop_info->offset];
                                          ^~~~~~~~~~~~~~~~~~~~
                                          static_members_table__ptr
/home/ojrask/tmp/meminfo/php-meminfo/extension/php7/meminfo.c: In function ‘meminfo_zval_dump’:
/home/ojrask/tmp/meminfo/php-meminfo/extension/php7/meminfo.c:358:22: warning: implicit declaration of function ‘Z_OBJDEBUG_P’; did you mean ‘Z_OBJCE_P’? [-Wimplicit-function-declaration]
         properties = Z_OBJDEBUG_P(zv, is_temp);
                      ^~~~~~~~~~~~
                      Z_OBJCE_P
/home/ojrask/tmp/meminfo/php-meminfo/extension/php7/meminfo.c:358:20: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
         properties = Z_OBJDEBUG_P(zv, is_temp);
                    ^
Makefile:191: recipe for target 'meminfo.lo' failed
make: *** [meminfo.lo] Error 1

And on a dockerized CentOS/RHEL environment the same procedure fails with errors similar to the following:

In file included from /opt/php-meminfo-master/extension/php7/meminfo.c:6:0:                                                                                                                                                      
/opt/php-meminfo-master/extension/php7/php_meminfo.h:21:65: error: unknown type name 'zend_string'                                                                                                                               
 void meminfo_zval_dump(php_stream * stream, char * frame_label, zend_string * symbol_name, zval * zv, HashTable *visited_items, int *first_element);                                                                                         
                                                                 ^                                                                                                                                                                            
In file included from /opt/php-meminfo-master/extension/php7/meminfo.c:6:0:                                                                                                                                                      
/opt/php-meminfo-master/extension/php7/php_meminfo.h:29:1: error: unknown type name 'zend_string'                                                                                                                                
 zend_string * meminfo_escape_for_json(const char *s);                                                                                                                                                                                        
 ^                                                                                                                                                                                                                                            
/opt/php-meminfo-master/extension/php7/meminfo.c: In function 'zif_meminfo_dump':                                                                                                                                                
/opt/php-meminfo-master/extension/php7/meminfo.c:57:5: warning: passing argument 1 of 'zend_fetch_resource' from incompatible pointer type [enabled by default]                                                                  
     php_stream_from_zval(stream, zval_stream);                                                                                                                                                                                               
     ^                                                                                                                                                                                                                                        
In file included from /usr/include/php/Zend/zend_API.h:27:0,                                                                                                                                                                                  
                 from /usr/include/php/main/php.h:38,                                                                                                                                                                                         
                 from /opt/php-meminfo-master/extension/php7/meminfo.c:5:                                                                                                                                                        
/usr/include/php/Zend/zend_list.h:83:16: note: expected 'struct zval **' but argument is of type 'struct zval *'                                                                                                                              
 ZEND_API void *zend_fetch_resource(zval **passed_id TSRMLS_DC, int default_id, const char *resource_type_name, int *found_resource_type, int num_resource_types, ...);                                                                       
                ^                                                                                                                                                                                                                             
/opt/php-meminfo-master/extension/php7/meminfo.c: In function 'meminfo_browse_exec_frames':                                                                                                                                      
/opt/php-meminfo-master/extension/php7/meminfo.c:83:5: error: unknown type name 'zend_array'                                                                                                                                     
     zend_array *p_symbol_table;                                                                                                                                                                                                              
     ^                        

(The error above is a snippet from the full error list, which is a lot longer.)

PHP version is 7.3.9, and PHP development tooling has been installed in both cases. PHP is installed from deb.sury.org on the Ubuntu machine, and from remirepo in the CentOS/RHEL image.

Header : signed integer overflow

When any of the memory usage values exceeds 2 147 483 648, on my system it gets generated in the JSON file as a negative integer.
This is a normal behavior for sprintf when called with %d : the argument is treated as an integer and presented as a signed decimal number.
You should replace %d with %lu : long unsigned decimal number.
%ld is a working replacement too, but since those values can't be negative...

Class static in memory are not detected by meminfo

Meminfo works by browsing the execution frame and collecting all items that are linked to variables, or descendants of these variables.

But static member of classes don't live in the execution frame. So they are not accounted by meminfo.

Related to #63

Children items not properly linked in PHP 7

From this code:

<?php
unset($_GET);
unset($_FILES);
unset($_POST);
unset($_SERVER);
unset($_COOKIE);
unset($argv);
unset($argc);

class MyClass {
    public $myDeclaredVar;
}

$myObject = new MyClass();
$myObject->myDeclaredVar = "My declared var content";
$myObject->myUndeclaredVar = "My undeclared content";
$myObject->chilObject = new StdClass()

meminfo_dump(fopen('php://stdout', 'w'));

The output from the PHP 7 extension shows:

"items": {
    "0x7fd5bc0561f8" : {
        "type" : "object",
        "size" : "72",
        "symbol_name" : "myObject",
        "is_root" : true,
        "frame" : "<GLOBAL>",
        "class" : "MyClass",
        "object_handle" : "1",
        "children" : {
            "myDeclaredVar":"0x7fd5bc05d8e0",
            "myUndeclaredVar":"0x7fd5bc05d900",
            "chilObject":"0x7fd5bc05d920"
        }
    },
    "0x7fd5bc056220" : {
        "type" : "string",
        "size" : "39",
        "is_root" : false
    },
    "0x7fd5bc05d900" : {
        "type" : "string",
        "size" : "37",
        "is_root" : false
    },
    "0x7fd5bc05c780" : {
        "type" : "object",
        "size" : "72",
        "is_root" : false,
        "class" : "stdClass",
        "object_handle" : "2",
        "children" : {
        }
    }
}

The 3 children strings are properly accounted for, but the declared string got the wrong item identifier, as well as the object.

Same PHP file executed with the PHP5 extension shows proper behavior:

"items": {
    "0x7f1acd2e4128" : {
        "type" : "object",
        "size" : "56",
        "symbol_name" : "myObject",
        "is_root" : true,
        "frame" : "<GLOBAL>",
        "class" : "MyClass",
        "object_handle" : "1",
        "children" : {
            "myDeclaredVar":"0x7f1acd2e60e8",
            "myUndeclaredVar":"0x7f1acd2e6118",
            "chilObject":"0x7f1acd2e5d48"
        }
    },
    "0x7f1acd2e60e8" : {
        "type" : "string",
        "size" : "47",
        "is_root" : false
    },
    "0x7f1acd2e6118" : {
        "type" : "string",
        "size" : "45",
        "is_root" : false
    },
    "0x7f1acd2e5d48" : {
        "type" : "object",
        "size" : "56",
        "is_root" : false,
        "class" : "stdClass",
        "object_handle" : "2",
        "children" : {
        }
    }
}

Objects that are still in memory but not shown by php-meminfo

I tried using php-meminfo in finding out why in a specific case PDO connections were being kept open. PDO connections only close when they end up out of scope without a refcount so I kinda knew where to look.

After addressing some issues ( #62 ) and even adding a little object store dumper to this extension (see paste below) I noticed that even though php-meminfo wasn't showing me these instances, they were still actively in memory.

This problem occured in a Laravel+Laravel Doctrine project. I suspect that these PDO instances might be referenced in closures somewhere? But maybe they're referenced in a different call stack? Is there any way we could have php-meminfo actually find references to these objects somehow?

Attachment, overly simple object_store_dump():

PHP_FUNCTION(object_store_dump)
{
        zend_object **obj_ptr, **end, *obj;

        if (EG(objects_store).top <= 1) {
                return;
        }

        end = EG(objects_store).object_buckets + 1;
        obj_ptr = EG(objects_store).object_buckets + EG(objects_store).top;

        do {
                obj_ptr--;
                obj = *obj_ptr;

                if (IS_OBJ_VALID(obj)) {
                        php_printf("object: %s: %d\n", obj->ce->name->val, obj->handle );

                        if (!(GC_FLAGS(obj) & IS_OBJ_DESTRUCTOR_CALLED)) {
                                php_printf("- DESTRUCTOR NOT CALLED\n");
                        }

                        if (!(GC_FLAGS(obj) & IS_OBJ_FREE_CALLED)) {
                                php_printf("- FREE NOT CALLED\n");
                        }

                }
        } while (obj_ptr != end);
}

Provide a way to find memory leak when cause is lot of primitive data types

So here's a top of summary table:

+------------------------------------------------------------+-----------------+-----------------------------+
| Type                                                       | Instances Count | Cumulated Self Size (bytes) |
+------------------------------------------------------------+-----------------+-----------------------------+
| string                                                     | 1494183         | 39037387                    |
| array                                                      | 117970          | 8493840                     |
| null                                                       | 88943           | 1423088                     |
| boolean                                                    | 4683            | 74928                       |
| integer                                                    | 2339            | 37424                       |
| ReflectionProperty                                         | 460             | 33120                       |
| Doctrine\ORM\Mapping\Column                                | 370             | 26640                       |
| Everlution\SearchBundle\Model\Builder\Field                | 317             | 22824                       |
| Everlution\SearchBundle\Model\Builder\FieldType\StringType | 237             | 17064                       |
| Closure                                                    | 169             | 12168                       |
+------------------------------------------------------------+-----------------+-----------------------------+

As you see, string takes most of the memory, not any class. README does not provide info on how to deal with such problem. How to proceed? I've looked into json file, I searched there for biggest strings, but found those which are big are not the issue. Memory is probably taken by lot of smaller strings.

Dump attached
meminfo.json.tar.gz

Mem leak not reported properly

I have a long-running process (PHP-PM) executing laravel in a loop. I am seeing memory leaks in my application but the meminfo_dump seems to be not reporting it.

PHP Version: 7.1.2

Memory Leaks:

                                                                                                                      │ime (ms)
--- Worker 5501 stderr ---                                                                                             │  50%     24
11546560                                                                                                               │  66%     34
[24/May/2018:16:38:45 +0000] 172.19.0.9 - - "GET /catalog/product/view/id/34072 HTTP/1.0" 200 347109 "-"               │  75%     50
13175728                                                                                                               │  80%   1380
[24/May/2018:16:39:17 +0000] 172.19.0.9 - - "GET /catalog/product/view/id/34072 HTTP/1.0" 200 346935 "-"               │  90%   2856
14878304                                                                                                               │  95%  11978
[24/May/2018:16:42:07 +0000] 172.19.0.9 - - "GET /catalog/product/view/id/34072 HTTP/1.0" 200 346911 "-"               │  98%  17847
16796656                                                                                                               │  99%  22491
[24/May/2018:16:42:37 +0000] 172.19.0.9 - - "GET /catalog/product/view/id/34072 HTTP/1.0" 200 346889 "-"               │ 100%  30584 (longest request)

With each request it is adding around 2MB of memory and not releasing it. I generated the meminfo and it is reporting all well, here is the summary:

+---------+-----------------+-----------------------------+
| Type    | Instances Count | Cumulated Self Size (bytes) |
+---------+-----------------+-----------------------------+
| string  | 160             | 5788                        |
| boolean | 44              | 704                         |
| array   | 9               | 648                         |
| integer | 1               | 16                          |
| float   | 1               | 16                          |
+---------+-----------------+-----------------------------+

I do not see any objects listed there which sounds strange to me unless I am misinterpretting it :(

pthreads and meminfo

Hi, i have tried to use your extension for profile the memory consuption on my pthreads project, but i receive a segfault.

Have you tested php-meminfo with pthreads?

The frame label is not correct when there are more than two frames

The frame label is not correct when there are more than two frames in the call stack (most of the time).

How to reproduce

<?php
    $dump = fopen('php://memory', 'rw');
    $myVariableInGlobalScope = 'scope';

    function functionLevel1() {
        $myVariableInsideAFunction1 = 'level_1';
        functionLevel2();
    }

    function functionLevel2() {
        $myVariableInsideAFunction2 = 'level_2';
        functionLevel3();
    }

    function functionLevel3() {
        global $dump;
        $myVariableInsideAFunction3 = 'level_3';

        meminfo_dump($dump);
    }

    functionLevel1();

    rewind($dump);
    $meminfoData = json_decode(stream_get_contents($dump), true);
    fclose($dump);

    $symbolNames = ['myVariableInsideAFunction1', 'myVariableInsideAFunction2', 'myVariableInsideAFunction3', 'myVariableInGlobalScope'];
    foreach($meminfoData['items'] as $item) {
        if (isset($item['symbol_name']) && in_array($item['symbol_name'], $symbolNames)) {
            echo 'Frame for '.$item['symbol_name'].': '.$item['frame']."\n";
        }
    }

The output is:

Frame for myVariableInsideAFunction3: functionLevel3()
Frame for myVariableInsideAFunction2: functionLevel1()
Frame for myVariableInsideAFunction1: <GLOBAL>
Frame for myVariableInGlobalScope: <GLOBAL>

It should be:

Frame for myVariableInsideAFunction3: functionLevel3()
Frame for myVariableInsideAFunction2: functionLevel2()
Frame for myVariableInsideAFunction1: functionLevel1()
Frame for myVariableInGlobalScope: <GLOBAL>

Duplication of scalar with multiple references on PHP7

With the following code:

<?php
unset($_GET);
unset($_FILES);
unset($_POST);
unset($_SERVER);
unset($_COOKIE);
unset($argv);
unset($argc);

$a = "test";

$b =& $a;

$c = strlen($b);

meminfo_dump(fopen('php://stdout', 'w'));

With PHP7, wrong output: b shouldn't be there, as it's a reference to a. And a has type unknown.

"items": {
    "0x7fb93bc571e0" : {
        "type" : "unknown",
        "size" : "16",
        "symbol_name" : "a",
        "is_root" : true,
        "frame" : "<GLOBAL>"
    },
    "0x7fb93bc57200" : {
        "type" : "unknown",
        "size" : "16",
        "symbol_name" : "b",
        "is_root" : true,
        "frame" : "<GLOBAL>"
    },
    "0x7fb93bc57220" : {
        "type" : "integer",
        "size" : "16",
        "symbol_name" : "c",
        "is_root" : true,
        "frame" : "<GLOBAL>"
    }
}

With PHP5, the output is correct:

{
"items": {
    "0x7f96977ad158" : {
        "type" : "string",
        "size" : "28",
        "symbol_name" : "a",
        "is_root" : true,
        "frame" : "<GLOBAL>"
    },
    "0x7f96977ad0f8" : {
        "type" : "integer",
        "size" : "24",
        "symbol_name" : "c",
        "is_root" : true,
        "frame" : "<GLOBAL>"
    }
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.