Stack overflow

Hey S.O! I am posting my stack overflow problem to StackOverflow.com. Irony at its best!

Anyway. I call this procedure on my SkypeReply event handler, which gets fired a lot:

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; 

The idea behind this is to scroll through my list of Skype groups to see which group has been renamed. AFAIK that doesn't matter since my SO has been traced to appear 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; 

When I set a breakpoint in Result: = Category; and Single Step thru, these two lines run again and again, right after each other!

And when I comment sCtgName := GetCategoryByID(CategoryID).DisplayName; in the first piece of code, there is no overflow, a message appears that it should once. However, GetCategoryByID is a function that I wrote, and I wrote one similar one that works fine (GetCategoryByName), so I don’t understand why he decided to repeat

 // Return the Category as Result (IGroup) Result := Category; // Exit the function. Exit; 

again and again.

If you need more information, feel free to ask!

EDIT: here is how you can reproduce it: https://gist.github.com/813389

EDIT: Here is my CallStack, as requested: Callstack

Edit2: Additional Information: More info

Thank you for your time! - Jeff

+6
function stack-overflow delphi skype
source share
3 answers

What doesn't appear in your question: the "OnCategoryRename" function that you posted here is a subfunction called by the TForm.Skype1Reply callback.

To see this, I had to click on the github link - but I think this is an important point in your problem.

My suggestion:

  • The GetCategoryById function actually sends a request that launches "Skype1Reply".
  • If the group name has changed, "Skype1Reply" calls "OnCategoryRename".
  • "OnCategoryRename" calls "GetCategoryById"
  • "GetCategoryById" launches "Skype1Reply"
  • Somehow, the test saying "if the group name has changed" is still true, so "Skype1Reply" calls "OnCategoryRename"
  • "OnCategoryRename" calls "GetCategoryById"
  • rinse, repeat

I think a quick and dirty fix will be to change

 sCtgName := GetCategoryByID(CategoryID).DisplayName; // Removing THIS line does not produce a Stack Overflow! 

from

 sCtgName := //find another way to get the new name, which you can probably get from your ICommand object pCommand.Reply.ReadDataFromReplyAndGetNewDisplayName; 

In the future, I suggest you publish a complete code sample for these kinds of questions.

+2
source share

Make sure you compile the project with “optimizations,” “frame stacks,” and “use debug.dcu” to get the most verbose call. Then send the column that you get when you click on the stack overflow (if you are having trouble determining the nature of the problem from it).

+5
source share

Stack overflow can be caused by infinite recursion.

You have to be very careful when writing code that has event handlers. One thing you can do to help you debug this, says David, is the INTO step, not the challenge. F7 goes into the call.

Another thing you can do is set a breakpoint at the top of the GetCategoryById function. Now look at your call stack. Do you see the duplicate name on the stack? That should make it very clear.

+2
source share

All Articles