ます’s Blog - どうでもいい記事100選

どうでもいい記事100選

%{mod_php_memory_usage}n(補足)

先日のですが。
この時は少し熱くなりすぎていたようで、途中経過を全く書いていませんでした。これじゃ、何がなんだか。。。という感じですね。反省。
今更蒸し返すような話でもありませんが、一応履歴を晒しておきます(自分が忘れそうなダケだからメモしておきたいとも言う)。

まず「mod_php_memory_usage」をキーワードにして検索。

% grep -rn mod_php_memory_usage /usr/local/src/php-4.4.7
/usr/local/src/php-4.4.7/NEWS:162:- Fixed bug #35646 (%{mod_php_memory_usage}n is not reset after exit).
/usr/local/src/php-4.4.7/NEWS:2455:  1.x logging directive "{mod_php_memory_usage}n" which will log the peak
/usr/local/src/php-4.4.7/sapi/apache/mod_php4.c:650:            ap_table_setn(r->notes, "mod_php_memory_usage", mem_usage);
/usr/local/src/php-4.4.7/sapi/apache2handler/sapi_apache2.c:590:                        apr_table_set(r->notes, "mod_php_memory_usage", mem_usage);

% less -N /usr/local/src/php-4.4.7/sapi/apache/mod_php4.c

        〜 省略 〜

    637 /* {{{ send_parsed_php
    638  */
    639 static int send_parsed_php(request_rec * r)
    640 {
    641         int result = send_php(r, 0, NULL);
    642
    643 #if MEMORY_LIMIT
    644         {
    645                 char *mem_usage;
    646                 TSRMLS_FETCH();
    647
    648                 mem_usage = ap_psprintf(r->pool, "%u", AG(allocated_memory_peak));
    649                 AG(allocated_memory_peak) = 0;
    650                 ap_table_setn(r->notes, "mod_php_memory_usage", mem_usage);
    651         }
    652 #endif
    653
    654         return result;
    655 }

        〜 省略 〜

「allocated_memory_peak」という情報を書き込んでいる模様。
次に「allocated_memory_peak」をキーワードにして検索。

