2011-02-09 6 views
0

私が使用しているレガシーWindows Scripting Componentの問題を追跡しようとしました。 WinDbgのいくつかのメモリダンプを見ると、スレッドの数が多いことがわかりました。実際には、アプリケーションスレッドの50%が別のスレッドが完了するのを待っているようです。このスレッドは以下の長いスタックを持っています。このスレッドはRegExpオブジェクトでいくつかの作業をしているので、私の質問はRegExpスレッドセーフです。RegExpオブジェクトは、Windowsスクリプトコンポーネント内で使用する場合、VBScriptスレッドセーフです。

確かに、他のスレッドがそれを待っているわけではないようですが、私は結論に飛びつき、実際の情報をオンラインで見つけるのに苦労しています。

vbscript!RegExpExec::PopGreedyStar+3a  
vbscript!RegExpExec::FExecAux+639  
vbscript!RegExpExec::FExec+1f  
vbscript!RegExpExec::Exec+5a0  
vbscript!RegExpExec::ReplaceUsingString+2d  
vbscript!CRegExp::OrigReplace+14e  
vbscript!CRegExp::Replace+80  
oleaut32!DispCallFunc+16a  
oleaut32!CTypeInfo2::Invoke+234  
vbscript!CRegExp::Invoke+24  
vbscript!IDispatchInvoke2+b2  
vbscript!IDispatchInvoke+59  
vbscript!InvokeDispatch+13a  
vbscript!InvokeByName+42  
vbscript!CScriptRuntime::RunNoEH+22b2  
vbscript!CScriptRuntime::Run+62  
vbscript!CScriptEntryPoint::Call+51  
vbscript!CScriptRuntime::RunNoEH+1e02  
vbscript!CScriptRuntime::Run+62  
vbscript!CScriptEntryPoint::Call+51  
vbscript!CSession::Execute+c8  
vbscript!NameTbl::InvokeEx+516  
scrobj!DoInvoke+2c  
scrobj!NameTable::InvokeEx+e6  
scrobj!ComDispatchEx::InvokeEx+25  
scrobj!DoInvoke+2c  
scrobj!InvokeMember+a3  
scrobj!NameTable::InvokeEx+aa  
scrobj!ComDexHandler::Inner::InvokeEx+25  
vbscript!IDispatchExInvokeEx2+a9  
vbscript!IDispatchExInvokeEx+56  
vbscript!InvokeDispatch+101  
vbscript!InvokeByName+42  
vbscript!CScriptRuntime::RunNoEH+234c  
vbscript!CScriptRuntime::Run+62  
vbscript!CScriptEntryPoint::Call+51  
vbscript!CScriptRuntime::RunNoEH+1bbd  
vbscript!CScriptRuntime::Run+62  
vbscript!CScriptEntryPoint::Call+51  
vbscript!CSession::Execute+c8  
vbscript!NameTbl::InvokeEx+516  
vbscript!IDispatchExInvokeEx2+a9  
vbscript!IDispatchExInvokeEx+56  
vbscript!InvokeDispatch+101  
vbscript!InvokeByName+42  
vbscript!CScriptRuntime::RunNoEH+234c  
vbscript!CScriptRuntime::Run+62  
vbscript!CScriptEntryPoint::Call+51  
vbscript!CScriptRuntime::RunNoEH+1bbd  
vbscript!CScriptRuntime::Run+62  
vbscript!CScriptEntryPoint::Call+51  
vbscript!CScriptRuntime::RunNoEH+1bbd  
vbscript!CScriptRuntime::Run+62  
vbscript!CScriptEntryPoint::Call+51  
vbscript!CScriptRuntime::RunNoEH+1bbd  
vbscript!CScriptRuntime::Run+62  
vbscript!CScriptEntryPoint::Call+51  
vbscript!CSession::Execute+c8  
vbscript!NameTbl::InvokeEx+516  
vbscript!IDispatchExInvokeEx2+a9  
vbscript!IDispatchExInvokeEx+56  
vbscript!InvokeDispatch+101  
vbscript!InvokeByName+42  
vbscript!CScriptRuntime::RunNoEH+234c  
vbscript!CScriptRuntime::Run+62  
vbscript!CScriptEntryPoint::Call+51  
vbscript!CScriptRuntime::RunNoEH+1beb  
vbscript!CScriptRuntime::Run+62  
vbscript!CScriptEntryPoint::Call+51  
vbscript!CSession::Execute+c8  
vbscript!COleScript::ExecutePendingScripts+144  
vbscript!COleScript::SetScriptState+14d 

答えて

0

私はあなたのケースでスレッドの安全性について知らない。しかし、あなたの状況を見て、私はそれが正規表現自体の問題になる可能性が高いと思います。それが私が見る最初のことです。数量化と再起動のためにスタックオーバーフローや非常に長いランタイムを引き起こす正規表現を作成することは可能です。 the pcre man pageから

When a pattern contains an unlimited repeat inside a subpattern that 
    can itself be repeated an unlimited number of times, the use of an 
    atomic group is the only way to avoid some failing matches taking a 
    very long time indeed. The pattern 

    (\D+|<\d+>)*[!?] 

    matches an unlimited number of substrings that either consist of non- 
    digits, or digits enclosed in <>, followed by either ! or ?. When it 
    matches, it runs quickly. However, if it is applied to 

    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 

    it takes a long time before reporting failure. This is because the 
    string can be divided between the internal \D+ repeat and the external 
    * repeat in a large number of ways, and all have to be tried. (The 
    example uses [!?] rather than a single character at the end, because 
    both PCRE and Perl have an optimization that allows for fast failure 
    when a single character is used. They remember the last single charac- 
    ter that is required for a match, and fail early if it is not present 
    in the string.) 

は今、Windowsスクリプトホストで利用可能なRegExpオブジェクトは、PCREはありませんが、私は同じ動作がそれに適用しなければならないと考えています。

したがって、正規表現でネストされた無制限数量を確認してください。

+0

素晴らしい点は、まずこの点を見てみましょう – MJJames

関連する問題