Bug 429196 - StackOverflowError in IIndex.adaptBinding(IBinding)
Summary: StackOverflowError in IIndex.adaptBinding(IBinding)
Status: NEW
Alias: None
Product: CDT
Classification: Tools
Component: cdt-indexer (show other bugs)
Version: Next   Edit
Hardware: PC Linux
: P3 normal with 1 vote (vote)
Target Milestone: ---   Edit
Assignee: Project Inbox CLA
QA Contact: Jonah Graham CLA
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-02-26 17:00 EST by Andrew Eidsness CLA
Modified: 2020-09-04 15:21 EDT (History)
4 users (show)

See Also:


Attachments
patch with a unit test to reproduce the problem (3.57 KB, patch)
2014-02-26 17:03 EST, Andrew Eidsness CLA
no flags Details | Diff
updated patch with proper bug number (3.58 KB, patch)
2014-02-26 19:43 EST, Andrew Eidsness CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Andrew Eidsness CLA 2014-02-26 17:00:16 EST
This stack overflow was initially detected in the CodanBuilder but I have created a test case that reproduces it independently.  I'll attach that test case after I have this bug number.

The problem happens when all of the following are true:

- the CIndex has more than one fragment
- an IASTTranslationUnit is created with that index
- the fIndexFileSet in the astTU has more than one fragment
- the astTU has a file-local variable

When those conditions are met, then attempts to find that variable cause the stack overflow.  Here is the looping part of the stacktrace (line numbers from 8.3):

org.eclipse.cdt.internal.core.pdom.PDOM.adaptBinding(PDOM.java:1090)
org.eclipse.cdt.internal.core.pdom.PDOM.findNames(PDOM.java:1127)
org.eclipse.cdt.internal.core.index.IndexFileSet.containsNonLocalDeclaration(IndexFileSet.java:83)
org.eclipse.cdt.internal.core.dom.parser.ASTInternal.getDeclaredInSourceFileOnly(ASTInternal.java:124)
org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage.getLocalToFile(PDOMLinkage.java:258)
org.eclipse.cdt.internal.core.pdom.dom.cpp.PDOMCPPLinkage.getLocalToFile(PDOMCPPLinkage.java:1179)
org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage.getLocalToFileRec(PDOMLinkage.java:229)
org.eclipse.cdt.internal.core.pdom.dom.cpp.PDOMCPPLinkage.doAdaptBinding(PDOMCPPLinkage.java:838)
org.eclipse.cdt.internal.core.pdom.dom.cpp.PDOMCPPLinkage.adaptBinding(PDOMCPPLinkage.java:802)
org.eclipse.cdt.internal.core.pdom.dom.cpp.PDOMCPPLinkage.adaptBinding(PDOMCPPLinkage.java:782)
org.eclipse.cdt.internal.core.pdom.PDOM.findBindingInLinkage(PDOM.java:1113)
org.eclipse.cdt.internal.core.pdom.PDOM.adaptBinding(PDOM.java:1104)
org.eclipse.cdt.internal.core.pdom.PDOM.adaptBinding(PDOM.java:1090)
Comment 1 Andrew Eidsness CLA 2014-02-26 17:03:35 EST
Created attachment 240347 [details]
patch with a unit test to reproduce the problem
Comment 2 Andrew Eidsness CLA 2014-02-26 17:09:19 EST
Here is the top of the stack trace for when the problem was originally found in Codan.  The line numbers in here should close to 8.3 but may have a few slight changes because of my local edits while debugging.

