Community
Participate
Working Groups
Use case: in a build definition extension, I declare a tool, and I want to enable it regarding the value of a variable, thanks to a "checkstring" element. I contribute this variable thanks to a IConfigurationBuildMacroSupplier implementation, associated with the toolchain containing the tool mentioned above. The projects creation runs correctly, and once created the project (and the tool enablement) behave as expected. But as soon as I close the project (or the IDE), and reopen it, I get the NPE mentioned below. Seems to be due to the fact that it tries to access to the build variables contributor, while the configuration description is not totally loaded yet. !ENTRY org.eclipse.core.jobs 4 2 2010-10-05 14:04:27.446 !MESSAGE An internal error occurred during: "Setting up indexer ('testApp')". !STACK 0 java.lang.NullPointerException at org.eclipse.cdt.internal.core.settings.model.CConfigurationDescriptionCache.getBuildVariablesContributor(CConfigurationDescriptionCache.java:450) at org.eclipse.cdt.internal.core.cdtvariables.BuildSystemVariableSupplier.getMacro(BuildSystemVariableSupplier.java:104) at org.eclipse.cdt.internal.core.cdtvariables.CoreMacroSupplierBase.getVariable(CoreMacroSupplierBase.java:22) at org.eclipse.cdt.utils.cdtvariables.SupplierBasedCdtVariableManager.getVariable(SupplierBasedCdtVariableManager.java:31) at org.eclipse.cdt.internal.core.cdtvariables.CdtVariableManager.getVariable(CdtVariableManager.java:61) at org.eclipse.cdt.managedbuilder.internal.macros.CoreMacrosSupplier.getVariable(CoreMacrosSupplier.java:37) at org.eclipse.cdt.managedbuilder.internal.macros.CoreMacrosSupplier.getMacro(CoreMacrosSupplier.java:29) at org.eclipse.cdt.managedbuilder.internal.macros.BuildCdtVariablesSupplierBase.getVariable(BuildCdtVariablesSupplierBase.java:38) at org.eclipse.cdt.utils.cdtvariables.SupplierBasedCdtVariableManager.getVariable(SupplierBasedCdtVariableManager.java:31) at org.eclipse.cdt.utils.cdtvariables.SupplierBasedCdtVariableSubstitutor.resolveMacro(SupplierBasedCdtVariableSubstitutor.java:286) at org.eclipse.cdt.utils.cdtvariables.SupplierBasedCdtVariableSubstitutor.resolveMacro(SupplierBasedCdtVariableSubstitutor.java:274) at org.eclipse.cdt.utils.cdtvariables.SupplierBasedCdtVariableSubstitutor.getResolvedMacro(SupplierBasedCdtVariableSubstitutor.java:259) at org.eclipse.cdt.utils.cdtvariables.SupplierBasedCdtVariableSubstitutor.resolveToString(SupplierBasedCdtVariableSubstitutor.java:222) at org.eclipse.cdt.utils.cdtvariables.SupplierBasedCdtVariableSubstitutor.resolveToString(SupplierBasedCdtVariableSubstitutor.java:240) at org.eclipse.cdt.utils.cdtvariables.CdtVariableResolver.resolveToString(CdtVariableResolver.java:94) at org.eclipse.cdt.managedbuilder.internal.macros.BuildMacroProvider.resolveValue(BuildMacroProvider.java:219) at org.eclipse.cdt.managedbuilder.internal.enablement.CheckStringExpression.evaluate(CheckStringExpression.java:57) at org.eclipse.cdt.managedbuilder.internal.enablement.AndExpression.evaluate(AndExpression.java:30) at org.eclipse.cdt.managedbuilder.internal.enablement.OptionEnablementExpression.evaluate(OptionEnablementExpression.java:193) at org.eclipse.cdt.managedbuilder.internal.enablement.OptionEnablementExpression.evaluate(OptionEnablementExpression.java:185) at org.eclipse.cdt.managedbuilder.internal.core.BooleanExpressionApplicabilityCalculator.evaluate(BooleanExpressionApplicabilityCalculator.java:103) at org.eclipse.cdt.managedbuilder.internal.core.BooleanExpressionApplicabilityCalculator.isToolUsedInCommandLine(BooleanExpressionApplicabilityCalculator.java:79) at org.eclipse.cdt.managedbuilder.internal.core.Tool.isEnabled(Tool.java:3591) at org.eclipse.cdt.managedbuilder.internal.core.FolderInfo.filterTools(FolderInfo.java:292) at org.eclipse.cdt.managedbuilder.internal.core.FolderInfo.getFilteredTools(FolderInfo.java:332) at org.eclipse.cdt.managedbuilder.internal.core.Configuration.getFilteredTools(Configuration.java:1056) at org.eclipse.cdt.managedbuilder.core.ManagedBuildManager.performValueHandlerEvent(ManagedBuildManager.java:3267) at org.eclipse.cdt.managedbuilder.core.ManagedBuildManager.performValueHandlerEvent(ManagedBuildManager.java:3226) at org.eclipse.cdt.managedbuilder.internal.dataprovider.ConfigurationDataProvider.load(ConfigurationDataProvider.java:368) at org.eclipse.cdt.managedbuilder.internal.dataprovider.ConfigurationDataProvider.loadConfiguration(ConfigurationDataProvider.java:542) at org.eclipse.cdt.internal.core.settings.model.CProjectDescriptionManager.loadData(CProjectDescriptionManager.java:1115) at org.eclipse.cdt.internal.core.settings.model.CConfigurationDescriptionCache.loadData(CConfigurationDescriptionCache.java:95) at org.eclipse.cdt.internal.core.settings.model.CProjectDescription.loadDatas(CProjectDescription.java:196) at org.eclipse.cdt.internal.core.settings.model.xml.XmlProjectDescriptionStorage.loadProjectDescription(XmlProjectDescriptionStorage.java:486) at org.eclipse.cdt.internal.core.settings.model.xml.XmlProjectDescriptionStorage.getProjectDescription(XmlProjectDescriptionStorage.java:231) at org.eclipse.cdt.internal.core.settings.model.CProjectDescriptionManager.getProjectDescriptionInternal(CProjectDescriptionManager.java:416) at org.eclipse.cdt.internal.core.settings.model.CProjectDescriptionManager.getProjectDescription(CProjectDescriptionManager.java:398) at org.eclipse.cdt.internal.core.settings.model.CProjectDescriptionManager.getProjectDescription(CProjectDescriptionManager.java:393) at org.eclipse.cdt.internal.core.settings.model.CProjectDescriptionManager.getProjectDescription(CProjectDescriptionManager.java:386) at org.eclipse.cdt.internal.core.pdom.CProjectDescriptionListener.isProjectCreationComplete(CProjectDescriptionListener.java:87) at org.eclipse.cdt.internal.core.pdom.CProjectDescriptionListener$1.postponeIndexerSetup(CProjectDescriptionListener.java:39) at org.eclipse.cdt.internal.core.pdom.PDOMManager.postponeSetup(PDOMManager.java:1376) at org.eclipse.cdt.internal.core.pdom.PDOMManager$3.run(PDOMManager.java:723) at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54)
Found a trivial fix in org.eclipse.cdt.internal.core.settings.model.CConfigurationDescriptionCache.getBuildVariablesContributor() @Override public ICdtVariablesContributor getBuildVariablesContributor() { // Assume no contributor when data is not loaded yet if ( fData == null ) { return null; } return fData.getBuildVariablesContributor(); } We need to deliver a product based on this patch in late October, so we'll provide a repackaged cdt.core for this one. Do you think it would be possible to integrate this fix in 7.0.2? PS: would be great to commit it ASAP, so I can grab a CDT nightly build for my October delivery ;)
Can you attach the fix as eclipse patch? Also, it would help if you could provide a sample of build definition extension in order to reproduce the issue.
Hmm. We need to be very careful about just quietly handling this. AFAIK the cache objects represent the read-only configuration, so if fData is null here I worry that it'll never become non-null. Alternatively, how are clients meant to determine whether getMacros returns an invalid value because the configuration isn't correctly loaded, or because the value doesn't exist?
(In reply to comment #3) > Hmm. We need to be very careful about just quietly handling this. > > AFAIK the cache objects represent the read-only configuration, so if fData is > null here I worry that it'll never become non-null. > Alternatively, how are clients meant to determine whether getMacros returns an > invalid value because the configuration isn't correctly loaded, or because the > value doesn't exist? If you take a look at the (long) stack trace, you'll see that fData is null since it is currently under initialization (at org.eclipse.cdt.internal.core.settings.model.CConfigurationDescriptionCache.loadData(CConfigurationDescriptionCache.java:95)) And during this init, CDT is looking at the enabled tools And in this case a tool enablement is conditioned on a build variable which is contributed by a build macro provider The purpose of the fix is just to consider that during initialization, since we can't access to the Build Variables Contributor, we just consider we don't have one...
Created attachment 180586 [details] Patch for org.eclipse.cdt.core project (In reply to comment #2) > Can you attach the fix as eclipse patch? Also, it would help if you could > provide a sample of build definition extension in order to reproduce the issue. Patch created and attached. I work on a small sample plugin highlighting the issue.
Created attachment 180594 [details] Sample plugin helping to reproduce the issue
(In reply to comment #2) > Can you attach the fix as eclipse patch? Also, it would help if you could > provide a sample of build definition extension in order to reproduce the issue. Please use attached plug-in to reproduce the issue. This plug-in provides a new project type/toolchain/configuration base on MinGW one to build an exe file. The toolchain provides two compilers, enabled regarding the value of MySampleMacro build variable, contributed through org.foo.bar.bug327001.BuildMacroSupplier. You can verify the correct enablement of the tool by providing a generic variable (through the Preferences > Run & Debug > String Substitution) named "ToolVersion": * set it to "V2" to enable "tool2" * set it to anything else to enable "tool1" Until there, everything is OK. Now, just close and reopen the project, and you'll get the NPE mentioned above. If you give a try with the proposed fix, the project behaves correctly again when closed then reopened.
(In reply to comment #2) Hi Andrew, Please can you tell me if there is any chance to commit this patch before the end of next week? (just a matter of organization for us, to see if we need to publish a patched CDT by ourselves or not) Thanks.
I'll take a look. I won't promise anything yet as the core build model could be swampy when considering all implications. I'll need James' second opinion in any case.
Created attachment 180885 [details] alternative patch (In reply to comment #5) > Created an attachment (id=180586) > Patch for org.eclipse.cdt.core project I don't think checking for null is the correct fix here. Some questions are popping up: - Why a build variable is being evaluated in the context of configuration description being loaded? Either there is no need to evaluate or if there is the need wrong configuration description is used. - I see cases with CConfigurationDescriptionCache.copyBuildData(CBuildData, boolean) down in stack trace and getBuildVariablesContributor() is called when fInitializing is "true". Does it mean we are trying to copy from non-inited configuration or fInitializing is not reset properly, or, again, wrong description is used? Not sure, it smells fishy. On the other hand, I think that an exception evaluating one enablement expression should not abort the whole operation. I suggest to catch the exception, log it, consider the expression false, and proceed with evaluating next expression. This does not fix the root cause but would mitigate the consequences IMO. James, what do you think?
Hi Andrew, I just hope someone would find a definitive fix without logging anything... Because in our case, such a patch means an error entry in the workspace log for each project, each time the workbench is started...
(In reply to comment #10) > I don't think checking for null is the correct fix here. Some questions are > popping up: > ... > James, what do you think? I'm having difficulty with this as well. It seems that incorrectly evaluating the variable results in an invalid toolchain: FolderInfo.filterTools(ITool[], IManagedProject) line: 316 FolderInfo.getFilteredTools() line: 325 Configuration.getFilteredTools() line: 1053 ManagedBuildManager.performValueHandlerEvent(IConfiguration, int, boolean) line: 3298 where filterTools is returning a vector with just an assembler and linker. As soon as the data cache is available, the compiler tool is available. Isn't this discrepancy a real bug that will be masked by simply returning null?
If it is just messages in the log and you guys think we are better off letting exceptions loose while evaluating expressions - that is fine with me. It is a real bug of course regardless and if somebody develops a real fix it would be better of course.
So, is there any chance someone to commit one of the proposed patchs, even if the bug is not closed and a definitive fix has to be found?
Just an update concerning the initially proposed patch. We've integrated it for three weeks now, and we didn't found any regression. We took the option to provide our own CDT build for our November product delivery, but we strongly hope to have an "official" fix for next CDT 7.0.2 release (which would make us avoid rebuilding our own each time...) Thanks!
Just a thought I sent to cdt-dev mailing list, and I copy there, for history logging: My interpretation would be: We are in a case where fdata member is under initialization (cf CConfigurationDescriptionCache.loadData(CConfigurationDescriptionCache.java:95) in the stack trace) For any reason, we need to check if current instance provides a Build Variable Contributor (cf CConfigurationDescriptionCache.getBuildVariablesContributor(CConfigurationDescriptionCache.java:450)) As fdata is not yet initialized at this time, the patch proposal is to temporarily consider that there is no Build Variable Contributor (until fdata will be non-null) Since build variables seems not to be cached anywhere, the next time the variable is evaluated, fdata member is non-null and normal behavior is resumed.