2012年12月27日木曜日

C言語 デバッグ用マクロ

http://gcc.gnu.org/onlinedocs/gcc/Variadic-Macros.html#Variadic-Macros

#define DMSG_ERR( p_fmt, ...) printk(KERN_ERR "cpu:%d %s:%d (%s) " p_fmt, smp_processor_id(), __BASENAME__, __LINE__, __func__, ## __VA_ARGS__)
#define DMSG_WARNING(p_fmt, ...) printk(KERN_WARNING "cpu:%d %s:%d (%s) " p_fmt, smp_processor_id(), __BASENAME__, __LINE__, __func__, ## __VA_ARGS__)
#define DMSG_NOTICE( p_fmt, ...) printk(KERN_NOTICE "cpu:%d %s:%d (%s) " p_fmt, smp_processor_id(), __BASENAME__, __LINE__, __func__, ## __VA_ARGS__)
#define DMSG_INFO( p_fmt, ...) printk(KERN_INFO "cpu:%d %s:%d (%s) " p_fmt, smp_processor_id(), __BASENAME__, __LINE__, __func__, ## __VA_ARGS__)



2012年12月20日木曜日

Programing memo

・デバッグ分出力のバイナリをデフォルトで生成するようにしておく。
・いたるところに、デバッグ文出力用マクロを挿入しておく。
 どこまで通過したか判るように。



2012年12月19日水曜日

zip unzip 指定ファイルの解凍

zip unzip 指定ファイルの解凍

$ unzip archives.zip mydir/my.iso -d /home/user



(DVD)メディアのチェックサム md5sum

チェックサム md5sum

(DVD)メディアは単純にチェックサムを比較することが出来ない。
http://www.debian.org/CD/faq/index.ja.html

$ /usr/bin/isosize -x /dev/hdc
sector count: 4425, sector size: 2048
$ dd if=/dev/hdc count=4425 bs=2048 | md5sum




書き込み済みの光学メディアを検証する場合
メディアの種類によっては ISO イメージにあるものよりも多くのバイト数を返してくる可能性
この後方に付くゴミは TAO モードで書き込まれた CD、追記された DVD-R[W]、
フォーマット済みの DVD-RW, DVD+RW, BD-RE、さらに USB キーの場合不可避
ISO イメージ自体にあるのと正確に同数のセクタのデータをメディアから読み込む必要があり
メディアからそれ以上に多くのバイトを読み込んだ場合チェックサムの結果は違うものになる



2012年12月14日金曜日

環境変数

forkした子プロセスは、環境変数も引き継ぐ。
getenv
putenv
setenv
unsetenv
environ (7) 大域変数
clearenv すべての環境変数をクリアする(空にする)posixでない!?

su コマンドを '-' 付加して実行すると、環境変数は引き継がない。
シェルをログインシェルにする。


/etc/profile.d/*.sh に環境変数を設定する各種スクリプトがある。


すべての環境変数を表示する。
$ gcc -Wall -o my_printenv my_printenv.c
#include <stdio.h>

extern char **environ;

int main()
{
char **ep = environ;
char *p;

FILE *fptr;

fptr = fopen("/tmp/xxx.txt", "a");

fprintf(fptr, "-------------\n");

while ((p = *ep++))
fprintf(fptr, "%s\n", p);

fclose(fptr);

return 0;
}



2012年12月11日火曜日

2012年12月5日水曜日

特殊なデバイス

/dev/null
書き込み全て破棄、読み取りは常にEOF

/dev/zero
書き込み全て破棄、読み取りは永遠にnull文字(\0)

/dev/full
書き込みは常にエラーerrno=ENOSPC(デバイス容量FULL)、読み取りは永遠にnull文字(\0)

・異常時対応の動作テストをする際に有用
・null,zeroデバイスは書き込み無視するので、不要なI/Oを破棄する際、無用のオーバーヘッドがない手頃な方法


/dev/random (暗号用。長時間I/Oブロックの可能性アリ)
/dev/urandom (普通のアプリはこちら)
乱数生成デバイス


#include <stdio.h>
int main()
{
int value;
FILE *fptr;
unsigned int w_i;
fptr = fopen("/dev/urandom", "r");
if(fptr==NULL) { return -1; }
for(w_i=0; w_i<20; w_i++) {
fread( &value, sizeof(value), 1, fptr);
printf("%2d value = 0x%08X %u\n", w_i, value, value);
}
fclose(fptr);
return 0;
}



タイマ時間

***
*
* gcc -Wall -lrt -o clock clock.c
*
***/
/***
Linux mtlx02 2.6.18-128.el5 #1 SMP Wed Dec 17 09:03:25 PM EST 2008 x86_64 x86_64 x86_64 GNU/Linux
clock=0 sec=0 nsec=999848 分解能約1ms CLOCK_REALTIME
clock=1 sec=0 nsec=999848 分解能約1ms CLOCK_MONOTONIC
clock=2 sec=0 nsec=1 分解能1ns CLOCK_PROCESS_CPUTIME_ID (TSC)
clock=3 sec=0 nsec=1 分解能1ns CLOCK_THREAD_CPUTIME_ID (TSC)
***/
#include <stdio.h>
#include <time.h>

