Armadilloフォーラム

EtherNet通信プログラムでの問題

ysdc_sasaki

2015年3月31日 19時02分

Armadillo420を使用したEthernet通信プログラムにて問題が発生し、困っております。
ご教示よろしくお願い致します。

[動作概要]
・Linux Version は 2.6.26-at22 。
・ソフトウェアはクライアントとして動作。
・ソフトウェア初期化時にArmadilloのIPアドレスを変更。
 (IPアドレス変更は"ioctl"関数を使用)
・通信先サーバに対し、ソケット生成、TCPコネクションを実行。
・3秒間隔で"netstat"を利用し、接続完了を確認。
 (タイムアウト発生でソケットクローズ後、ソケット生成及び
  TCPコネクションをリトライ)
・断続的にサーバとの通信処理実施。
・接続確立後は3秒間隔で"netstat"を利用し切断監視。

[発生している問題]
 通信先サーバが存在しない状態でソフトウェアを動作し続けると
 一定時間(10~20分)経過後、"netstat"実行後、ソフトウェアが
 強制終了(プロセスが停止)してしまう。

[ソースコード抜粋]

// コマンド実行
strcpy(command, "netstat -tn | grep ESTABLISHED > /tmp/chk_tcp"); ret = system((const char*)command);
  :
  :

// 出力結果確認
strcpy(command, "cat /tmp/chk_tcp");
fp = popen(command, "r");
fgets(read_buff, sizeof(read_buff), fp)) {
  :
  :
}

【教えていただきたいこと】
・一定間隔(3秒)で"netstat"を実行することで、プロセスが停止すると
 いうことが発生するのか?
・Armadilloでサポートされていない"netstat"のオプション"-4"を
 一定間隔(3秒)で実行した場合、プロセスが停止するということが
 発生するのか?
 ("netstat -4"を実行するとエラーメッセージが表示されるだけで
  実行結果は記録されない為、接続確認は出来ないことは確認して
  いますが、プロセス停止の有無が知りたいです)

コメント

netstatの振る舞いは知りませんが、popen()で開いたストリームをpclose()しているかどうかが気になります。
もしクローズしていないなら、ストリームの総数を使い切って落ちているような気がします。
その場合、ストリーム総数が仮に256なら(256-α)*3secで12分強になるので辻褄が合いそうです。

# そもそもなんで一々catを挟むのかとか、strcpy()でコピーするバッファと処理が勿体無いとか、いろいろ疑問ですが。

at_takashi.sasayama

2015年4月1日 13時31分

笹山です。

まだ試されていませんでしたら、
core ファイルの取得を試みてはいかがでしょうか?

手順としては以下になります。

■1. core ファイルを出力する設定

デフォルトでは プログラムが異常終了しても
core ファイルは出力されません。
その為 armadillo 上で以下のコマンドを実行します。

[armadillo]# ulimit -c unlimited
[armadillo]# ulimit -c
unlimited

■2. core ファイルが出力されることを確認

実際に core ファイルが出力されるかを、
以下の dmp-core-test.c の様な、異常終了するプログラムで
確認されることをおすすめします。

dmp-core-test.c

#include<stdio.h>
int main(int argc, char* argv[]) {
        int* p;
        printf("%d\n",*p); /* 未初期化のポインタ変数を参照 */
        return 0;
}

dmp-core-test.c のビルド

[ATDE3]$ arm-linux-gnueabi-gcc dmp-core-test.c -o dmp-core-test -g

生成される dmp-core-test を armadillo 上で実行すると
セグメンテーションフォルトが発生し、core ファイルが出力されます。

[armadillo]# chmod +x dmp-core-test
[armadillo]# ./dmp-core-test
Segmentation fault (core dumped)
 
[armadillo]# ls -al core
-rw-r--r-- 1 atmark atmark 139264 2015-04-01 12:35 core

■3. core ファイルの解析

問題となっているプログラムを -g オプションを付けてビルドし、
異常終了を再現させます。
core ファイルが出力されたら ATDE3 に転送して、以下のコマンドを実行します。
ここでは dmp-core-test を例としています。

[ATDE3]$ arm-linux-gnueabi-gdb -c core ./dmp-core-test
GNU gdb 6.8-debian
Copyright (C) 2008 Free Software Foundation, Inc.
 : 一部省略
Core was generated by `./dmp-core-test'.
Program terminated with signal 11, Segmentation fault.
[New process 1124]
#0  0x00008478 in main (argc=1, argv=0xbea50e34) at dmp-core-test.c:4
4               printf("%d\n",*p);  # ここでセグメンテーションフォルトが発生
(gdb)

> ・Armadilloでサポートされていない"netstat"のオプション"-4"を
> 一定間隔(3秒)で実行した場合、プロセスが停止するということが発生するのか?

> ("netstat -4"を実行するとエラーメッセージが表示されるだけで
> 実行結果は記録されない為、接続確認は出来ないことは確認していますが、
> プロセス停止の有無が知りたいです)

Armadillo-420 でのデフォルトのユーザーランドコンフィグでは、
netstat は busybox1.00.rc3 のものが使用されます。

busybox1.00.rc3/netstat.c の ソースを見てみたところ、
他プロセスを停止させる処理は無いようです。

また無効なオプション ( -4 ) を指定された際は、
Usage を表示して exit しており、
この間にも 他プロセスを停止させる処理は存在してないようです。

笹山様

細かい話ですが、そのdmp-core-test.cだと先ず有り得ませんが
偶然pが意味ある数値で初期化されると運悪く正常終了します。
pを0で初期化するのも手ですが、単純にarmadillo上で次のような
スクリプトを実行する方が宜しいのでは?

#!/bin/sh
sleep 1; kill -QUIT $$
sleep 100

まぁ、どうしてもsegmentation faultを見たいと言うことでしたら別ですが。

at_takashi.sasayama

2015年4月1日 16時53分

izawa さん

笹山です。

> 細かい話ですが、そのdmp-core-test.cだと先ず有り得ませんが
> 偶然pが意味ある数値で初期化されると運悪く正常終了します。

失礼しました。
仰る通りの問題をサンプルプログラムは抱えていますね。
0 で初期化するべきでした。

> pを0で初期化するのも手ですが、単純にarmadillo上で次のような
> スクリプトを実行する方が宜しいのでは?
> #!/bin/sh
> sleep 1; kill -QUIT $$
> sleep 100

成程です。
core ファイルが正常に出力されるかを確認する場合は、
こちらの方が手早く確認できますね。