Attempt to free unreferenced scalarとは?! エラーの原因と解決方法を教えてください

このQ&Aのポイント
  • CGI開発中に”Attempt to free unreferenced scalar”エラーが発生しました。具体的な要因や解決策を教えてください。
  • エラーメッセージ「Attempt to free unreferenced scalar: SV 0xXXXXXXX, Perl interpreter: 0xXXXXXX at XXX.cgi line XX.」について、意味が分かりません。解釈や解決策を教えてください。
  • ローカル環境では正常に動作しているCGIが、本番機で”Attempt to free unreferenced scalar”エラーが発生します。具体的な原因と解決方法を教えてください。
回答を見る
  • ベストアンサー

Attempt to free unreferenced scalar とは?

あるCGIを開発しているのですが動作確認してみたところ Attempt to free unreferenced scalar: SV 0xXXXXXXX, Perl interpreter: 0xXXXXXX at XXX.cgi line XX. のようなエラーがでるようになりました。 調べてみると http://perldoc.jp/docs/perl/5.6.1/perldiag.pod > (W) Perl がスカラの参照カウントをデクリメントしようとして、0 になるかを見たところ、既に 0 になっていることがわかりました。これは、既に解放されているべきものであり、実際は、おそらく、解放されたものでしょう。これは、SvREFCNT_dec() が必要以上に呼ばれたか、SvREFCNT_inc() が必要なときに呼ばれなかったか、SV が消滅すべきで無いときに消滅してしまったか、メモリ異常になったことが考えられます。 と書いてあるのですが意味が分かりません。 どなたか主にこのエラーが発生する具体的な要因や解決方法などを 教えていただけないでしょうか。 なお、ローカルの環境(04WebServer+Active Perl v5.10.0 build 1002) では正常に動作するのに本番機(IIS+Active Perl v5.8.8 build 817)で このような現象がでています。 エラーのでている部分のスクリプトは申し訳ありませんが事情で 提示できないのであくまでこういう時に発生するというような情報と 解決策があるだけでよろしいです。 他に必要な情報があれば書いていただいたことはなるべく調べて回答 するようにします(ただし調べきれない場合もあると思います)。 ただ、返事の方が動作確認できない状態になるため1週間後辺りに なります。 よろしくお願いします。

  • Perl
  • 回答数3
  • ありがとう数5

質問者が選んだベストアンサー

  • ベストアンサー
  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.3

これはまたえらく複雑なことをしていますね。 5.10で確認して起きないということであれば、Perlのバグとみてよいかと思います。 5.8→5.10で内部構造的に結構変わっているので、該当するバグのフィックスがあったかどうか というのはわかりません。 sub regex とその中で作っている無名サブルーチンで、同じような my $foobra = shift というパターンをしているのがちょっと気になるといえば気になります。 サブルーチンが増えるというのが気にならないのであれば、 現在無名サブルーチンになっているのを名前をつけて独立したサブルーチンにした上で 置換部で呼び出してみたらどうでしょうか?

pick52
質問者

お礼

あれから調べてみた限りでは http://d.hatena.ne.jp/usuihiro1978/20080107 に関する不具合なのかなと思います。 まだ、根本的に解決できていませんが質問してからずいぶん経って しまったのでいったん締め切って後ほど新たに質問し直そうと思います。 ありがとうございました。

pick52
質問者

補足

どうも、返事が遅くなりました。 > これはまたえらく複雑なことをしていますね。 そうなんですよね。 正規表現はPerlの要の一つなんですけどどうも苦手で...。 (苦手意識があるから余計に難しく感じているのかも) > 5.10で確認して起きないということであれば、Perlのバグとみて > よいかと思います。 > 5.8→5.10で内部構造的に結構変わっているので、該当するバグの > フィックスがあったかどうか > というのはわかりません。 他のPerl 5.10.0で確認はしていないので明確なところは分かりませんが 可能性は高そうです。 すべて確認したのはOSがWinでPerlもActive Perlなので他のPerlでは どうなのかも分かりませんが本番機もWin+Active Perl 5.8.8でしかも 勝手にバージョンアップとかするわけに行かないということもあり、 スクリプトの方を修正せざるを得ない状況です。 最初、本番機でテストしてみようとしたらヘッダを出力しているにも 関わらず何故かヘッダがないと怒られまして何故だろうといろいろ 調べてみるとどうやらPerlが強制終了してそれまでSTDOUTに出力した 内容が消失していたみたいです。 > sub regex とその中で作っている無名サブルーチンで、同じような > my $foobra = shift というパターンをしているのがちょっと気に > なるといえば気になります。 > サブルーチンが増えるというのが気にならないのであれば、 > 現在無名サブルーチンになっているのを名前をつけて独立した > サブルーチンにした上で > 置換部で呼び出してみたらどうでしょうか? my宣言しているので大丈夫なはず...とは思いましたが一応、 やってみました。 しかし、やはり同様のようです。 不思議なのが前回書いたように何かの処理を行ったりprintで不要な 文字列を出力させたりすると発生しなくなったりすることがあると いう点です。 上記にも書いたようにPerlが強制終了しているようなのでやはり Perlのバグの可能性は濃厚です。 と同時に問題の起こっている正規表現部分も実際には意図したとおりに 動いているようなのですが、間違っている可能性が高く自信がないので 同様の動作をしながらもっと適切な書き方があったらよろしくお願い します。 $$str には複数行の文字列が入っていてその中から$patternにマッチ する特定のパターンを抽出し(このパターンは複数行&同一行で複数回 パターンにマッチする可能性あり)それを特定の変数などに置換、 それで変換した結果、そのパターンがあった行がスペースのみになった 時はすべて除去、みたいな感じです。 (一部説明が間違っているかも) 具体的には http://oshiete1.goo.ne.jp/qa4213045.html の質問の 回答から試行錯誤した上で自分で考え出した正規表現なのですが非常に ややこしくなっています。 まだ、上記の質問も締め切っていませんので宜しければそちらも お願いします。

