nDiki : 標準エラー出力

2005年3月11日 (金)

wxPerl で daemon モニタ

Perl で書いた HTTP daemon 形式のシステムがあるのだが、Windows ユーザにとってはコマンド プロンプトからコマンドラインオプションを指定しての起動は繁雑でよろしくないらしい。

以前から管理用のGUIをつけようと思っていたのだが、現在の daemon プログラムにGUIをつけるとするとマルチスレッド化にしなければならないとか、そういう頭があって後まわしにしていた。

今回、まずはランチャと daemon のログモニタというレベルでGUIを作ってみることにした。 wxPerlランチャを作ってそこから子プロセスとして daemon を起動するという形式。 ランチャ側のアイドルループで、daemon の標準出力・標準エラー出力を読み出して表示するというもの。Linux 上ではうまく動いた。

  • Wx::Process でプロセスオブジェクトを生成
  • Wx::Process::Redirect() で、I/Oを取れるようにする。
  • Wx::ExecuteCommand() や Wx::ExecuteArgs() で daemon を起動。Wx::Process のインスタンスに結びつける。
  • EVT_IDLE でアイドルイベントハンドラの中で Wx::Process::GetInputStream、Wx::Process::GetErrorStream からの読み出しを行い defined ならば、UI側で表示。
  • daemon の終了がしたかどうかは EVT_END_PROCESS で捕捉。

といった感じ。

[ 3月11日全て ]

2006年8月7日 (月)

第13回 社内 Perl 勉強会

リャマ本を使用した社内 Perl 勉強会の13回目を開催。今日は6人。

今日は「初めてのPerl 第3版」第14章「プロセス管理」が範囲。

Perl が glue としての真価を発揮できる章である。

今回の反省点

system、exec、パイプオープン、`...`、標準エラー出力リダイレクト(2>)、STDOUT/STDERR の再オープンなど出席者によって回答がバラけて、今回ははからずも効果的であった (問題がらさすがに fork はいなかった)。

Windows では回答しづらい課題かと思っていたが、思ったより問題なく実行できていたようである。

Windows 上の date コマンドで、曜日を表示させる方法について1人だけ気がついた人がいて他の人が悔しがっていた。

[ 8月7日全て ]

2006年12月15日 (金)

Perl テストスクリプトの中で標準エラー出力を一時的に止める

make test で実行するテストスクリプトの中で、標準エラー出力を止めたい場合がある (わざとエラーを起こす時など)。

Perl 5.8.8 の ExtUtils/MM_Unix.pm を参考に

  {
    local *STDERR_COPY;
    my $duped = 0;
    $duped = 1 if open(STDERR_COPY, '>&STDERR');
    open(STDERR, '> ' . File::Spec->devnull()) if $duped;
    my $result = `$command`;
    my $status = $?;
    open(STDERR, '>&STDERR_COPY') if $duped;
  }
  warn "This message is printed to STDERR\n";

としてみた。 LinuxWin32 ではとりあえずうまくいって動いている。

追記

(open が2引数なのは、当時古い Perl バージョンでも動くように書いたから)


[ Perl テストスクリプトの書き方 ]

[ 12月15日全て ]

2011年2月21日 (月)

Visual C++ Win32 コンソールアプリケーションへのメモリリーク検出の埋め込み

Visual C++ 2005 で開発のプログラムがどうもメモリリークしているっぽい。 メモリリーク検出を仕込む方法のメモ。

stdafx.h

デバッグバージョンのヒープ割り当て関数を使うようにするマクロ定義と crtdbg.h のインクルードをする。 メモリリーク情報ダンプの際にレポートにファイル名と行番号が出るように new を書き換えるマクロを定義する。

 // デバッグバージョンのヒープ割り当て関数を使うようにする。
 #ifdef _DEBUG
 #define _CRTDBG_MAP_ALLOC
 #include <stdlib.h>
 #include <crtdbg.h>
 #endif

 // _CRTDBG_MAP_ALLOC に関係なくプリコンパイルしたいもの。
 // かつ new を書き換えるとコンパイルが通らなくなるヘッダファイル群。
 #include <string>

 #ifdef _DEBUG
 // プリコンパイルするほどではないけど、
 // new を書き換えるとコンパイルが通らなくなるヘッダファイル群。
 // 例えば。
 #include <map>

 #define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
 #endif

 // プリコンパイルしていもの。
 #include <myproj/utility.h>

main 関数

終了時にメモリリーク情報をダンプさせるようにする。 また、コンソールアプリケーションの標準エラー出力にレポートが出力されるように設定する。

 int main(int argc, char* argv[]) {
   // 終了時にメモリリーク情報をダンプさせる。
   _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);


   // レポートをファイルに書き出させる。
   _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
   _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
   _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);

   // レポートを標準エラー出力に出力させる。
   _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
   _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
   _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);

   // 処理を開始。
   ...
 }
[ 2月21日全て ]

2013年10月22日 (火)

Capture::Tiny で Perl テストスクリプトの中で標準エラー出力を一時的に止める

意図的に出していて問題のない標準エラー出力への警告などをテスト実行(prove)時には出さないようにしたいというのはままある。で話題になった時にずいぶん昔にやった方法を紹介したりするのだけれど、まあ毎回自前で dup するのもということで CPAN モジュール探した。

期待する標準エラー出力への出力かどうかのテストをするなら Test:: 系をだけれど、ここでは単純に抑制したいだけなので Capture::Tiny で良いかな。

なお標準エラー出力をまるっと止めると、出ることが意図されていない警告にも気がつかなくなるので注意を。

 #!/usr/bin/perl

 use warnings;
 use strict;

 use Test::More;
 use Capture::Tiny qw/capture_stderr/;

 sub warn_function {
   warn "WARN FUNCTION";
   return 1;
 }

 sub warn_command {
   `echo "WARN COMMAND" >&2`;
   return 1;
 }

 sub uuv_function {
   my $undef_var;

   # Use of uninitialized value
   return $undef_var ne "dog";
 }

 subtest capture_stderr => sub {
   capture_stderr sub {
     ok warn_function;
   };

   capture_stderr sub {
     ok warn_command;
   };

   capture_stderr sub {
     ok uuv_function;
   };

 };

 done_testing;

[ Perl テストスクリプトの書き方 ]

[ 10月22日全て ]

About

Naney Naneymx

Naney (なにい) です。株式会社MIXIで SNS 事業の部長をしています。

※本サイトの内容は個人的見解であり所属組織とは関係ありません。

Process Time: 0.022421s / load averages: 0.38, 0.38, 0.35