Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 321118

Summary: Fast indexer fails due to NPE when a -I. option is present
Product: [Tools] CDT Reporter: Martin Oberhuber <mober.at+eclipse>
Component: cdt-parserAssignee: Markus Schorn <mschorn.eclipse>
Status: RESOLVED FIXED QA Contact: Markus Schorn <mschorn.eclipse>
Severity: normal    
Priority: P3 CC: cdtdoug, mober.at+eclipse, sandi_ro
Version: 6.0.2   
Target Milestone: 7.0   
Hardware: All   
OS: All   
Whiteboard:
Attachments:
Description Flags
Patch (against 6.0.2) fixing the issue
none
fix mschorn.eclipse: iplog-

Description Martin Oberhuber CLA 2010-07-28 08:53:31 EDT
CQ:WIND00225191 
Build ID: CDT 6.0.2

This issue occurs only in CDT 6.0.2 - it looks like the problem has already been fixed in CDT 7.0, but we need a solution in the 6.0.x stream.

A build configuration in our product on top of Eclipse passes a -I. directive (among others) to the CDT indexer. This leads to the following NullPointerException. Due to the NPE, static analysis completely unusable in a project that has the -I. directive, since parsing is aborted prematurely for every source file that has an #include statement which cannot be resolved with the include path before the -I. statement.

The backtrace looks similar to bug 309288, but it must be a different problem since that one is reported to be fixed in CDT 6.0.2. Note that I couldn't easily reproduce the problem in plain CDT, since a manual -I. directive is replaced by CDT before it gets to the indexer. Maybe build discovery could run into the issue, I didn't try that.

!ENTRY org.eclipse.cdt.core 4 0 2010-07-26 00:27:42.562
!MESSAGE Error while parsing /vbDebugAgent/usrAppInit.c.
!STACK 0
java.lang.NullPointerException
	at java.io.File.<init>(File.java:194)
	at org.eclipse.cdt.internal.core.pdom.indexer.FileExistsCache.isFile(FileExistsCache.java:59)
	at org.eclipse.cdt.internal.core.pdom.indexer.ProjectIndexerInputAdapter.doesIncludeFileExist(ProjectIndexerInputAdapter.java:118)
	at org.eclipse.cdt.internal.core.index.IndexBasedCodeReaderFactory.getInclusionExists(IndexBasedCodeReaderFactory.java:122)
	at org.eclipse.cdt.internal.core.parser.scanner.CPreprocessor$2.checkFile(CPreprocessor.java:117)
	at org.eclipse.cdt.internal.core.parser.scanner.CPreprocessor$2.checkFile(CPreprocessor.java:1)
	at org.eclipse.cdt.internal.core.parser.scanner.CPreprocessor.findInclusion(CPreprocessor.java:907)
	at org.eclipse.cdt.internal.core.parser.scanner.CPreprocessor.executeInclude(CPreprocessor.java:1172)
	at org.eclipse.cdt.internal.core.parser.scanner.CPreprocessor.skipBranch(CPreprocessor.java:1478)
	at org.eclipse.cdt.internal.core.parser.scanner.CPreprocessor.skipOverConditionalCode(CPreprocessor.java:1445)
	at org.eclipse.cdt.internal.core.parser.scanner.CPreprocessor.executeDirective(CPreprocessor.java:1043)
	at org.eclipse.cdt.internal.core.parser.scanner.CPreprocessor.internalFetchToken(CPreprocessor.java:685)
	at org.eclipse.cdt.internal.core.parser.scanner.CPreprocessor.fetchToken(CPreprocessor.java:481)
	at org.eclipse.cdt.internal.core.parser.scanner.CPreprocessor.nextToken(CPreprocessor.java:539)
	at org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser.fetchToken(AbstractGNUSourceCodeParser.java:238)
	at org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser.nextToken(AbstractGNUSourceCodeParser.java:260)
	at org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser.acceptInactiveCodeBoundary(AbstractGNUSourceCodeParser.java:322)
	at org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser.declarationList(AbstractGNUSourceCodeParser.java:1035)
	at org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser.parseTranslationUnit(AbstractGNUSourceCodeParser.java:1007)
	at org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser.translationUnit(AbstractGNUSourceCodeParser.java:1002)
	at org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser.parse(AbstractGNUSourceCodeParser.java:594)
	at org.eclipse.cdt.core.dom.parser.AbstractCLikeLanguage.getASTTranslationUnit(AbstractCLikeLanguage.java:134)
	at org.eclipse.cdt.internal.core.pdom.AbstractIndexerTask.createAST(AbstractIndexerTask.java:267)
	at org.eclipse.cdt.internal.core.pdom.AbstractIndexerTask.createAST(AbstractIndexerTask.java:250)
	at org.eclipse.cdt.internal.core.pdom.AbstractIndexerTask.parseFile(AbstractIndexerTask.java:676)
	at org.eclipse.cdt.internal.core.pdom.AbstractIndexerTask.parseLinkage(AbstractIndexerTask.java:565)
	at org.eclipse.cdt.internal.core.pdom.AbstractIndexerTask.runTask(AbstractIndexerTask.java:316)
	at org.eclipse.cdt.internal.core.pdom.indexer.PDOMIndexerTask.run(PDOMIndexerTask.java:122)
	at org.eclipse.cdt.internal.core.pdom.PDOMIndexerJob.run(PDOMIndexerJob.java:137)
	at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55)