その他の回答 (2)

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.2

特にこれが怪しいというモジュールはないですね。 > 前後で終了させたりして調べてみるとどうやら正規表現でsによって > 文字列を置換した後に問題が起こっているようなのですが見てみても > 問題はなさそうなんです。 どんな感じの置換を行っているんでしょうか? e 修飾子を複数個つけてたりはしていませんか? Perl Internalsについて - Unknown::Programming http://d.hatena.ne.jp/fbis/20080627/1214537750 で紹介されている Internals::SvREFCNT($foo); を使って、問題の正規表現に関連している変数を調べてみてはどうでしょうか?

pick52
質問者

補足

この正規表現が非常にややこしい状態で正規表現での置換は全部 成功しているようなのですが最後に通ったときに何かおかしくなって いるのでメモリ上のデータに何か問題があるのかも知れません。 (サブルーチンにリファレンスでデータを渡してそのサブルーチンの 中でデリファレンスしeで無名サブルーチンを実行しています) なお、以下で回答してからまたあれこれ調べてみてひとつ分かったことが あります。 それはどうやら Perl 5.8.8 でエラーがでているようです。 別の5.8.8がインストールされている環境でも同様のエラーがでました。 この環境のPerlのバージョンを5.10.0にして試したわけではないのですが もしそうならPerl側に問題がある可能性が非常に高く、5.10.0までに 修正されたと見た方がいいのでしょうか。 (本番機は自分のものではなく自由にいじれるわけではないのでPerlの バージョンアップは多分できません) 更に不思議なのが同様の正規表現をパターンマッチでif内で一度判定 させて、その中で置換してやると正常に通るようです。 sub regex { my $str = shift; my $VAR = shift; my $pattern = shift; my $replace = shift; my $func = sub { my $str = shift; my $VAR = shift; my $pattern = shift; my $buf = shift; $str =~ s/$pattern/$@ = ''; $_ = eval(sprintf($buf, map { eval($_); } @_)); $@ ? $@ : $_/egs; if($str =~ /^\s*\n?$/s) { return; } return $str; }; if($$str =~ /((([^\n]*?)$pattern(?=.*))+(\n?))/gs) { # この if を追加 $$str =~ s/((([^\n]*?)$pattern(?=.*))+(\n?))/&$func($1, $VAR, $pattern, @$replace)/egs; } return; } 結果的にこのような感じにしたら取り敢えず今回は正常に動作している ようなのですがなんか面倒だし原因もよく分からず納得いかない状態 で...。 (根本的な原因を理解して取り除かないとまた同様の問題が発生する 可能性が高いというのもありますし) 正規表現部分は結構試行錯誤して自力でやったものなので間違っている 可能性があります(これが原因だったりして...) 正規表現は難しすぎてよく分かりません。

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.1

いくらなんでもこれだけの情報でどうにかしろと言うのは無理と言うものでしょう。 >どなたか主にこのエラーが発生する具体的な要因や解決方法などを >教えていただけないでしょうか。 要はPerlの変数管理がおかしくなってしまったということです。 ・Windows以外のたとえばLinuxをつかったどれかのディストロでも起きるか? ・使っているモジュールには何があるか。特に自作のXS使用のものはあるか ・スレッドを使っているか あたりはどうでしょうか? 純粋に自分がPerlのコードしか書いていない(Cによる拡張を使っていない) のであれば、Perl本体のバグの可能性もあります。

pick52
質問者

補足

えっと、すみません。 現状で使用しているモジュールで分かるのは CGI::Carp File::Spec File::Basename Cwd Tie::IxHash Encode File::Path CGI::Session Data::Dumper のようです。 自作モジュールは使用していません。 一部を除き、ほとんどは標準モジュールであとはスクリプトの下に 置いて use lib でインクルード場所を指定し読み込んでいます。 スレッドは多分使っていないと思います。 (使用しているモジュール内で使用していない限り) 前後で終了させたりして調べてみるとどうやら正規表現でsによって 文字列を置換した後に問題が起こっているようなのですが見てみても 問題はなさそうなんです。 (しかも、何回かその部分を使用しているのですがある一定の タイミングのみ?で起こっているようです) Linuxでの動作確認はできればしたいと思いますが現在、環境を 用意できないのですぐには確認できないと思います。 あとはよく分かりません。

関連するQ&A

  • perlのエラー表示・停止を無効にしたい

    Perlを動かしていると、時々、 Attempt to free unreferenced scalar: SV 0xXXXXXXX, Perl interpreter: 0xXXXXXX at XXX.cgi line XX. という感じのエラーがでてプログラムが停止します。 なぜか理由も分かりませんが、VirtualPC環境の為、OSがフリーズするなどは問題ないですし、データが正常に記録されるよりも、より長時間動いてくれる方が助かるため、こういったエラーを出して、停止しない様にしたいのですが方法はありますでしょうか? どなたがご存知の方がおられましたら教えて頂けないでしょうか。 宜しくお願い致します。

    • ベストアンサー
    • Perl
  • OS X 10.4.7 にアップデートしたらローカルで動作しない

    Mac OS X でローカルでパールが使えるようにしてコードを書いていましたが、OS のアップデートをしたらそれ以前には問題なくブラウザ上で動作していたcgi ファイルが動作しなくなってしまいました。 アップデートする以前に書いたものだけでなく、それ以降に新たに書いたものも同様です。 バージョンはMac OS X 10.4.5 ぐらいから 10.7.7へのアップデートです。 cgiファイルの保存先は、 ライブラリ/WebServer/CGI-Executables と、 ユーザ/(ユーザ名)/サイト/ 内にcgi-bin フォルダを作成して、そこからでもパールが使えるようにした状況で使用していたのですが、その両方共ダメになってしまいました。 ちなみにアップデートした直後は ライブラリ/WebServer/CGI-Executables 内のcgiファイルであれば動作していたのですが、その後再起動(一回目か数回後かはちょっと忘れました・・)したらこちらのディレクトリも動作しなくなったという経緯があります。なにか関係あるでしょうか?

  • JavaAppetについて

    パズルゲームのアプレットと作成しているのですが、ビルドしたら以下のようなエラーが出て、なかなか解決できないので教えてください。 "class"または"interface"がありません(J0020) 式ステートメントは、メソッド呼び出し、インクリメント、デクリメント、または"new"の割り当てが必要です(J0231) 果たしてこれはどのようなエラーでどう解決すればよいのか教えてください。

  • IIS上でフリーCGIが動かない

    Windos2003Server IIS6.0環境で ActivePerl5.8.8 を導入しましたが、 KENTWEBなどで配布されているフリーCGIをブラウザから開くと、 画面が真っ白のまま何も表示されていません。(エラー表示もありません) 以下のテスト用CGIを作成し、フリーCGIと同フォルダに置いてアクセスすると正常動作します。 --------------------------- #!/user/local/bin/perl print "Content-type: text/html\n\n"; print "こんにちわ\n" --------------------------- この現象の原因としてどのようなことが考えられるでしょうか。 ご存知の方がおられましたらご教示ください。

  • ローカル環境でのCGIエラー

    ActivePerlとAn HTTPdでWindowsXP HomeEditionのPC上でCGIを動かそうと思っています。 どちらも最新版をダウンロードしてインストールしました。 ActivePerlに関してはegフォルダ下のexample.plで動作確認が取れています。 An HTTPdに関してはhttp://127.0.0.1以下のURLを指定してページが表示されています。 ですが、htmlからcgiを呼び出そうとすると「ページを表示できません」「サーバーが見つからないか、DNS エラーです。」のエラーが出てしまいます。 試しにcgiファイルをフルパスで指定したのですが同じでした。 ちなみに、簡単なCGIプログラムtest.cgiを作成、サーバにアップして動作を確認しましたがローカルではエラーになります。 また、ローカルでコマンドプロンプトにて c:\usr\local\bin\perl c:\プログラムのパス\cgi-bin\test.cgi と入力すると内容を表示します。 コマンドプロンプトでCGIプログラムのあるcgi-binディレクトリに移動して perl -v と入力するとperlのバージョン情報を表示するので、パスは通っていると思われます。 Au HTTPdのerrors.logには Thu Aug 16 19:21:18 2007 Warning: CGI TerminateProcess 2500 error 5 とりあえず、自分で原因を絞れるであろうところはあたってみたつもりですが、何か見落としていることがあるでしょうか? もしかしたらAu HTTPdに問題があるでしょうか?

    • 締切済み
    • CGI
  • PerのTaintモードエラー

    いつも、参考させて頂きます。 PerlのTaintモードに関しての質問です。 環境:  OS:Windoews XP  WebServer:IIS v5.1  Perl v5.10.0 現象: CGIプログラムにTaintモード(-T)を入れると下記のエラーが発生しております。 エラー内容: 1.ブラウザ:   CGI Error   The specified CGI application misbehaved by not returning a complete set of HTTP headers.   The headers it did return are:   "-T" is on the #! line, it must also be used on the command line at        C:\Inetpub\wwwroot\jimmy\test.cgi line 1.  2.エラーログ   127.0.0.1, -, 2009/05/09, 14:43:50, W3SVC1, XXXX, 127.0.0.1, 15, 286, 485, 502, 0,     GET, /XXXX/test.cgi, -, ソース: #!/usr/local/bin/perl -T print "Content-type: text/html\n\n"; print "Taintモードテスト!"; ※Taintモード(-T)を外すと正常に動作します。 どうしてでしょうか?アドバイスお願い致します。

  • PERL 宣言文 -wについて

    Perl初心者のWEBサーバエンジニアです。 サーバの移行に伴ってCGIファイルが動作していないため、ご相談になります。 【サーバ環境】 perl実行パス      /usr/local/bin/perl シンボリックリンク   /usr/bin/perl => /usr/local/bin/perl ソース記述       #!/usr/bin/perl ヴァージョン      5.8.5 perl実行環境      http://△△△.jp/cgi-bin/ ※apacheのスクリプトエイリアス指定 options +ExecCGI -Include SetHandler cgi-script 上記の環境で、cgiファイルが500internalサーバエラーになる現象が発生しています。 ファイルは以前動作したサーバから引っ張ってきました。 原因を探っていたのですが、cgiファイルのソース記述を #!/usr/bin/perl -w と記述を変更すると正常に動作しました。 -w について 【1度しか出現しない識別子や、初期化されずに参照される変数など、危険、無駄と思われる処理の警告を出力します。実際にはもっとたくさんの種類のチェックをするようです。】 と言う事はわかりましたが、いままで、-wなしで動作していたので、-wなしで動くよう、perlの設定を変更したいとかんがえております。 なにぶんPERL初心者ですので、同様の事象で知見がある方、ご教授を宜しくお願いいたします。

    • ベストアンサー
    • CGI
  • すごく基本的な事なのでしょうが・・わからないんです

    ある人のHPに行こうとすると、次のメッセージが でてきました。  どうすればいいのかわかりません。 どこでどの様な操作をすれば解決するのでしょうか? CGI Error The error was detected while processing this request. Be sure of followings: The CGI script does exist. The permission of CGI script is 755. The Perl path in CGI script is #!/bin/perl. CGIスクリプトの呼び出し中にエラーが発生しました。 下記の点をご確認ください。 ・CGIスクリプトが存在すること。 ・CGIスクリプトのパーミッションが755であること。 ・CGIスクリプトのperlのパスが#!/bin/perlであること。

    • ベストアンサー
    • CGI
  • 掲示板が表示されません

    掲示板を見ようとしたら、  「CGIスクリプトの呼び出し中にエラーが発生し  ました。   下記の点をご確認ください。   ・CGIスクリプトが存在すること。   ・CGIスクリプトのバーミッションが755で   あること。   ・CGIスクリプトのperlのパスが、    #!/usr/local/bin/perl    であること。」 というメッセージが表示されて掲示板を見ることができません。 どおしたら良いでしょうか。

  • 自前サーバでCGIを~

     まずはLAN内だけで掲示板などのCGIを実行できるようにしてみよう、ということでApacheを使ってCGIの設定をしているんですが、ブラウザからCGIファイルを起動してもInternal Server Errorと出てしまいます。よってそれ以前ということで・・・  コマンドラインから「perl test.cgi」のようにCGIファイルを実行してみるとちゃんと動作するんですが、「type -a perl」で検索したフルパスをそのままCGIファイルに「#!/usr/bin/perl」などのように書いても、ファイルがコマンド化されてくれません。でも、perlの実行ファイルは存在していました。  これは、どうすれば解決できるのでしょうか?

専門家に質問してみよう