Bug 315920 - [stack][expressions] Debugger doesn't handle a stack overflow well
Summary: [stack][expressions] Debugger doesn't handle a stack overflow well
Status: NEW
Alias: None
Product: CDT
Classification: Tools
Component: cdt-debug-dsf-gdb (show other bugs)
Version: 7.0   Edit
Hardware: PC Windows 7
: P3 normal with 2 votes (vote)
Target Milestone: ---   Edit
Assignee: Project Inbox CLA
QA Contact: Jonah Graham CLA
URL:
Whiteboard:
Keywords: performance
: 411916 467438 518222 (view as bug list)
Depends on:
Blocks:
 
Reported: 2010-06-06 22:42 EDT by Nobody - feel free to take it CLA
Modified: 2020-09-04 15:26 EDT (History)
4 users (show)

See Also:


Attachments
Always add stack frame limits (5.96 KB, patch)
2015-03-03 10:08 EST, John Moule CLA
no flags Details | Diff
Minimal fix taking into account stack frames limits dynamically (792 bytes, patch)
2018-05-29 04:53 EDT, jonathan ponroy CLA
no flags Details | Diff
Full fix taking into account the stack frames limits (2.52 KB, patch)
2018-05-31 06:01 EDT, jonathan ponroy CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Nobody - feel free to take it CLA 2010-06-06 22:42:10 EDT
If a stack overflow occurs during a DSF/GDB session it takes a very long time to populate the debug view. The cause of it is the "stack-list-frames" command called without limits - the list returned by GDB contains more than 64000 frames. What's interesting, "stack-list-frames" without limits is not used to display the frames but to calculate the index of a frame.
Comment 1 Pawel Piech CLA 2010-06-07 14:20:17 EDT
That is interesting.  I only see -stack-info-depth being called without limit, but IMO this is a problem too.  The index is being calculated by the expressions service so that it can work with GDB's variables API.
Comment 2 Nobody - feel free to take it CLA 2010-06-07 16:06:30 EDT
(In reply to comment #1)
> That is interesting.  I only see -stack-info-depth being called without limit,
> but IMO this is a problem too.  

See getFrameData() of MIStack, line 440. 

> The index is being calculated by the
> expressions service so that it can work with GDB's variables API.

Don't understand how this issue is related to GDB's variable object API if that's what you mean.
Comment 3 Pawel Piech CLA 2010-06-07 17:10:16 EDT
(In reply to comment #2)
> (In reply to comment #1)
> > That is interesting.  I only see -stack-info-depth being called without limit,
> > but IMO this is a problem too.  
> 
> See getFrameData() of MIStack, line 440. 

Wow I completely missed.  That can totally be optimized out.. no need for API changes either.

> 
> > The index is being calculated by the
> > expressions service so that it can work with GDB's variables API.
> 
> Don't understand how this issue is related to GDB's variable object API if
> that's what you mean.
MIVariableManager retrieves the stack depth without limit, which means that GDB has to unwind the whole stack even if it doesn't send the whole stack trace to the client.
Comment 4 Nobody - feel free to take it CLA 2013-06-28 16:00:12 EDT
*** Bug 411916 has been marked as a duplicate of this bug. ***
Comment 5 John Moule CLA 2015-03-03 10:08:51 EST
Created attachment 251256 [details]
Always add stack frame limits

I have a situation where a C remote application is misbehaving and putting GDB into a bad state. GDB responds with infinite stack frames when the following commands are issued without any low-frame high-frame params in the first 2 instances and max-depth in the 3rd:

  -stack-list-arguments
  -stack-list-frames
  -stack-info-depth

I've solved this by always adding low-frame high-frame params/max-depth to the variants of these methods that previously didn't specify these params; for example:

  public MIStackListFrames(IMIExecutionDMContext execDmc) {
    super(execDmc, "-stack-list-frames", new String[] { "0", MIStackInfoDepth.getLimit() }); //$NON-NLS-1$ //$NON-NLS-2$
    }

This always forces GDB to limit the number of frames returned. I get the limit like this:

  static String getLimit() {
    String retVal = Integer.toString(Integer.MAX_VALUE);
    final IPreferenceStore prefsStore = new ScopedPreferenceStore(InstanceScope.INSTANCE, DsfUIPlugin.PLUGIN_ID);
    final boolean isFrameLimitEnabled = prefsStore.getBoolean(IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT_ENABLE);
    if (isFrameLimitEnabled) {
      int prefLimit = prefsStore.getInt(IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT);
      retVal = Integer.toString(Math.max(prefLimit, 50));
    }
    System.out.println(retVal);
    return retVal;
  }

But this doesn't support the dynamic stack frame limit, that can be changed if the user clicks <...more frames...> in the Debug view, and returned by org.eclipse.cdt.dsf.debug.ui.viewmodel.launch.StackFramesVMNode.getStackFrameLimit(IExecutionDMContext)

Can anyone tell me please when inside MIStackListFrames() how can I access the instance of StackFramesVMNode for the active debug session, so that I can call getStackFrameLimit()?
Comment 6 Nobody - feel free to take it CLA 2017-06-14 09:34:50 EDT
*** Bug 518222 has been marked as a duplicate of this bug. ***
Comment 7 jonathan ponroy CLA 2018-05-24 08:33:12 EDT
*** Bug 467438 has been marked as a duplicate of this bug. ***
Comment 8 jonathan ponroy CLA 2018-05-29 04:53:53 EDT
Created attachment 274236 [details]
Minimal fix taking into account stack frames limits dynamically

Regarding the previous patch, this fix take into account the "Show more..." to display more frames of stack. The previous patch is useless.
Known issues/possible improvement
  _ when clicking on "Show more...", ask "-stack-list-frames 10 20" instead of "-stack-list-frames 0 20"
Comment 9 jonathan ponroy CLA 2018-05-31 06:01:18 EDT
Created attachment 274277 [details]
Full fix taking into account the stack frames limits

This is the full fix taking into account the stack frames limits:
  _ new introduced function loadedStackDepth allow to know what frames are really loaded in frame cache ( which can be different from getValidStackDepth )
  _ when we resume (F8) the session, we forget the previous temporary saved stack frame limit. (ex : if we displayed 20 frames and we resumed, the next time we break, we display only 10 frames so we need to ask only 10 frames to gdb)