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

どうでもいい記事100選

xdebug_get_code_coverage(その後)

先日のですが。
私は今、猛烈に憤慨している。。。抑えきれない程の怒りと憤りが体中を駆け巡っているぜ。。。!

% less -N /path/to/crash.php
      1 <?php
      2
      3   xdebug_start_code_coverage( );
      4
      5   mb_http_output( "SJIS" );
      6   ob_start( "mb_output_handler" );
      7
      8   echo "盛大にクラッシュだ!\n";
      9
     10   $Coverage_Array = xdebug_get_code_coverage( );
     11
     12   print_r( $Coverage_Array );
     13
     14 ?>
% /path/to/php-4.4/bin/php -c /path/to/php-4.4/lib/php-xdebug.ini /path/to/crash.php
Segmentation fault
% gdb /path/to/php-4.4/bin/php
GNU gdb 6.4.90-debian
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i486-linux-gnu"...Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1".

(gdb) r -c /path/to/php-4.4/lib/php-xdebug.ini /path/to/crash.php
Starting program: /path/to/php-4.4/bin/php -c /path/to/php-4.4/lib/php-xdebug.ini /path/to/crash.php
Failed to read a valid object file image from memory.

Program received signal SIGSEGV, Segmentation fault.
0xb7e21473 in strlen () from /lib/tls/i686/cmov/libc.so.6
(gdb) bt
#0  0xb7e21473 in strlen () from /lib/tls/i686/cmov/libc.so.6
#1  0xb7d92607 in xdebug_count_line (filename=0x0, lineno=0, executable=0, deadcode=0)
    at /usr/local/src/xdebug-2.0.2/xdebug_code_coverage.c:52
#2  0xb7d8d257 in add_stack_frame (zdata=0xbf97a100, op_array=0x0, type=1) at /usr/local/src/xdebug-2.0.2/xdebug.c:1137
#3  0xb7d8e7aa in xdebug_execute_internal (current_execute_data=0xbf97a100, return_value_used=1)
    at /usr/local/src/xdebug-2.0.2/xdebug.c:1558
#4  0x0813b89c in call_user_function_ex (function_table=0x82e50a8, object_pp=0x0, function_name=0x83149c4, retval_ptr_ptr=0xbf97a220,
    param_count=2, params=0xbf97a1c8, no_separation=1, symbol_table=0x0) at /usr/local/src/php-4.4.7/Zend/zend_execute_API.c:597
#5  0x08122295 in php_end_ob_buffer (send_buffer=1 '\001', just_flush=0 '\0') at /usr/local/src/php-4.4.7/main/output.c:242
#6  0x08122708 in php_end_ob_buffers (send_buffer=1 '\001') at /usr/local/src/php-4.4.7/main/output.c:341
#7  0x0810c802 in php_request_shutdown (dummy=0x0) at /usr/local/src/php-4.4.7/main/main.c:977
#8  0x0816020f in main (argc=4, argv=0xbf97a9d4) at /usr/local/src/php-4.4.7/sapi/cli/php_cli.c:889

最近こんなのばっかり。_| ̄|○
バックトレースを見る限りでは(最終的に)strlen関数を実行した時に落ちているので、やっつけで以下パッチを敢行。これで落ちる事は無くなりました。

--- xdebug-2.0.2,orig/xdebug_code_coverage.c	2007-11-12 01:17:28.000000000 +0900
+++ xdebug-2.0.2/xdebug_code_coverage.c	2007-11-20 18:53:32.000000000 +0900
@@ -46,6 +46,10 @@
 	xdebug_coverage_line *line;
 	char *sline;
 
+	if (!filename) {
+		return;
+	}
+
 	sline = xdebug_sprintf("%d", lineno);
 
 	/* Check if the file already exists in the hash */

もういいんです。ファイル名が渡ってこない場合に正しく集計されなくても。
個人的にはxdebug関数が怪しいのではなくて、それよりも前の段階でおかしいような気がしています。なので、根本的に直したとは言いがたい。
ファイル名が渡ってこない時点で既におかしいような気がするのですが、時間が無いので深追いせず。はぁ。
callbackを引数に取るPHP組み込み関数で、PHP組み込み関数を引数に渡した場合も同じように落ちるんだろうなぁ。。。きっと。ファイル名が渡ってこないっていうのは(恐らく)そういう状況なのかと。
ややこしい事に、

  • ob_start関数単体の実行では問題ない(output_callbackを指定すると問題発生)
  • output_callbackを指定してもxdebug関数を呼び出さなければ問題ない
  • PHP5.2.5では、どのような状況でも問題ない

こういう状況なので、バグ・レポートを出しても盛大な責任の擦り付け合いが始まりそうな予感がします。
そもそもPHP4サポート終了間近だし修正せずに放置、という事も考えられますね。
そんな環境いつまでも使ってんじゃねぇ!って事ですか。そうですか。
っていうか、「zend_extension_debug」って何だよ。。。外部extension状態でデバッグ環境つくるのに苦労しまくり。はぁ。
通常の場合は「extension_debug」なのかな。

% grep -rn extension_debug /usr/local/src/php-4.4.7
/usr/local/src/php-4.4.7/main/php_ini.c:157:# define ZEND_EXTENSION_TOKEN    "zend_extension_debug_ts"
/usr/local/src/php-4.4.7/main/php_ini.c:163:# define ZEND_EXTENSION_TOKEN    "zend_extension_debug"

って、そうでもないみたい。
どうやるんだろう。。。デバック環境のphpizeを使ってビルド環境を作れば特に気にしなくてもよいのかな。
明示的に(コンパイル・フラグに)デバック・シンボルの情報を付与したりするのだろうか。謎。