IBMiとOracleで嵌り事象に遭遇したので、備忘録として。
突然のセグメンテーション障害(core dumped)
IBMi 環境下のPHPoci8.so
を使用して、ユーザーのPHPアプリケーションテストをしたところ、ある日突然なんのエラーメッセージも出力されず「セグメンテーション障害(core dumped)」となり、PHPアプリケーションが落ちてしまう様になった。エラー時に出力された、スプールは以下の通り。
MCH6801 エスケープ 40 20/09/07 20:04:46.275123 QP2USER2 QSYS *STMT QP2USER2 QSYS *STMT
送信元モジュール. . . . . : QP2API
送信元プロシージャー. . . : runpase_common__FiPvT2
ステートメント. . . . . . : 5
送信先モジュール. . . . . : QP2API
送信先プロシージャー. . . : runpase_common__FiPvT2
ステートメント. . . . . . : 5
メッセージ. . : オブジェクトQPADEV0001USHIDAY 505789のオフセット
X'0000000000000018'のオブジェクト・ドメインまたは記憶域保護エラー。
原因--プログラムは,ブロック化された命令を使用しようとしたか,システム・ド
メイン・オブジェクトをアクセスしようとしたか,あるいは保護されたページを間
違って使用しようとしました。違反タイプは4です。違反タイプは以下のタイプ
のエラーを示します。1-オブジェクト・ドメイン違反。2-テスト・ポインター
・ターゲット・アドレス可能度(TESTPTA)違反。3-読み取り保護エラー。
4-書き込み保護エラー。5-実行保護エラー。空間クラスはX'08'です。空間
クラスは,記憶域保護エラーまたは空間ポインターのTESTPTA違反の空間のタイ
プを示します。00- 1次関連空間(空間オブジェクトを含む)。01- 2次関連空
間。02-自動記憶域用の暗黙の処理空間。03-静的記憶域用の暗黙的処理空間。
04-活動化グループに基づくヒープ記憶域の暗黙の処理空間。05-定数空間。
06-ハンドルに基づくヒープ記憶域用の空間。07-テラスペース・オフセット
X'0000000000000018'。08- I5/OS PASEメモリー・アドレス
X'0000000000000018'のテラスペース。X'80000000000000000000040050000018'は
,保護エラーまたは空間ポインターのTESTPTA違反の記憶域へのポインターです
。一部の違反は,低システム機密保護レベルで抑制されている場合があります。
CPFB9C6 エスケープ 40 20/09/07 20:04:46.438840 QP2FORK QSYS *STMT QP0ZPCPN QSYS *STMT
送信元モジュール. . . . . : QP2FORK
送信元プロシージャー. . . : send_escape__FPcPvUi
ステートメント. . . . . . : 11
送信先モジュール. . . . . : QP0ZPCPN
送信先プロシージャー. . . : Qp0zNewProcess
ステートメント. . . . . . : 278
メッセージ. . : PASE FOR Iが終了しました。シグナル11,エラー・コード
5770SS1 V7R2M0 140418 ジョブ・ログ CSC2015 20/09/07 20:04:46 JST ページ 2
ジョブ名 . . . . . . . . . : QPADEV0001 ユーザー. . . . : USHIDAY 番号 . . . . . . . . . . . : 505789
ジョブ記述 . . . . . . . . : USHIDAYJD ライブラリー. . : USHIDA
MSGID タイプ SEV 日付 時刻 FROM PGM ライブラリー INST TO PGM LIBRARY INST
1。
原因--PASE FOR Iプログラムは,PASE FOR Iシグナル11のため終了しました
。エラー・コード1は,現行ディレクトリーにコア・ファイルが書き込まれたこ
とを示しています。このシグナルは,ジョブ・ログに表示される例外メッセージに
対して作成されている可能性があります。回復手順--エラーを訂正して,要求
を再試行してください。エラーの詳細説明--コア・ファイルが書き込まれてい
る場合には,PASE FOR I 'DBX'コマンドでそれを調べてください。PASE FOR
Iコマンドは,対話式ジョブでプログラムQP2TERMを呼び出すことにより表示され
るコマンド行で入力できます。
CPF24A3 エスケープ 40 20/09/07 20:04:46.439263 QMHSNDPM QSYS 0C79 QLEAWI QSYS *STMT
送信先モジュール. . . . . : QLEDEH
送信先プロシージャー. . . : Q LE leDefaultEh2
ステートメント. . . . . . : 175
メッセージ. . : 呼び出しスタックのカウンター・パラメーターの値が正しくな
い。
原因--呼び出しスタックのカウンター・パラメーターに指定した値3が正しくあ
りません。この値はAPIのパラメーター番号7に指定されました。回復手順-
-呼び出しスタックのカウンター・パラメーターの値を訂正して要求を再試行して
ください。この値は0以上でなければなりませんが,呼び出しスタックの項目数
より大きくすることはできません。
CEE9901 診断 30 20/09/07 20:04:46.439299 QLEAWI QSYS *STMT QP0ZPCP2 QSYS *STMT
送信元モジュール. . . . . : QLETOOL
送信元プロシージャー. . . : Q LE CPF24A3_handler
ステートメント. . . . . . : 9
送信先モジュール. . . . . : QP0ZPCP2
送信先プロシージャー. . . : _CXX_PEP__Fv
ステートメント. . . . . . : *N
メッセージ. . : アプリケーション・エラー。CPFB9C6は,QP0ZPCPNによっ
てステートメント0000000278命令X'0000'で監視されていません。
原因--例外が発生して処理されなかったので,アプリケーションは異常終了しまし
た。未処理例外が送られるプログラムの名前はQP0ZPCPN QP0ZPCPN
Qp0zNewProcessです。プログラムは,このメッセージが送られた時に高水準言語ス
テートメント番号0000000278で停止されました。複数のステートメント番号が表
示された場合には,プログラムは最適化されたILEプログラムです。最適化によ
って単一ステートメント番号を判別することはできません。*Nが値として表示さ
れた場合には,実際の値が使用できなかったことを意味します。回復手順--前
にリストされた低レベル・メッセージを参照して,例外の原因を突き止めてくださ
い。エラーを訂正してから,要求を再試行してください。
CPC1219 完了 50 20/09/07 20:04:46.439427 QWTPITP2 QSYS 0645 *EXT *N
メッセージ. . : このジョブは異常終了した。
原因--このジョブが異常終了する原因となるエラーが起こりました。回復手順-
-このジョブのジョブ・ログで,以前にリストされているメッセージを参照してく
ださい。エラーを訂正して,要求を再試行してください。
結果的には、以前ユーザーは、Oracle 11g
を使用していたのだが、今回から12c
に変更されており、12c
はユーザーに紐付く省略のDefaultプロファイル
のパスワード期限が、180日だった事が原因でした。
事象のまとめ
今回の事象をまとめると以下の通り。
- PHP on IBMi アプリケーションで、Oracle DBに接続。
- 接続時には、
セグメンテーション障害(core dumped)
となり、実行カレントディレクトリにcore
のメモリダンプが吐き出されて異常終了となる。 - Zend Server,コミュニティ版PHPどちらでも同様の現象となる。
- 開発用Windowsで同様の処理をしても、正常に処理される。
- IBMiからJava(JDBC)経由のアプリケーションでは、正常に処理される。
- 旧Oracle 11gに接続先を向けると、正常に処理される。(この辺りで、ようやく12c固有の問題と判断が付きました)
- IBMi上のSQLPlusでは、正常にログイン出来る。(ムムッ、なにやら不穏なワーニング
ORA-28002: the password will expire within 7 days
が...)
./sqlplus user/pwd@hostname:1521/database
SQL*Plus: Release 10.2.0.5.0 - Production on Mon Sep 7 21:49:09 2020
Copyright (c) 1982, 2010, Oracle. All Rights Reserved.
ERROR:
ORA-28002: the password will expire within 7 days
どうも原因は、これのようで、IBMiのoci8.so
またはOracle Instant Client
の何れかが、このワーニングをハンドリング出来ていないのかな?通常なら、7日間の猶予があるようで、それでlocalやJavaは問題が表面化せず動作しているのかもしれません。
解決方法
デフォルトプロファイルのパスワード期限を無期限にするか、対象のプロファイルのパスワードを無期限にします。本来は、デフォルト変えてまうより、アプリケーション接続ユーザー様のプロファイルにするべきでしょうね。
- プロファイルの期限を設定
- アカウントロックを解除/パスワード再設定
# SQLplusで接続する
./sqlplus user/pwd@hostname:1521/database
# 無期限設定
alter profile DEFAULT limit PASSWORD_LIFE_TIME unlimited;
alter profile プロファイル名 limit PASSWORD_LIFE_TIME unlimited;
# 設定確認
SELECT * FROM dba_profiles WHERE PROFILE='DEFAULT' AND RESOURCE_NAME='PASSWORD_LIFE_TIME';
ROFILE
--------------------------------------------------------------------------------
RESOURCE_NAME RESOURCE
-------------------------------- --------
LIMIT
--------------------------------------------------------------------------------
COM INH IMP
--- --- ---
DEFAULT
PASSWORD_LIFE_TIME PASSWORD
UNLIMITED
NO NO NO
Oracleのプロではないので、バージョン変わる時に流儀が変わっていると、嵌ることがよくあります。
因みに、明示的にユーザーをロックしたり、パスワードをExpireさせた時は、oci8.soから「~Loked~」など、メッセージが返され、Coredumped で落ちる事はないので、自然と180日で切れて、猶予期間が存在する時だけ起こる事象かもしれません。