【发布时间】:2011-02-05 20:38:49
【问题描述】:
我在 StackOverflow.com 上发布了我的 Stack Overflow 问题。最好的讽刺!
无论如何。我在我的 SkypeReply 事件处理程序上调用这个过程,它被触发了很多:
Procedure OnCategoryRename;
Var
CategoryID : Integer;
sCtgName : String;
Begin
if (AnsiContainsStr(pCommand.Reply,'GROUP')) and (AnsiContainsStr(pCommand.Reply,'DISPLAYNAME')) then
begin
sCtgName := pCommand.Reply;
Delete(sCtgName,1,Pos('GROUP',sCtgName)+5);
CategoryID := StrToInt(Trim(LeftStr(sCtgName,Pos(' ',sCtgName))));
sCtgName := GetCategoryByID(CategoryID).DisplayName; // Removing THIS line does not produce a Stack Overflow!
ShowMessage(sCtgName);
end;
这样做的目的是遍历我的 Skype 群组列表,以查看已重命名的群组。 AFAIK 这并不重要,因为我的 S.O 已被追踪到出现在 here
Function GetCategoryByID(ID : Integer):IGroup;
Var
I : Integer;
Category : IGroup;
Begin
// Make the default result nil
Result := nil;
// Loop thru the CUSTOM CATEGORIES of the ONLY SKYPE CONTROL used in this project
// (which 100% positive IS attached ;) )
for I := 1 to frmMain.Skype.CustomGroups.Count do
Begin
// The Category Variable
Category := frmMain.Skype.CustomGroups.Item[I];
// If the current category ID returned by the loop matches the passed ID
if Category.Id = ID then
begin
// Return the Category as Result (IGroup)
Result := Category;
// Exit the function.
Exit;
end;
End;
End;
当我在 Result := Category; 处设置断点时;和单步通过,这两条线被一遍又一遍地执行,紧随其后!
当我在第一个代码 sn-p 中注释掉 sCtgName := GetCategoryByID(CategoryID).DisplayName; 时,没有溢出,消息被显示一次它应该。但是,GetCategoryByID 是我写的一个函数,我也写了一个类似的函数,它工作得很好(GetCategoryByName),所以我不明白为什么它决定重复
// Return the Category as Result (IGroup)
Result := Category;
// Exit the function.
Exit;
一遍又一遍。
编辑:这里是如何重现它:https://gist.github.com/813389
编辑:这是我的 CallStack,根据要求:
Edit2:更多信息:
【问题讨论】:
-
如果您想自己调试,请使用 F7 进入而不是 F8 跳过
-
我在您显示的代码中看不到 SO。你没有告诉我们什么?
-
如果你正在递归地做一些没有结束的事情,你可能会得到堆栈溢出。
OnCategoryRename对我来说听起来像是一个事件。如果GetCategoryByID中有触发OnCategoryRename的内容,您将得到一个永无止境的递归。您可以通过在单步执行代码时查看调用堆栈来查看是否发生这种情况。 -
什么Delphi版本?您是否退出了 Delphi,删除了所有 .DCU 文件,然后启动 Delphi 并再次尝试您的项目?您使用的是哪个
Exit(我有一个客户,他有一卡车的单位有procedure Exit;)。 -
@Jeff:
frmMain.Skype.CustomGroups.Item[I]是什么类型?调用它会导致SkypeReply处理程序触发吗?或者可以将其转换为Category的类型导致SkypeReply触发?我可以看到您正在检查pCommand.Reply是否包含'GROUP',但我没有看到后者从前者中删除(尽管它可能在处理程序的代码中完成,如果仍然需要的话)。如果由于某种原因,处理程序在 proc 完成之前被触发(或 因为 proc 导致处理程序触发),到那时pCommand.Reply是否可能仍然包含'GROUP'?
标签: delphi function stack-overflow skype