Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [cdt-dev] ASTRewrite

Joseph,
Could you please provide a code example that triggers this infinite loop. Thanks.

-serget

On Wed, Jul 11, 2012 at 10:35 AM, Joseph Paul Cohen <jcccnet@xxxxxxxxx> wrote:
I made this change and now my code works. Not sure if it's correct
though. Can someone verify it? If the code is not making forward
progress then it returns false.

diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGenerator.java
index 072c70f..b8cbee2 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGenerator.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGenerator.java
@@ -865,7 +865,8 @@ public class ChangeGenerator extends ASTVisitor {
         */
        private boolean doesRegionContainNode(IASTTranslationUnit ast,
int offset, int length) {
                IASTNodeSelector nodeSelector =
ast.getNodeSelector(ast.getFilePath());
-               while (length > 0) {
+               boolean loop = true;
+               while (length > 0 && loop) {
                        IASTNode node =
nodeSelector.findFirstContainedNode(offset, length - 1);
                        if (node == null)
                                return false;
@@ -874,6 +875,8 @@ public class ChangeGenerator extends ASTVisitor {
                        int oldOffset = offset;
                        offset = endOffset(node);
                        length -= offset - oldOffset;
+                       if ((offset - oldOffset) == 0)
+                               loop = false;
                }
                return false;
        }


On Wed, Jul 11, 2012 at 12:31 PM, Joseph Paul Cohen <jcccnet@xxxxxxxxx> wrote:
> It seems there is a endless loop here in file ChangeGenerator.  Length
> is never decreased because offset and oldOffset are always the same.
>
> The endOffset call is reaching into a ASTPreprocessorNode object and
> calling getNodeOffset() + getNodeLength().
>
> Can anyone give me a high level view of this code? Or know of any
> writeup regarding the ChangeGenerator?
>
>
>         private boolean doesRegionContainNode(IASTTranslationUnit ast, int
> offset, int length) {
>                 IASTNodeSelector nodeSelector = ast.getNodeSelector(ast.getFilePath());
>                 while (length > 0) {
>                         IASTNode node = nodeSelector.findFirstContainedNode(offset, length - 1);
>                         if (node == null)
>                                 return false;
>                         if (!isNodeRemoved(node))
>                                 return true;
>                         int oldOffset = offset;
>                         offset = endOffset(node);
>                         length -= offset - oldOffset;
>                 }
>                 return false;
>         }
>
> Thread dump:
> Thread [Worker-2] (Suspended)
>         ChangeGenerator.doesRegionContainNode(IASTTranslationUnit, int, int) line: 876
>         ChangeGenerator.getPreviousSiblingOrPreprocessorNode(IASTNode) line: 803
>         ChangeGenerator.handleReplace(IASTNode) line: 593
>         ChangeGenerator.visit(IASTDeclaration) line: 177
>         CPPASTFunctionDefinition.accept(ASTVisitor) line: 178
>         CPPASTTranslationUnit(ASTTranslationUnit).accept(ASTVisitor) line: 251
>         ChangeGenerator.generateChange(IASTNode, ASTVisitor) line: 124
>         ChangeGenerator.generateChange(IASTNode) line: 117
>         ASTRewriteAnalyzer.rewriteAST(IASTTranslationUnit,
> ASTModificationStore, NodeCommentMap) line: 26
>         ASTRewrite.rewriteAST() line: 213
>         ModificationCollector.createFinalChange() line: 82
>         RemoveFunctionAction$RemoveFunctionsJob.run(IProgressMonitor) line: 274
>         Worker.run() line: 54
>
>
> Variable values at end of loop:
>
> this    ChangeGenerator  (id=127)
> ast     CPPASTTranslationUnit  (id=123)
> offset  173
> length  53
> nodeSelector    ASTNodeSelector  (id=142)
> node    CPPASTSimpleDeclSpecifier  (id=198)
> oldOffset       173
>
>
>
> On Wed, Jul 11, 2012 at 12:03 PM, Joseph Paul Cohen <jcccnet@xxxxxxxxx> wrote:
>> So it wasn't the thread waiting for DirtyRegionQueue. It's hanging in
>> a thread at FindNodeForOffsetAction(ASTGenericVisitor).visit(IASTStatement)
>> line: 118.
>>
>> I will look into this file, thanks for noticing my mistake.  Also
>> since my first email I changed to code to use a ModificationCollector
>> but it still hangs here.
>>
>> Thread Dump while preforming rewrite:
>>
>> org.eclipse.equinox.launcher.Main at localhost:40561 (Suspended)
>>         Daemon System Thread [Signal Dispatcher] (Suspended)
>>         Daemon System Thread [Finalizer] (Suspended)
>>                 waiting for: ReferenceQueue$Lock  (id=78)
>>                 Object.wait(long) line: not available [native method]
>>                 ReferenceQueue<T>.remove(long) line: 135
>>                 ReferenceQueue<T>.remove() line: 151
>>                 Finalizer$FinalizerThread.run() line: 177
>>         Daemon System Thread [Reference Handler] (Suspended)
>>                 waiting for: Reference$Lock  (id=77)
>>                 Object.wait(long) line: not available [native method]
>>                 Reference$Lock(Object).wait() line: 503
>>                 Reference$ReferenceHandler.run() line: 133
>>         Thread [main] (Suspended)
>>                 OS.Call(int, int, int, int) line: not available [native method]
>>                 Display.sleep() line: 4036
>>                 IDEWorkbenchAdvisor(WorkbenchAdvisor).eventLoopIdle(Display) line: 364
>>                 IDEWorkbenchAdvisor.eventLoopIdle(Display) line: 917
>>                 Workbench$3.eventLoopIdle(Display) line: 459
>>                 PartRenderingEngine$9.run() line: 1026
>>                 Realm.runWithDefault(Realm, Runnable) line: 332
>>                 PartRenderingEngine.run(MApplicationElement, IEclipseContext) line: 916
>>                 E4Workbench.createAndRunUI(MApplicationElement) line: 86
>>                 Workbench$5.run() line: 585
>>                 Realm.runWithDefault(Realm, Runnable) line: 332
>>                 Workbench.createAndRunWorkbench(Display, WorkbenchAdvisor) line: 540
>>                 PlatformUI.createAndRunWorkbench(Display, WorkbenchAdvisor) line: 149
>>                 IDEApplication.start(IApplicationContext) line: 124
>>                 EclipseAppHandle.run(Object) line: 196
>>                 EclipseAppLauncher.runApplication(Object) line: 110
>>                 EclipseAppLauncher.start(Object) line: 79
>>                 EclipseStarter.run(Object) line: 353
>>                 EclipseStarter.run(String[], Runnable) line: 180
>>                 NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not
>> available [native method]
>>                 NativeMethodAccessorImpl.invoke(Object, Object[]) line: 57
>>                 DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 43
>>                 Method.invoke(Object, Object...) line: 601
>>                 Main.invokeFramework(String[], URL[]) line: 629
>>                 Main.basicRun(String[]) line: 584
>>                 Main.run(String[]) line: 1438
>>                 Main.main(String[]) line: 1414
>>         Thread [Framework Active Thread] (Suspended)
>>                 waiting for: Framework  (id=76)
>>                 Object.wait(long) line: not available [native method]
>>                 Framework.run() line: 1863
>>                 Thread.run() line: 722
>>         Daemon Thread [State Data Manager] (Suspended)
>>                 Thread.sleep(long) line: not available [native method]
>>                 StateManager.run() line: 297
>>                 Thread.run() line: 722
>>         Daemon Thread [Start Level Event Dispatcher] (Suspended)
>>                 waiting for: EventManager$EventThread  (id=20)
>>                 Object.wait(long) line: not available [native method]
>>                 EventManager$EventThread(Object).wait() line: 503
>>                 EventManager$EventThread.getNextEvent() line: 400
>>                 EventManager$EventThread.run() line: 336
>>         Daemon Thread [Framework Event Dispatcher] (Suspended)
>>                 waiting for: EventManager$EventThread  (id=22)
>>                 Object.wait(long) line: not available [native method]
>>                 EventManager$EventThread(Object).wait() line: 503
>>                 EventManager$EventThread.getNextEvent() line: 400
>>                 EventManager$EventThread.run() line: 336
>>         Daemon Thread [[Timer] - Main Queue Handler] (Suspended)
>>                 waiting for: Object  (id=72)
>>                 Object.wait(long) line: not available [native method]
>>                 TimerImpl.run() line: 141
>>                 Thread.run() line: 722
>>         Daemon Thread [Bundle File Closer] (Suspended)
>>                 waiting for: EventManager$EventThread  (id=25)
>>                 Object.wait(long) line: not available [native method]
>>                 EventManager$EventThread(Object).wait() line: 503
>>                 EventManager$EventThread.getNextEvent() line: 400
>>                 EventManager$EventThread.run() line: 336
>>         Thread [Worker-JM] (Suspended)
>>                 waiting for: ArrayList<E>  (id=74)
>>                 Object.wait(long) line: not available [native method]
>>                 InternalWorker.run() line: 58
>>         Thread [Worker-0] (Suspended)
>>                 waiting for: WorkerPool  (id=71)
>>                 Object.wait(long) line: not available [native method]
>>                 WorkerPool.sleep(long) line: 188
>>                 WorkerPool.startJob(Worker) line: 220
>>                 Worker.run() line: 50
>>         Thread [Worker-1] (Suspended)
>>                 waiting for: WorkerPool  (id=71)
>>                 Object.wait(long) line: not available [native method]
>>                 WorkerPool.sleep(long) line: 188
>>                 WorkerPool.startJob(Worker) line: 220
>>                 Worker.run() line: 50
>>         Thread [Worker-2] (Suspended)
>>                 FindNodeForOffsetAction(ASTGenericVisitor).visit(IASTStatement) line: 118
>>                 CPPASTCompoundStatement.accept(ASTVisitor) line: 74
>>                 CPPASTFunctionDefinition.accept(ASTVisitor) line: 201
>>                 CPPASTTranslationUnit(ASTTranslationUnit).accept(ASTVisitor) line: 251
>>                 ASTNodeSelector.getNode(ASTNodeSpecification<T>) line: 115
>>                 ASTNodeSelector.findNode(int, int, Relation, Class<T>, boolean) line: 88
>>                 ASTNodeSelector.findNode(int, int, Relation, Class<T>) line: 50
>>                 ASTNodeSelector.findFirstContainedNode(int, int) line: 122
>>                 ChangeGenerator.doesRegionContainNode(IASTTranslationUnit, int, int)
>> line: 869
>>                 ChangeGenerator.getPreviousSiblingOrPreprocessorNode(IASTNode) line: 803
>>                 ChangeGenerator.handleReplace(IASTNode) line: 593
>>                 ChangeGenerator.visit(IASTDeclaration) line: 177
>>                 CPPASTFunctionDefinition.accept(ASTVisitor) line: 178
>>                 CPPASTTranslationUnit(ASTTranslationUnit).accept(ASTVisitor) line: 251
>>                 ChangeGenerator.generateChange(IASTNode, ASTVisitor) line: 124
>>                 ChangeGenerator.generateChange(IASTNode) line: 117
>>                 ASTRewriteAnalyzer.rewriteAST(IASTTranslationUnit,
>> ASTModificationStore, NodeCommentMap) line: 26
>>                 ASTRewrite.rewriteAST() line: 213
>>                 ModificationCollector.createFinalChange() line: 82
>>                 RemoveFunctionAction$RemoveFunctionsJob.run(IProgressMonitor) line: 274
>>                 Worker.run() line: 54
>>         Thread [Worker-3] (Suspended)
>>                 waiting for: WorkerPool  (id=71)
>>                 Object.wait(long) line: not available [native method]
>>                 WorkerPool.sleep(long) line: 188
>>                 WorkerPool.startJob(Worker) line: 220
>>                 Worker.run() line: 50
>>         Daemon Thread [Java indexing] (Suspended)
>>                 waiting for: IndexManager  (id=73)
>>                 Object.wait(long) line: not available [native method]
>>                 IndexManager(Object).wait() line: 503
>>                 IndexManager(JobManager).run() line: 382
>>                 Thread.run() line: 722
>>         Thread [Worker-4] (Suspended)
>>                 waiting for: WorkerPool  (id=71)
>>                 Object.wait(long) line: not available [native method]
>>                 WorkerPool.sleep(long) line: 188
>>                 WorkerPool.startJob(Worker) line: 220
>>                 Worker.run() line: 50
>>         Daemon Thread [org.eclipse.cdt.internal.ui.text.CReconciler] (Suspended)
>>                 waiting for: DirtyRegionQueue  (id=75)
>>                 Object.wait(long) line: not available [native method]
>>                 AbstractReconciler$BackgroundThread.run() line: 179
>>         Daemon Thread [[ThreadPool Manager] - Idle Thread] (Suspended)
>>                 waiting for: Executor  (id=68)
>>                 Object.wait(long) line: not available [native method]
>>                 Executor(Object).wait() line: 503
>>                 Executor.run() line: 106
>>
>>
>> On Wed, Jul 11, 2012 at 2:35 AM, Leherbauer, Anton (Toni)
>> <Anton.Leherbauer@xxxxxxxxxxxxx> wrote:
>>> Hi,
>>>
>>> the screenshot shows the Reconciler thread in a state where it is idle (waiting for: DirtyRegionQueue).
>>> This is obviously not the thread that hangs in the rewriteAST method.
>>> A full thread dump would show more.
>>>
>>> Toni
>>>
>>>> -----Original Message-----
>>>> From: cdt-dev-bounces@xxxxxxxxxxx [mailto:cdt-dev-bounces@xxxxxxxxxxx]
>>>> On Behalf Of Joseph Paul Cohen
>>>> Sent: Tuesday, July 10, 2012 17:09
>>>> To: cdt-dev
>>>> Subject: [cdt-dev] ASTRewrite
>>>>
>>>> Hello,
>>>>
>>>> I have been using the CDT ASTRewrite object to create changes. For some
>>>> refactorings (not all) with multiple IAST nodes removed it hangs at this line:
>>>>
>>>> final Change c = rw.rewriteAST();
>>>>
>>>> The thread says "waiting for: DirtyRegionQueue" (Image Attached)
>>>>
>>>> Can anyone tell me what this means? Or some hints at what to look at?
>>>>
>>>> -J
>>> _______________________________________________
>>> cdt-dev mailing list
>>> cdt-dev@xxxxxxxxxxx
>>> https://dev.eclipse.org/mailman/listinfo/cdt-dev
_______________________________________________
cdt-dev mailing list
cdt-dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/cdt-dev


Back to the top