这段代码加上程序就会卡死,一晚上头发都白了,也没弄明白
本帖最后由 冥界3大法王 于 2023-5-17 22:55 编辑{:301_974:}{:301_974:}{:301_974:}
if (FilePath.Text <> '') and (Check_Module.Checked = True) then
begin
//ShowMessage('复选框勾选的情况');
while not DirectoryExists(FilePath.Text) do
begin
Titles := TStringList.Create;
try
EnumWindowsTitles(Titles);
for I := 0 to Titles.Count - 1 do
begin
// ShowMessage('x64dbg的窗口标题是' + Titles);
match := TRegEx.match(Titles, '(?<=模块:\s).*(?=-\ 线程)'); //这里可以外部再弄个Edit防错处理
if match.Success then
begin
ShowMessage(match.Value); //能成功执行到这里,但是。。。这后面有问题啊~~
if Pos(match.Value, Exclusion_list.Text) > 0 then//如二者相同,则说明找到了与已知列表模块相同的,则不StepOver【包含指定字符串对比没错啊。。。】
begin
DbgCmdExec('StepOver');
end
else
begin
DbgCmdExec('StepIn');
end;
end
else
begin
ShowMessage('正则表达式竟然匹配不成功哟~~');
end;
end;
finally
Titles.Free;
end;
end;
end; if else 层次看不清楚,截个层次分明的图看看 本帖最后由 冥界3大法王 于 2023-5-17 23:09 编辑
blfiag 发表于 2023-5-17 22:54
if else 层次看不清楚,截个层次分明的图看看有点长啊。
ming bai le , gou ri desou gou wu bibu shang ping le .
bianli 's time istoo Short ! 这段代码可能会卡死的原因是在 DirectoryExists(FilePath.Text) 返回 false(即目录未找到)时,将会初始化一个 TStringList 对象 Titles,并循环遍历当前打开的窗口,并将每个窗口的标题进行正则匹配,但是如果没有找到与正则表达式匹配的窗口标题,则会一直等待直到找到匹配项或程序被中止。
为了避免程序卡死,可以考虑增加超时或者退出条件。例如,可以添加一个计数器,在达到一定次数后强制退出循环,像这样:
var
count: integer;
begin
count := 0;
while (not DirectoryExists(FilePath.Text)) and (count < 10) do // 在未打开文件路径或计数器计数到 10 时退出循环
begin
Inc(count);
Titles := TStringList.Create;
try
EnumWindowsTitles(Titles);
for I := 0 to Titles.Count - 1 do
begin
// ...
end;
finally
Titles.Free;
end;
end;
end;
内容是搜来的 你这个是循环啊 孤狼微博 发表于 2023-5-17 23:05
这段代码可能会卡死的原因是在 DirectoryExists(FilePath.Text) 返回 false(即目录未找到)时,将会初始化 ...
@孤狼微博
试过了,不能使用
sleep会卡死线程
使用timer后期也会卡死调试器
后来使用的delay函数解决的
刚才找到原因了,因为遍历窗口的时间太短了,加了delay(500)就正常了。 @孤狼微博
还一个办法,再设一个全局热键,用于暂停。 有几个原因可能导致代码执行卡顿:
[*]目录存在性检查循环:代码中使用了一个while循环来检查指定的目录是否存在。如果目录不存在,循环会一直执行,直到目录存在为止。这可能会导致程序在目录不存在的情况下一直卡在这个循环中,造成性能问题。
[*]窗口枚举和正则表达式匹配:代码中使用了窗口枚举和正则表达式匹配来获取特定窗口的模块名称。如果系统中有大量的窗口或窗口标题的正则匹配比较耗时,那么这部分操作也可能导致卡顿。
[*]ShowMessage函数调用:代码中使用了ShowMessage函数来显示调试或提示信息。如果在循环中频繁调用ShowMessage函数,它会阻塞代码的执行,导致程序卡顿。
为了解决这些问题,你可以考虑以下优化措施:
[*]考虑添加适当的超时机制来限制目录存在性检查的时间,避免无限循环。
[*]如果可能,优化窗口枚举和正则表达式匹配的过程,使其更加高效。
[*]尽量减少在循环中使用ShowMessage函数调用,或者考虑使用日志记录等方式代替。
[*]检查代码中是否存在其他性能瓶颈或大量的重复操作,以便进行优化。
最好的优化策略取决于你的具体需求和代码的上下文。如果问题仍然存在,你可能需要进一步分析代码和执行环境,以找出性能瓶颈并进行相应的优化。
GPT的回复 同意楼上,感觉你的两个while循环有可能出问题,为何不用if,而是循环判断? 本帖最后由 Event 于 2023-5-18 00:38 编辑
看起来是在一个循环中等待文件路径(FilePath.Text中的)存在。如果该路径不存在,它会进入循环,枚举Windows标题
附上GPT4的分析:
一种可能的卡死原因是这个while循环,当文件路径不存在时,程序会陷入一个无限循环。假如文件路径一直不存在,或者在这段时间内没有被其他程序或用户创建,那么代码将一直执行这个循环,导致看上去像是“卡死”。
如果这个文件路径的存在性是你的代码运行的关键,那么你可能需要做一些调整:
提供一个超时机制,如果文件路径在一定时间内仍不存在,就跳出循环。
提供一个用户反馈机制,告知用户文件路径不存在,并让他们有机会更正或创建这个路径。
检查你的代码是否有可能在其他地方创建或更正这个文件路径。如果有,确保这部分代码能在适当的时间内运行。
另外,注意到你在代码中使用了正则表达式来进行模式匹配,如果正则表达式的复杂性或输入字符串的长度过大,也可能造成性能问题,但是在这个例子中,这个问题似乎相对较小。
```pascal
if (FilePath.Text <> '') and (Check_Module.Checked = True) then
begin
var LoopCount: Integer := 0;
const MaxLoopCount: Integer := 1000; // 可以根据需要调整这个值
while (not DirectoryExists(FilePath.Text)) and (LoopCount < MaxLoopCount) do
begin
Inc(LoopCount);
Titles := TStringList.Create;
try
EnumWindowsTitles(Titles);
for I := 0 to Titles.Count - 1 do
begin
match := TRegEx.match(Titles, '(?<=模块:\s).*(?=-\ 线程)');
if match.Success then
begin
if Pos(match.Value, Exclusion_list.Text) > 0 then
begin
DbgCmdExec('StepOver');
end
else
begin
DbgCmdExec('StepIn');
end;
end
else
begin
ShowMessage('正则表达式竟然匹配不成功哟~~');
end;
end;
finally
Titles.Free;
end;
end;
if LoopCount >= MaxLoopCount then
begin
ShowMessage('超时: 文件路径 "' + FilePath.Text + '" 不存在');
end;
end;
```