+++ This bug was initially created as a clone of Bug #309288 +++

-- Error Details --
Date: Thu Apr 15 03:45:03 PDT 2010
Message: Problems occurred when invoking code from plug-in: "org.eclipse.cdt.core".
Severity: Error
Plugin: org.eclipse.cdt.core
Session Data:
eclipse.buildId=M20080911-1700
java.version=1.6.0_0
java.vendor=Sun Microsystems Inc.
BootLoader constants: OS=linux, ARCH=x86_64, WS=gtk, NL=en_US
Command-line arguments:  -os linux -ws gtk -arch x86_64


Exception Stack Trace:
java.lang.NullPointerException
at java.io.File.<init>(File.java:239)
at org.eclipse.cdt.internal.core.pdom.indexer.FileExistsCache.isFile(FileExistsCache.java:59)
at org.eclipse.cdt.internal.core.pdom.indexer.ProjectIndexerInputAdapter.resolveIncludeFile(ProjectIndexerInputAdapter.java:84)
at org.eclipse.cdt.internal.core.index.IndexBasedCodeReaderFactory.getContentForInclusion(IndexBasedCodeReaderFactory.java:125)
at org.eclipse.cdt.internal.core.parser.scanner.CPreprocessor$1.checkFile(CPreprocessor.java:96)
at org.eclipse.cdt.internal.core.parser.scanner.CPreprocessor$1.checkFile(CPreprocessor.java:1)
at org.eclipse.cdt.internal.core.parser.scanner.CPreprocessor.findInclusion(CPreprocessor.java:824)
at org.eclipse.cdt.internal.core.parser.scanner.CPreprocessor.findInclusion(CPreprocessor.java:795)
at org.eclipse.cdt.internal.core.parser.scanner.CPreprocessor.executeInclude(CPreprocessor.java:1085)
at org.eclipse.cdt.internal.core.parser.scanner.CPreprocessor.executeDirective(CPreprocessor.java:925)
at org.eclipse.cdt.internal.core.parser.scanner.CPreprocessor.internalFetchToken(CPreprocessor.java:608)
at org.eclipse.cdt.internal.core.parser.scanner.CPreprocessor.fetchToken(CPreprocessor.java:436)
at org.eclipse.cdt.internal.core.parser.scanner.CPreprocessor.nextToken(CPreprocessor.java:494)
at org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser.fetchToken(AbstractGNUSourceCodeParser.java:369)
at org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser.LA(AbstractGNUSourceCodeParser.java:234)
at org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser.skipToSemiOrClosingBrace(AbstractGNUSourceCodeParser.java:591)
at org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser.skipProblemDeclaration(AbstractGNUSourceCodeParser.java:566)
at org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser.parseTranslationUnit(AbstractGNUSourceCodeParser.java:965)
at org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser.translationUnit(AbstractGNUSourceCodeParser.java:928)
at org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser.parse(AbstractGNUSourceCodeParser.java:514)
at org.eclipse.cdt.core.dom.parser.AbstractCLikeLanguage.getASTTranslationUnit(AbstractCLikeLanguage.java:140)
at org.eclipse.cdt.internal.core.model.TranslationUnit.getAST(TranslationUnit.java:836)
at org.eclipse.cdt.internal.core.model.TranslationUnit.getAST(TranslationUnit.java:798)
at org.eclipse.cdt.internal.core.model.ASTCache$1.run(ASTCache.java:290)
at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:37)
at org.eclipse.cdt.internal.core.model.ASTCache.createAST(ASTCache.java:284)
at org.eclipse.cdt.internal.core.model.ASTCache.getAST(ASTCache.java:163)
at org.eclipse.cdt.internal.core.model.ASTCache.runOnAST(ASTCache.java:210)
at org.eclipse.cdt.internal.ui.editor.ASTProvider.runOnAST(ASTProvider.java:344)
at org.eclipse.cdt.internal.ui.viewsupport.SelectionListenerWithASTManager$PartListenerGroup.calculateASTandInform(SelectionListenerWithASTManager.java:170)
at org.eclipse.cdt.internal.ui.viewsupport.SelectionListenerWithASTManager$PartListenerGroup$3.run(SelectionListenerWithASTManager.java:148)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55)
Comment 1 Martin Oberhuber CLA 2010-07-28 08:55:11 EDT
Created attachment 175397 [details]
Patch (against 6.0.2) fixing the issue

