2024/08/19

憑いてる? 見えてはいけないものが見える !?

お盆休み返上で、『DXL 拡張ライブラリをリリースします!』で紹介した LotusScript のライブラリを一心不乱に開発していました。その時いくつか不思議な事象に見舞われました。連発して発生しましたので、冷や汗がでまくりました。お盆だからなのかはわかりませんが、きっと”何か”が降りてきたのだと思います...

今回はそんな摩訶不思議な体験のレポートです。


エージェントがハングアップ

エージェントにライブラリを組み込みテストを行っていました。ライブラリを少しアップデートした後、テストしたところ、エージェントがハングアップするようになりました。

Ctrl+Break を連打しても実行が止まりません。まるでゾンビ化したようです。

仕方がないので、[HCL Notes の診断データを収集して HCL Notes を終了する]を実行したところ、無事ゾンビは退治できました。nsd は最強ですね。でも、もう一度実行したら、また発生します。起動したてのクリーンな環境でもハングアップ。何度実行しても同じです。OS を再起動しても症状は変わりません。

Ctrl+Break 無効化するゾンビのようです。

突然発生したので狼狽しましたが、デバッガで確認したら原因がわかりました。虫(デバッガ)はゾンビに有効なアイテムのようです。デバッガは素晴らしいですね!


のっぺらぼうなデバッガ !?

次の不思議体験は、先ほどの救世主 ”デバッガ” が魂を抜かれた話です。

デバッガを有効にして、テストエージェントを実行します。すると、デバッガは起動するのですが、中身が空っぽです。オブジェクトやイベントなど何も表示されません。デバッガは動こうとしているのに、大いなる力に吸い取られているようです...

ただ、完全に憑依されたわけではようです。かろうじて[停止]や[デバッガの終了]は利用できるので助かりました...。

ちなみに、メッセージボックスを仕込んでも何も表示されません。どうやら、この現象が発生するとスクリプトは全く実行されていないようです。これだと調査しようがありません...。


見えてはいけないものが見える !?

続いては、ライブラリのバグ修正を行っている際に発生しました。霊感は強い方ではないのですが『見えてはいけないものが見える』んです。

エージェント内の関数ではなく、ライブラリ内にある同名の関数を指しています !?

ライブラリ開発においては、変数や関数のスコープを意識して開発しています。インターフェースではないスクリプトライブラリ内の関数は、外部からアクセスできないように Private 化しています。

ところが、見えているんです! しかもコンパイルエラーも出ません!!

しかも、この現象、先ほどののっぺらぼうと徒党を組んで出現しました。実行もデバッグもできないので、具体的な調査や切り分けができず、ただただ狼狽するだけでした...。


持ってたわけではないので一安心

立て続けにこんな現象が発生したので、何かの祟りかと思いましたが、お盆が明る頃には原因が見えてきました。すべて理由がある現象でした。”持ってる”わけではなかったので安心しました。

さて、それぞれの現象、原因はわかりますか?

順番に確認しましょう。


ハングアップの理由

現象を端的に発生させるサンプルコードを作成しました。これは完全なバグです。

Option Declare

Sub Initialize
   Call xSample()
End Sub

Function xSample()
   Dim i As Integer
   On Error GoTo Label_Err
   i = CInt("a")
Label_Exit:

Label_Err:
   Resume Label_Exit
End Function

デバッグモードで実行したときの動作は次の通りでした。

デバッグモードで動作を確認するとすぐわかりますね。

原因は Label_Exit: の後ろに Exit Function を忘れていることです。これが原因となってエラー処理で永久ループを起こしていました。 

このような状況になった場合、デバッグモードではない通常実行では Ctrl + Break でエージェントを強制終了ができないようです(停止できる場合もあるようです)。


ちなみに実際のプログラムでは、i = CInt("a") に相当する型の不一致エラーを発見し、これを修正してこの関数の調査を終わっていました。それが原因で、Exit Function の記述漏れの発見に手間取ってしまいました。

エラー処理や While ループなど、永久ループの可能性がある場合は、先に構造をを定義しておくべきですね。実際の処理を記述し始めるとついつい忘れてしまいます。


なお、この現象については技術情報が公開されています。

LotusScript のエージェントがループしてしまった際に Ctrl + Break で中断できません


のっぺらぼうはだれが召喚した?

まずは、再現プログラムです。この現象の再現にはメインにプログラムとは別にスクリプトライブラリが必要です。

◇ エージェント

Option Declare
Use "lsPsychics"

Sub Initialize
   Dim ns As New NotesSession
   MsgBox ns.CurrentAgent.Title
End Sub

◇ lsPsychics スクリプトライブラリ

Option Declare

Sub Initialize
   Call xInitMe()
End Sub

Function xInitMe()
   Dim i As Integer
   i = CInt("a")
End Function


メインルーチンは、自分自身の DB 名をメッセージボックスで表示するだけの単純なプログラムで、ここに間違いはありません。

のっぺらぼうを召喚しているのは、組み込んでいる lsPsychics スクリプトライブラリでした。このライブラリ、Initialize で関数 xInitMe を呼び出して初期化しています。ただ、この関数内にバグがありエラーが発生しています。

実は、デバッガの仕様でスクリプトライブラリの Initialize はデバッグされません。この現象は、以下の通り技術情報が公開されていました。

Script Library の Sub Initialize 内のコードがデバッグできません

ちなみに、ライブラリの Initialize 内に Stop を記述するとデバッグできるとのことです。


見えないものが見えたのはバグ

この現象が発生するサンプルコードです。Use で呼び出している lsPsychics スクリプトライブラリは前述のままとします。

Option Declare
Use "lsPsychics"

Sub Initialize
   Call xInitMe()
End Sub

Function xInitMe()
   'エージェントの初期化処理
End Function

この状態で Initialize の xInitMe 関数のポップアップヘルプを表示すると lsPsychics スクリプトライブラリを参照しているかのように表示されます。

実際に実行すると、正常にエージェント内のものが実行されます。また、エージェント内の xInitMe 関数を削除するとコンパイルエラーが出ますので、言語仕様的な問題はありません。単にデザイナーのポップアップヘルプのバグということになります。

この現象も技術情報が公開されていました。

Private の 関数やサブルーチンが他のスクリプトライブラリから参照できてしまう


やっぱりなにか ”持っている” ??

すべての現象はそれぞれ明確な原因がありました。ここにまとめたように、単純化した再現プログラムを作成でき、システム的な要因であることがわかりました。

ただ、それぞれの原因を見るとかなりレアな現象だと思います。それが同時多発的に絡み合って発生するなんて、何か ”持っている” のか何かに ”取り憑かれた” のかもしれませんね...

 

0 件のコメント:

コメントを投稿