int main()
{
clockid_t clocks[] = {
CLOCK_REALTIME, /* システム全体の実時間(real time、wall time) */
CLOCK_MONOTONIC, /* 任意の時点からの経過時間 */
CLOCK_PROCESS_CPUTIME_ID, /* プロセス毎に使用可能なCPUが備える高分解能の時計 */
CLOCK_THREAD_CPUTIME_ID, /* プロセス毎の時計と同じだが、スレッド毎に使用可能 */
(clockid_t) -1
};

char *clocksStr[] = {
"CLOCK_REALTIME", /* システム全体の実時間(real time、wall time) */
"CLOCK_MONOTONIC", /* 任意の時点からのけ化時間 */
"CLOCK_PROCESS_CPUTIME_ID", /* プロセス毎に使用可能なCPUが備える高分解能の時計 */
"CLOCK_THREAD_CPUTIME_ID", /* プロセス毎の時計と同じだが、スレッド毎に使用可能 */
""
};

int w_i;


/* 分解能表示 */
printf("clock_getres\n");
for(w_i=0; clocks[w_i]!=(clockid_t) -1; w_i++) {
struct timespec res;
int ret;

ret = clock_getres(clocks[w_i], &res);
if(ret) {
perror("clock_getres");
} else {
printf("%30s : clock=%d sec=%ld nsec=%ld\n",
clocksStr[w_i],
clocks[w_i], res.tv_sec, res.tv_nsec);
}
} /*for(w_i)*/

/* 現在時刻表示 */
printf("clock_gettime\n");
for(w_i=0; clocks[w_i]!=(clockid_t) -1; w_i++) {
struct timespec res;
int ret;

ret = clock_gettime(clocks[w_i], &res);
if(ret) {
perror("clock_getres");
} else {
printf("%30s : clock=%d sec=%ld nsec=%ld\n",
clocksStr[w_i],
clocks[w_i], res.tv_sec, res.tv_nsec);
}
} /*for(w_i)*/

return 0;
}



Linuxハングアップ次の操作

↓下記、下の項目に行くほど程度のひどいハングアップ。

・Ctrl+q(Ctrl+sを押している場合の解除)
・Ctrl+d(入力待ちの場合、入力を終了)
・Ctrl+c(プロセスの終了)
・Ctrl+\(プロセスの終了)
・Ctrl+z(プロセスの停止)
・仮想コンソールに切り替える(X上Ctrl+Alt+F2、コンソール上Alt+F3)
・Ctrl+Alt+BackSpace(X上Xセッションを終了)
・CTRL+ALT+DEELTE(再起動)
・Alt-SysRq-s(sync) → Alt-SysRq-u(unmount) → Alt-SysRq-b(reboot) (システム再起動)
 ※sysRqキーがない場合、PrintScreenキー
・Alt+SysRq+b (syncせずに再起動)
・電源ボタンを押す(押してみる)
・リセットボタンを押す(押してみる)
・電源ボタン長押し
・コンピューターの電源OFF
・電源コードを抜く



デバッグツール debug tool

実行中のアプリケーションを外から観察するコマンド

strace システムコールをトレース(カーネルと何を話しいてるか)
ltrace 共有ライブラリをトレース(*.soと何を話しいてるか)
lsof LiSt Open Files。どのファイルを使っているか調べられる。(ファイル≒unixは全てファイル)
tracef 関数呼び出しをトレース(フリーツール!?)
ftrace 関数呼び出しをトレース(フリーツール!?)
ldd 依存ライブラリ

http://d.hatena.ne.jp/koseki2/20090619/TraceProc%29