VBScript中的RegExp对象在Windows脚本组件中使用时是否线程安全

VBScript中的RegExp对象在Windows脚本组件中使用时是否线程安全,vbscript,wsc,Vbscript,Wsc,我正在尝试跟踪我们使用的旧版Windows脚本组件的一个问题。查看WinDbg中的几个内存转储,我发现很多线程,实际上看起来有50%的应用程序线程都在等待另一个线程完成。此线程有一个长堆栈,位于下面。这个线程正在处理一个RegExp对象,所以我现在的问题是RegExp线程安全吗 当然,它看起来并不是来自所有其他等待它的线程,但我想在我下结论之前确定一下,并努力在网上找到任何真正的信息 vbscript!RegExpExec::PopGreedyStar+3a vbscript!RegEx

我正在尝试跟踪我们使用的旧版Windows脚本组件的一个问题。查看WinDbg中的几个内存转储,我发现很多线程,实际上看起来有50%的应用程序线程都在等待另一个线程完成。此线程有一个长堆栈,位于下面。这个线程正在处理一个RegExp对象,所以我现在的问题是RegExp线程安全吗

当然,它看起来并不是来自所有其他等待它的线程,但我想在我下结论之前确定一下,并努力在网上找到任何真正的信息

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 

我不知道你的情况下线程的安全性。但是,从你的情况来看,我认为这更可能是正则表达式本身的问题。这将是我第一个看到的。由于量词和重新启动,可以创建一个自身导致堆栈溢出或非常长的运行时的正则表达式

发件人:

当一个模式在一个子模式中包含一个无限制的重复时
本身可以无限次重复,使用
原子组是避免某些失败匹配的唯一方法
确实很长时间了。模式
(\D+)*[!?]
匹配无限数量的子字符串,这些子字符串由非-
数字,或包含在中的数字,后跟任意一个!或当它
如果匹配,它运行得很快。但是,如果将其应用于
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
报告失败需要很长时间。这是因为
字符串可以分为内部\D+重复和外部
*重复大量的方法,所有的方法都需要尝试。(修订)
示例末尾使用[!?]而不是单个字符,因为
PCRE和Perl都有一个允许快速失败的优化
当使用单个字符时,他们会记住最后一个字符-
匹配所需的ter,如果不存在,则提前失败
在字符串中。)
现在,Windows脚本主机中可用的RegExp对象不是pcre,但我相信必须对其应用相同的行为

所以,检查正则表达式中嵌套的无限量词

   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.)