% grep -rn allocated_memory_peak /usr/local/src/php-4.4.7
/usr/local/src/php-4.4.7/sapi/apache/mod_php4.c:648:            mem_usage = ap_psprintf(r->pool, "%u", AG(allocated_memory_peak));
/usr/local/src/php-4.4.7/sapi/apache/mod_php4.c:649:            AG(allocated_memory_peak) = 0;
/usr/local/src/php-4.4.7/sapi/apache2handler/sapi_apache2.c:589:                        mem_usage = apr_psprintf(ctx->r->pool, "%u", AG(allocated_memory_peak));
/usr/local/src/php-4.4.7/Zend/ChangeLog:1480:    allocated_memory_peak should be only reset on scipt startup. right now the
/usr/local/src/php-4.4.7/Zend/ChangeLog:2243:    * zend_alloc.c: reset allocated_memory_peak after each request.
/usr/local/src/php-4.4.7/Zend/zend_alloc.c:173:         if (AG(allocated_memory) > AG(allocated_memory_peak)) {
/usr/local/src/php-4.4.7/Zend/zend_alloc.c:174:                 AG(allocated_memory_peak) = AG(allocated_memory);
/usr/local/src/php-4.4.7/Zend/zend_alloc.c:346: if (AG(allocated_memory) > AG(allocated_memory_peak)) {
/usr/local/src/php-4.4.7/Zend/zend_alloc.c:347:         AG(allocated_memory_peak) = AG(allocated_memory);
/usr/local/src/php-4.4.7/Zend/zend_alloc.c:452: AG(allocated_memory_peak) = 0;
/usr/local/src/php-4.4.7/Zend/zend_alloc.c:563: AG(allocated_memory_peak) = 0;
/usr/local/src/php-4.4.7/Zend/zend_globals.h:232:       unsigned int allocated_memory_peak;

この情報は「/(php-src)/Zend/zend_alloc.c」ファイル内で情報が(随時)更新されていく模様。
このファイルは、かなりの魔窟になっていて読み解くのに苦労するのですが(w、基本的には「allocated_memory」が「allocated_memory_peak」よりも大きい場合に「allocated_memory」を「allocated_memory_peak」に代入している模様。
気分転換に「allocated_memory」をキーワードにして検索。

% grep -rn allocated_memory /usr/local/src/php-4.4.7
/usr/local/src/php-4.4.7/ext/standard/var.c:735:        RETURN_LONG(AG(allocated_memory));
/usr/local/src/php-4.4.7/sapi/apache/mod_php4.c:648:            mem_usage = ap_psprintf(r->pool, "%u", AG(allocated_memory_peak));
/usr/local/src/php-4.4.7/sapi/apache/mod_php4.c:649:            AG(allocated_memory_peak) = 0;
/usr/local/src/php-4.4.7/sapi/apache2handler/sapi_apache2.c:589:                        mem_usage = apr_psprintf(ctx->r->pool, "%u", AG(allocated_memory_peak));
/usr/local/src/php-4.4.7/Zend/ChangeLog:1480:    allocated_memory_peak should be only reset on scipt startup. right now the
/usr/local/src/php-4.4.7/Zend/ChangeLog:2243:    * zend_alloc.c: reset allocated_memory_peak after each request.
/usr/local/src/php-4.4.7/Zend/zend_alloc.c:67:#define _CHECK_MEMORY_LIMIT(s, rs, file, lineno) { if ((ssize_t)(rs) > (ssize_t)(INT_MAX - AG(allocated_memory))) { \
/usr/local/src/php-4.4.7/Zend/zend_alloc.c:75:                                                          AG(allocated_memory) += rs;\
/usr/local/src/php-4.4.7/Zend/zend_alloc.c:76:                                                          if (AG(memory_limit)<AG(allocated_memory)) {\
/usr/local/src/php-4.4.7/Zend/zend_alloc.c:78:                                                                  AG(allocated_memory) -= rs;\
/usr/local/src/php-4.4.7/Zend/zend_alloc.c:79:                                                                  if (EG(in_execution) && AG(memory_limit)+1048576 > AG(allocated_memory)) { \
/usr/local/src/php-4.4.7/Zend/zend_alloc.c:80:                                                                          AG(memory_limit) = AG(allocated_memory) + 1048576; \
/usr/local/src/php-4.4.7/Zend/zend_alloc.c:173:         if (AG(allocated_memory) > AG(allocated_memory_peak)) {
/usr/local/src/php-4.4.7/Zend/zend_alloc.c:174:                 AG(allocated_memory_peak) = AG(allocated_memory);
/usr/local/src/php-4.4.7/Zend/zend_alloc.c:277: AG(allocated_memory) -= SIZE;
/usr/local/src/php-4.4.7/Zend/zend_alloc.c:346: if (AG(allocated_memory) > AG(allocated_memory_peak)) {
/usr/local/src/php-4.4.7/Zend/zend_alloc.c:347:         AG(allocated_memory_peak) = AG(allocated_memory);
/usr/local/src/php-4.4.7/Zend/zend_alloc.c:450: AG(allocated_memory) = 0;
/usr/local/src/php-4.4.7/Zend/zend_alloc.c:452: AG(allocated_memory_peak) = 0;
/usr/local/src/php-4.4.7/Zend/zend_alloc.c:511:                         AG(allocated_memory) -= REAL_SIZE(ptr->size);
/usr/local/src/php-4.4.7/Zend/zend_alloc.c:550:                 AG(allocated_memory) -= REAL_SIZE(t->size);
/usr/local/src/php-4.4.7/Zend/zend_alloc.c:563: AG(allocated_memory_peak) = 0;
/usr/local/src/php-4.4.7/Zend/zend_globals.h:231:       unsigned int allocated_memory;
/usr/local/src/php-4.4.7/Zend/zend_globals.h:232:       unsigned int allocated_memory_peak;

重複が目立ちますが、新たに「/(php-src)/ext/standard/var.c」ファイルがリストUPされました。
中身を覗いてみます。

% less -N /usr/local/src/php-4.4.7/ext/standard/var.c

        〜 省略 〜

    731 #if MEMORY_LIMIT
    732 /* {{{ proto int memory_get_usage()
    733     Returns the allocated by PHP memory */
    734 PHP_FUNCTION(memory_get_usage) {
    735         RETURN_LONG(AG(allocated_memory));
    736 }
    737 /* }}} */
    738 #endif

        〜 省略 〜

単に「allocated_memory」という情報を返却している模様。
試しにWebからmemory_get_usage関数を実行してみると、情報が正しく返却されました(0以上の値が返却される)。
という訳で、書き込む情報を「allocated_memory_peak」から「allocated_memory」に変更して実行してみる。

--- php-4.4.7,orig/sapi/apache/mod_php4.c       2007-01-01 18:46:51.000000000 +0900
+++ php-4.4.7/sapi/apache/mod_php4.c    2007-11-26 13:35:23.000000000 +0900
@@ -645,7 +645,7 @@
                char *mem_usage;
                TSRMLS_FETCH();

-               mem_usage = ap_psprintf(r->pool, "%u", AG(allocated_memory_peak));
+               mem_usage = ap_psprintf(r->pool, "%u", AG(allocated_memory));
                AG(allocated_memory_peak) = 0;
                ap_table_setn(r->notes, "mod_php_memory_usage", mem_usage);
        }

この結果は駄目でした。。。残念。_| ̄|○
この位置では「allocated_memory_peak」と「allocated_memory」共に既に初期化(未定義?)されている模様(fprintf関数経由でstderrに情報を吐き出して確認)。
他はどうなっているのだろうか?と疑問に思いつつ「/(php-src)/sapi/apache2handler/sapi_apache2.c」ファイル内を確認してみました。

% less -N /usr/local/src/php-4.4.7/sapi/apache2handler/sapi_apache2.c

        〜 省略 〜

    580                 if (!parent_req) {
    581                         php_execute_script(&zfd TSRMLS_CC);
    582                 } else {
    583                         zend_execute_scripts(ZEND_INCLUDE TSRMLS_CC, NULL, 1, &zfd);
    584                 }
    585 #if MEMORY_LIMIT
    586                 {
    587                         char *mem_usage;
    588
    589                         mem_usage = apr_psprintf(ctx->r->pool, "%u", AG(allocated_memory_peak));
    590                         apr_table_set(r->notes, "mod_php_memory_usage", mem_usage);
    591                 }
    592 #endif
    593         }

        〜 省略 〜

このファイルでは「php_execute_script」関数か「zend_execute_scripts」関数を実行した後に「allocated_memory_peak」を書き込んでいる模様。
実行している位置が違うような気が。。。という訳で、本丸のファイル内を検索。

% grep -rn _execute_script /usr/local/src/php-4.4.7/sapi/apache
/usr/local/src/php-4.4.7/sapi/apache/mod_php4.c:557:            zend_execute_scripts(ZEND_INCLUDE TSRMLS_CC, NULL, 1, &fh);
/usr/local/src/php-4.4.7/sapi/apache/sapi_apache.c:54:          (void) php_execute_script(&file_handle TSRMLS_CC);

どちらかの関数を実行した直後に埋め込むのが良さそう。。。と判断し、今回は「php_execute_script」関数を実行した直後に埋め込む事にしました。
判断基準は「php_execute_script」関数を実行した直後に「AP(in_request) = 0;」と「php_request_shutdown」関数を実行している箇所があった為で、明確な根拠があった訳ではありません。要するに適当だ、という事です。(w

% less -N /usr/local/src/php-4.4.7/sapi/apache/sapi_apache.c

        〜 省略 〜

     26 /* {{{ apache_php_module_main
     27  */
     28 int apache_php_module_main(request_rec *r, int display_source_mode TSRMLS_DC)
     29 {
     30         int retval = OK;
     31         zend_file_handle file_handle = {0};
     32
     33         if (php_request_startup(TSRMLS_C) == FAILURE) {
     34                 return FAILURE;
     35         }
     36         /* sending a file handle to another dll is not working
     37         // so let zend open it.
     38         */
     39
     40         if (display_source_mode) {
     41                 zend_syntax_highlighter_ini syntax_highlighter_ini;
     42
     43                 php_get_highlight_struct(&syntax_highlighter_ini);
     44                 if (highlight_file(SG(request_info).path_translated, &syntax_highlighter_ini TSRMLS_CC) != SUCCESS) {
     45                         retval = NOT_FOUND;
     46                 }
     47         } else {
     48                 file_handle.type = ZEND_HANDLE_FILENAME;
     49                 file_handle.handle.fd = 0;
     50                 file_handle.filename = SG(request_info).path_translated;
     51                 file_handle.opened_path = NULL;
     52                 file_handle.free_filename = 0;
     53
     54                 (void) php_execute_script(&file_handle TSRMLS_CC);
     55         }
     56
     57         AP(in_request) = 0;
     58
     59         zend_try {
     60                 php_request_shutdown(NULL);
     61         } zend_end_try();
     62
     63         return retval;
     64 }
     65 /* }}} */

        〜 省略 〜

。。。という経過がありつつ、最終的に先日のパッチに繋がる、と。
どうでもいい事、失礼しました。