printfデバッグのお供に

みんな大好き printfデバッグ
デバッガでアタッチしにくかったり、とりあえずの動作状況を見たいときなど、、、いまだに強い人気を誇っている printf デバッグです。
だけど、サーバみたいなプロセスだと printf することすらできない。。。
そんなときに使うさくっとコピペでつくれるロガーを作ってみました。
コピペで切り貼りすればあっというまにロガーができます。
楽しい printf デバッグライフがおくれます。
こんなの使うなんて邪悪です。

使い方は簡単で、

MYLOG("ここまでやってきた");

ってやると、

tail /tmp/mydebug

ここまでやってきた@ /home/rti/tokyo_tyrant-0.4.0/session.c:66(ps_create_sid_tokyo_tyrant)

みたいな形でログに残せます。

printf 表記もいけます。
MYLOG("1 + 1 = %d",1+1);

1 + 1 = 2@ /home/rti/tokyo_tyrant-0.4.0/session.c:66(ps_create_sid_tokyo_tyrant)

簡単ですね。


↓ここからコピペして使ってください。

//ログを出します
#define MYLOG(FORMAT,...) { mylogformat(__FILE__,__LINE__,__FUNCTION__,FORMAT, ##__VA_ARGS__); }
//バックトレースを表示します
#define MYLOGBT() { mylogBT(__FILE__,__LINE__,__FUNCTION__); }
//int 3のブレークポイントを打ち込みます。
#define MYLOGINT3() { mylogInt3(__FILE__,__LINE__,__FUNCTION__); }

//ログを出すファイル名
#define MYLOGFILE "/tmp/mydebug"

void mylogformat(const char * filename , int inLine , const char* inFunction , const char * inFormat,...)
{
	char buffer[2048];
	FILE * fp = fopen(MYLOGFILE,"a");
	if (!fp)
	{
		return ;
	}
	vsprintf(buffer, inFormat, (char*)(&inFormat+1) );
	buffer[sizeof(buffer) - 1] = '\0';
	
	fputs(buffer , fp);
	fprintf(fp,"@ %s:%d(%s)\n",filename,inLine,inFunction);

	fclose(fp);
}

void mylogBT(const char * filename , int inLine , const char* inFunction)
{
	void* trace[100];
	int n,i;
	const char ** buffer;
	FILE * fp = fopen(MYLOGFILE,"a");
	if (!fp)
	{
		return ;
	}

	fprintf(fp,"==== start backtrace === @ %s:%d(%s)\n",filename,inLine,inFunction);

	n = backtrace(trace, sizeof(trace) / sizeof(trace[0]));
	buffer = backtrace_symbols(trace, n);
	if (!buffer)
	{
		fputs("not enough memory...", fp);
	}
	else
	{
		for(i = 0; i < n ; i ++)
		{
			fprintf(fp,"%d : %s\n",i,buffer[i] );
		}
		free(buffer);
	}
	fprintf(fp,"\n==== end backtrace === \n");

	fclose(fp);
}

void mylogInt3(const char * filename , int inLine , const char* inFunction)
{
	FILE * fp = fopen(MYLOGFILE,"a");
	if (!fp)
	{
		return ;
	}
	fprintf(fp,"---- int 3!!! --- @ %s:%d(%s)\n",filename,inLine,inFunction);
	fclose(fp);

	asm ("int $3") ;
}

↑コピペはここまで。


他にも、バットトレースも見れます。
MYLOGBT();

==== start backtrace === @ /home/rti/tokyo_tyrant-0.4.0/session.c:117(ps_create_sid_tokyo_tyrant)
0 : /usr/lib/php5/20060613+lfs/tokyo_tyrant.so(mylogBK+0x80) [0xb60def50]
1 : /usr/lib/php5/20060613+lfs/tokyo_tyrant.so(ps_create_sid_tokyo_tyrant+0x5a) [0xb60df13a]
2 : /usr/lib/apache2/modules/libphp5.so(zif_session_regenerate_id+0xf0) [0xb6e1f6a0]
3 : /usr/lib/apache2/modules/libphp5.so(execute_internal+0x51) [0xb6f90e41]
4 : /usr/lib/php5/20060613+lfs/xdebug.so(xdebug_execute_internal+0x159) [0xb68d79f0]
5 : /usr/lib/apache2/modules/libphp5.so [0xb6fa9c80]
6 : /usr/lib/apache2/modules/libphp5.so(execute+0x160) [0xb6f95490]
7 : /usr/lib/php5/20060613+lfs/xdebug.so(xdebug_execute+0xb7a) [0xb68d7677]
8 : /usr/lib/apache2/modules/libphp5.so(zend_execute_scripts+0x180) [0xb6f6fbd0]
9 : /usr/lib/apache2/modules/libphp5.so(php_execute_script+0x1a3) [0xb6f25af3]
10 : /usr/lib/apache2/modules/libphp5.so [0xb6fe7cc0]
11 : /usr/sbin/apache2(ap_run_handler+0x59) [0x807a1c9]
12 : /usr/sbin/apache2(ap_invoke_handler+0x81) [0x807d5e1]
13 : /usr/sbin/apache2(ap_process_request+0x196) [0x808b0a6]
14 : /usr/sbin/apache2 [0x80881d8]
15 : /usr/sbin/apache2(ap_run_process_connection+0x59) [0x80815f9]
16 : /usr/sbin/apache2 [0x808fcd4]
17 : /usr/sbin/apache2 [0x80900b3]
18 : /usr/sbin/apache2(ap_mpm_run+0x5fa) [0x809073a]
19 : /usr/sbin/apache2(main+0xa50) [0x8066f10]
20 : /lib/i686/cmov/libc.so.6(__libc_start_main+0xe5) [0xb7dbd455]
21 : /usr/sbin/apache2(apr_global_mutex_lock+0x31) [0x8065ec1]

==== end backtrace ===

最狂にも、 int 3h を打ち込むこともできます。

MYLOGINT3();

---- int 3!!! --- @ /home/rti/tokyo_tyrant-0.4.0/session.c:118(ps_create_sid_tokyo_tyrant)

こんなの邪道だ。