LoginSignup
0
0

More than 5 years have passed since last update.

Perl CGI 本当は怖い eval内のループ処理

Last updated at Posted at 2017-04-22

Perlではよく例外処理の代わりにeval を利用していると思います。

私はいつもこんなコードを書いてCGIで実行していました。
※ひとまずコードへのツッコミは無しで^^

eval {
    $sth = $dbh->prepare(
        "ほにゃららSQL"
    );
    $sth->execute;
    for(my $i=0; $i<$sth->rows; $i++){
        my @row = $sth->fetchrow_array;
        $data[$i]{id} = $row[0];
        $data[$i]{name} = $row[1];
    }
    $sth->finish;
};

このコードはSQLがエラー無く通った場合、何事もなく処理されます。
しかし、万が一、生成されたSQL文の文法エラーやMySQLサーバーの異常などで $dbh->prepare() が失敗した場合、どんなことが起きるかというと・・・

eval関数によってエラーが無視され、メモリを圧迫、放っておくとHTTPDのエラーログが膨大なサイズに膨れ上がって、しまいにはサーバーがダウンします。

こんなくだらないエラーログだけで28GBまで膨れ上がったerror.logファイル
image

原因は単純なコードミス
何よりダメなのは$sth->prepareが失敗している可能性があるにもかかわらず、$dbh->executeして、さらにはforループの条件式に$sth->rowsを参照している事。
しかし、$sth->rowsは基本的に参照できないときには-1を返すので、固定SQLなどの絶対失敗しないSQLしかテストしていない場合、このエラーに気づくことはありません。

気をつけましょう。そしてみんなごめんなさい。

0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0