%{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 /* }}} */ 〜 省略 〜
。。。という経過がありつつ、最終的に先日のパッチに繋がる、と。
どうでもいい事、失礼しました。