IndexFileSet.containsNonLocalDeclaration(IBinding, IIndexFragment) line: 83	
ASTInternal.getDeclaredInSourceFileOnly(IIndexFragment, IBinding, boolean, PDOMBinding) line: 124	
PDOMCPPLinkage(PDOMLinkage).getLocalToFile(IBinding, PDOMBinding) line: 258	
PDOMCPPLinkage.getLocalToFile(IBinding, PDOMBinding) line: 1179	
PDOMCPPLinkage(PDOMLinkage).getLocalToFileRec(PDOMNode, IBinding, PDOMBinding) line: 229	
PDOMCPPLinkage.doAdaptBinding(PDOMNode, IBinding, long[]) line: 838	
PDOMCPPLinkage.adaptBinding(PDOMNode, IBinding, long[]) line: 802	
PDOMCPPLinkage.adaptBinding(IBinding, boolean) line: 782	
WritablePDOM(PDOM).findBindingInLinkage(PDOMLinkage, IBinding, boolean) line: 1113	
WritablePDOM(PDOM).adaptBinding(IBinding, boolean) line: 1104	
WritablePDOM(PDOM).adaptBinding(IBinding) line: 1090	
CIndex.adaptBinding(IBinding) line: 490	
ClassMembersInitializationChecker$OnEachClass.areEquivalentBindings(IBinding, IBinding, IIndex) line: 219	
ClassMembersInitializationChecker$OnEachClass.getContainedEquivalentBinding(Iterable<IField>, IBinding, IIndex) line: 203	
ClassMembersInitializationChecker$OnEachClass.visit(IASTName) line: 188	
CPPASTName.accept(ASTVisitor) line: 167	
CPPASTIdExpression.accept(ASTVisitor) line: 79	
CPPASTBinaryExpression.accept(ASTVisitor) line: 170	
CPPASTIfStatement.accept(ASTVisitor) line: 139	
CPPASTCompoundStatement.accept(ASTVisitor) line: 85	
CPPASTFunctionDefinition.accept(ASTVisitor) line: 198	
CPPASTTranslationUnit(ASTTranslationUnit).accept(ASTVisitor) line: 265	
ClassMembersInitializationChecker.processAst(IASTTranslationUnit) line: 72	
ClassMembersInitializationChecker(AbstractIndexAstChecker).processFile(IFile) line: 79	
ClassMembersInitializationChecker(AbstractIndexAstChecker).processResource(IResource) line: 54	
ClassMembersInitializationChecker(AbstractChecker).processResource(IResource, ICheckerInvocationContext) line: 249	
CodanRunner.processResource(IResource, Object, CheckerLaunchMode, IProgressMonitor) line: 90	
CodanRunner.processResource(IResource, Object, CheckerLaunchMode, IProgressMonitor) line: 116	
CodanRunner.processResource(IResource, Object, CheckerLaunchMode, IProgressMonitor) line: 116	
CodanRunner.processResource(IResource, Object, CheckerLaunchMode, IProgressMonitor) line: 116	
CodanRunner.processResource(IResource, Object, CheckerLaunchMode, IProgressMonitor) line: 116	
CodanRunner.processResource(IResource, Object, CheckerLaunchMode, IProgressMonitor) line: 116	
CodanRunner.processResource(IResource, CheckerLaunchMode, IProgressMonitor) line: 54	
CodanBuilder.processResource(IResource, IProgressMonitor) line: 81	
CodanBuilder.fullBuild(IProgressMonitor) line: 102	
CodanBuilder.build(int, Map, IProgressMonitor) line: 67	
BuildManager$2.run() line: 733	
SafeRunner.run(ISafeRunnable) line: 42	
BuildManager.basicBuild(int, IncrementalProjectBuilder, Map<String,String>, MultiStatus, IProgressMonitor) line: 206	
BuildManager.basicBuild(IBuildConfiguration, int, IBuildContext, ICommand[], MultiStatus, IProgressMonitor) line: 246	
BuildManager$1.run() line: 299	
SafeRunner.run(ISafeRunnable) line: 42	
BuildManager.basicBuild(IBuildConfiguration, int, IBuildContext, MultiStatus, IProgressMonitor) line: 302	
BuildManager.basicBuildLoop(IBuildConfiguration[], IBuildConfiguration[], int, MultiStatus, IProgressMonitor) line: 358	
BuildManager.build(IBuildConfiguration[], IBuildConfiguration[], int, IProgressMonitor) line: 381	
Workspace.buildInternal(IBuildConfiguration[], int, boolean, IProgressMonitor) line: 514	
Workspace.build(IBuildConfiguration[], int, boolean, IProgressMonitor) line: 433	
BuildAction$1.runInWorkspace(IProgressMonitor) line: 305	
BuildAction$1(InternalWorkspaceJob).run(IProgressMonitor) line: 38	
Worker.run() line: 53
Comment 3 Andrew Eidsness CLA 2014-02-26 19:43:49 EST
Created attachment 240351 [details]
updated patch with proper bug number
Comment 4 Doug Schaefer CLA 2014-04-02 14:22:58 EDT
I have another customer report with the same stack overflow. Need to fix this ASAP.
Comment 5 Doug Schaefer CLA 2014-04-02 15:38:55 EDT
Andrew's change request from https://git.eclipse.org/r/#/c/22624/ does fix the stack overflows I'm seeing. I'll see if I can come up with a better solution but may have to go with what he had.
Comment 6 Doug Schaefer CLA 2014-04-03 10:01:52 EDT
I have a bit of a hacky solution but it should perform well. I'll post a review once I get Andrew's JUnit tests brought over.
Comment 7 Sergey Prigogin CLA 2014-04-03 13:23:01 EDT
The code in http://git.eclipse.org/c/cdt/org.eclipse.cdt.git/commit/?h=cdt_8_3&id=126da7d685ccbbd971fe0135dead883dd2e3cab4 could be made more robust by adding try/finally around the adaptBinding(binding, true) call. Do you plan to merge this change to master?
Comment 8 Doug Schaefer CLA 2014-04-03 13:44:55 EDT
Yes, this will go into master. We keep forgetting to propagate changes forward and that's pissing off my customers. If anyone has a better idea on how to fix this, go at it. For now, it solves my immediate problem, which is an angry customer :).
Comment 9 Andrew Eidsness CLA 2014-04-03 13:49:23 EDT
Also, the inProgress member should likely be ThreadLocal to avoid trampling by concurrent readers.
Comment 10 Doug Schaefer CLA 2014-04-03 18:21:02 EDT
I've incorporated both Sergey and Andrew's feedback. Thanks guys!

