Является ли объект RegExp в VBScript Thread Safe безопасным при использовании внутри компонента сценариев Windows
Я пытаюсь отследить проблему с устаревшим компонентом сценариев 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
1 ответ
Я не знаю о безопасности потоков в вашем случае. Но, глядя на вашу ситуацию, я бы сказал, что это скорее всего проблема в самом регулярном выражении. Это будет первое, на что я посмотрю. Можно создать регулярное выражение, которое само по себе вызывает переполнение стека или очень и очень длительное время выполнения из-за квантификаторов и перезапусков.
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.)
Теперь объект RegExp, доступный в Windows Script Host, не является pcre, но я считаю, что то же самое поведение должно было бы применяться к нему.
Итак, проверьте свое регулярное выражение на наличие вложенных неограниченных квантификаторов.