Attached patch (against 6.0.2) fixes the issue for us. Essentially, any "-I." dirctive is replaced by the respective current scanning directory, or ignored.
Comment 2 Doug Schaefer CLA 2010-07-28 12:52:32 EDT
(In reply to comment #1)
> Created an attachment (id=175397) [details]
> Patch (against 6.0.2) fixing the issue
> 
> Attached patch (against 6.0.2) fixes the issue for us. Essentially, any "-I."
> dirctive is replaced by the respective current scanning directory, or ignored.

I'm not sure this is the correct fix, or even if this is a problem. -I. means the current directory when the compiler was invoked. Only the build system would know what that is.

I'd like to get confirmation, but I believe "." is actually an invalid directory in the scanner info API. As would all other relative directory paths.
Comment 3 Markus Schorn CLA 2010-08-02 06:48:06 EDT
Ad -I. option:
==============
These options are made absolute by the shell before invoking the compiler. Therefore, as Doug wrote, it is recommended that the build system provides 
absolute paths for the include search path. The preprocessor does not know the current directory with which the compiler is invoked. 
In CDT 7.0, as a best guess the preprocessor assumes that it is the same as the directory of the source-file being parsed, still the build system should provide absolute paths. See bug 243170 for an extensive discussion.

The NPE can be triggered with "." or "" on the include search path, also with "c:/" on the in include search path and the non-sense include directive #include "/" or #include "\"
Comment 4 Markus Schorn CLA 2010-08-02 06:57:56 EDT
Created attachment 175700 [details]
fix

The correct fix for relative include search paths is done in 7.0, it uses the current directory of the source-file, rather than the current directory of the including file.
For 6.0.x I just ported the fix for the NPE.
Comment 5 Markus Schorn CLA 2010-08-02 06:58:48 EDT
Fixed in 6.0.x > 20100802.
Comment 6 CDT Genie CLA 2010-08-02 07:23:03 EDT
*** cdt cvs genie on behalf of mschorn ***
Bug 321118: NPE in include file resolution.

[*] FileExistsCache.java 1.2.2.1 http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.cdt/all/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/FileExistsCache.java?root=Tools_Project&r1=1.2&r2=1.2.2.1