I'm going to leave this bug open because my solution is really dumb. We should really take another look and see if there's a better way to do this local stuff. I'm not even sure what it's trying to accomplish.
Comment 11 Sergey Prigogin CLA 2014-04-03 19:14:04 EDT
(In reply to Doug Schaefer from comment #10)
To come up with a better solution we would need a reproducible example.
Comment 12 Andrew Eidsness CLA 2014-04-03 22:24:22 EDT
Something other than the test case which reproduces the problem every time it is run?
Comment 13 Sergey Prigogin CLA 2014-04-03 22:44:53 EDT
(In reply to Andrew Eidsness from comment #12)
> Something other than the test case which reproduces the problem every time
> it is run?

Yes, such a test case. Ideally, reduced to a manageable size.
Comment 14 Doug Schaefer CLA 2014-04-04 10:08:13 EDT
(In reply to Sergey Prigogin from comment #13)
> (In reply to Andrew Eidsness from comment #12)
> > Something other than the test case which reproduces the problem every time
> > it is run?
> 
> Yes, such a test case. Ideally, reduced to a manageable size.

What's wrong with the JUnit we added? It's about as small as you can get.
Comment 15 Sergey Prigogin CLA 2014-04-04 12:35:59 EDT
(In reply to Doug Schaefer from comment #14)
Oh, I completely forgot that there was a test in the first patch.
Comment 16 Andrey Ayupov CLA 2014-09-23 13:39:54 EDT
Is this bug fixed in Luna? I keep hitting it very often in my plugins.
Comment 17 Nathan Ridge CLA 2014-09-28 19:12:17 EDT
(In reply to Andrey Ayupov from comment #16)
> Is this bug fixed in Luna?

Looks like it's not.
Comment 18 Andrey Ayupov CLA 2014-10-28 15:54:42 EDT
It seems that cdt 8.4 (that came with luna) has this fix:
http://git.eclipse.org/c/cdt/org.eclipse.cdt.git/commit/?h=cdt_8_3&id=126da7d685ccbbd971fe0135dead883dd2e3cab4
So I believe I can just have my customers update the CDT in Kepler or start using Luna.
Comment 19 Nathan Ridge CLA 2014-10-29 03:44:00 EDT
(In reply to Andrey Ayupov from comment #18)
> It seems that cdt 8.4 (that came with luna) has this fix:
> http://git.eclipse.org/c/cdt/org.eclipse.cdt.git/commit/
> ?h=cdt_8_3&id=126da7d685ccbbd971fe0135dead883dd2e3cab4
> So I believe I can just have my customers update the CDT in Kepler or start
> using Luna.

Oh, you're right! I missed the fact that an interim fix (the one you linked to) had been committed, and the bug is just kept open until we put in place a more proper fix (as per comment 10).