Perl 本体が落ちる

Windows 7 上で Perl を実行すると Perl.exe が初めてクラッシュした。思い当たることがなく、同じスクリプトFreeBSD 上で実行すると Perl がクラッシュしてコアダンプを吐き出した。

 % tail -f /var/log/messages
Nov 18 13:43:49 myhost kernel: pid 83986 (perl5.12.4), uid 1001: exited on signal 11 (core dumped)

Windows 7 も同様にイベントログにエラーが出されている。

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
  <Events>
    <Event xmlns='http://schemas.microsoft.com/win/2004/08/events/event'>
      <System><Provider Name='Application Error'/>
      <EventID Qualifiers='0'>1000</EventID>
      <Level>2</Level>
      <Task>100</Task>
      <Keywords>0x80000000000000</Keywords>
      <TimeCreated SystemTime='2011-11-18T03:17:59.000000000Z'/>
      <EventRecordID>11391</EventRecordID>
      <Channel>Application</Channel>
      <Computer>MY-PC.local</Computer>
      <Security/></System>
      <EventData>
        <Data>perl.exe</Data>
        <Data>5.12.3.1204</Data>
        <Data>4d531b74</Data>
        <Data>mysql.dll</Data>
        <Data>0.0.0.0</Data>
        <Data>4e336678</Data>
        <Data>c0000409</Data>
        <Data>000000000000dde9</Data>
        <Data>1388</Data>
        <Data>01cca5a0a81a80ef</Data>
        <Data>C:\Perl64\bin\perl.exe</Data>
        <Data>C:\Perl64\site\lib\auto\DBD\mysql\mysql.dll</Data>
        <Data>e9f97a7f-1193-11e1-aaf1-f04da2dbd192</Data>
      </EventData>
      <RenderingInfo Culture='ja-JP'>
        <Message>障害が発生しているアプリケーション名: perl.exe、バージョン: 5.12.3.1204、タイム スタンプ: 0x4d531b74
          障害が発生しているモジュール名: mysql.dll、バージョン: 0.0.0.0、タイム スタンプ: 0x4e336678
          例外コード: 0xc0000409
          障害オフセット: 0x000000000000dde9
          障害が発生しているプロセス ID: 0x1388
          障害が発生しているアプリケーションの開始時刻: 0x01cca5a0a81a80ef
          障害が発生しているアプリケーション パス: C:\Perl64\bin\perl.exe
          障害が発生しているモジュール パス: C:\Perl64\site\lib\auto\DBD\mysql\mysql.dll
          レポート ID: e9f97a7f-1193-11e1-aaf1-f04da2dbd192
      </Message>
      <Level>エラー</Level>
      <Task>アプリケーション クラッシュ イベント</Task>
      <Opcode>情報</Opcode>
      <Channel></Channel>
      <Provider></Provider>
      <Keywords>
        <Keyword>クラシック</Keyword>
      </Keywords>
    </RenderingInfo>
  </Event>
</Events>

mysql.dll の名称が出ていたので、DBD::MYSQL のアップデートを施しても、クラッシュが治らない。
ほぼ半日をかけたところで、ソースコードに誤りがあることに気が付いた。プリペアードステートメントにバインドするパラメータの型付けが間違っていた。

my $sth = $dbh->prepare('INSERT INTO `my_db` (`timestamp`, `message`) VALUES (?, ?);');
$sth->bind_param(1, $timestamp, SQL_VARCHAR);
$sth->bind_param(2, $strings,   SQL_INTEGER);
eval{ $sth->execute };
...

というようにINT型である `timestamp` には SQL_VARCHA を指定し、`message` には SQL_INTEGER を指定していたためだった。
指定を間違えていた場合、warn や die が発生するのではなく、Perl そのものがクラッシュするとは思わなかった。
初めての経験とはいえ、これまでよくも同じような間違えをこれまでしなかったものだと思った。