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