Bug 447554 - gcov not handling linked files
- Fix number of runs counter to come from program summary
instead of object summary as that has been obsoleted
- Fix logic to handle case where we end up with an IFileEditorInput
and we want an IFileStore (don't return null and end up
using a source-not-found editor)
- Add a method to get all projects we are tracking for gcov
- Add a visitor class to search a project for a linked-in
resource we are trying to open from the gcov view
Change-Id: Ieeb4c8a047a95da239e7b625f717a1d44fad8f31
Reviewed-on: https://git.eclipse.org/r/35155
Reviewed-by: Roland Grunberg <rgrunber@redhat.com>
Tested-by: Roland Grunberg <rgrunber@redhat.com>
(cherry picked from commit 75704836bd061a8d66588792170d9528a0946b3c)
Reviewed-on: https://git.eclipse.org/r/35156
Tested-by: Hudson CI
Reviewed-by: Jeff Johnston <jjohnstn@redhat.com>
Tested-by: Jeff Johnston <jjohnstn@redhat.com>
diff --git a/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/parser/CovManager.java b/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/parser/CovManager.java
index 42894f6..3f5d45d 100644
--- a/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/parser/CovManager.java
+++ b/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/parser/CovManager.java
@@ -157,7 +157,8 @@
// to fill the view title
if (daRcrd != null)
- nbrPgmRuns = daRcrd.getObjSmryNbrPgmRuns();
+ nbrPgmRuns = daRcrd.getPgmSmryNbrPgmRuns();
+
/* process counts from data parsed */
// solve graph for each function
diff --git a/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/parser/GcdaRecordsParser.java b/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/parser/GcdaRecordsParser.java
index a4c901a..107d13a 100644
--- a/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/parser/GcdaRecordsParser.java
+++ b/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/parser/GcdaRecordsParser.java
@@ -36,6 +36,7 @@
private final ArrayList<GcnoFunction> fnctns;
private long objSmryNbrPgmRuns = 0;
private long pgmSmryChksm = 0;
+ private long pgmSmryNbrPgmRuns = 0;
private long objSmryChksm = 0;
private long objSmryArcCnts = 0;
private long objSmrytotalCnts = 0;
@@ -212,7 +213,9 @@
case GCOV_TAG_PROGRAM_SUMMARY: {
// long[] pgmSmryskips = new long[(int) length];
pgmSmryChksm = (stream.readInt() & MasksGenerator.UNSIGNED_INT_MASK);
- for (int i = 0; i < length - 1; i++) {
+ stream.readInt();
+ pgmSmryNbrPgmRuns = (stream.readInt() & MasksGenerator.UNSIGNED_INT_MASK);
+ for (int i = 0; i < length - 3; i++) {
// pgmSmryskips[i] = (stream.readInt() & MasksGenerator.UNSIGNED_INT_MASK);
stream.readInt();
}
@@ -269,14 +272,22 @@
* @return the objSmrySumMax
*/
public long getObjSmrySumMax() {
- return objSmrySumMax;
+ return objSmrySumMax;
}
/**
* @return the pgmSmryChksm
*/
public long getPgmSmryChksm() {
- return pgmSmryChksm;
+ return pgmSmryChksm;
}
+ /**
+ * @return the prgSmryNbrPgmRuns
+ */
+ public long getPgmSmryNbrPgmRuns() {
+ return pgmSmryNbrPgmRuns;
+ }
+
+
}
diff --git a/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/GcovAnnotationModel.java b/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/GcovAnnotationModel.java
index ceb6892..50f7567 100644
--- a/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/GcovAnnotationModel.java
+++ b/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/GcovAnnotationModel.java
@@ -17,11 +17,16 @@
import java.util.Iterator;
import java.util.List;
+import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.IBinary;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.ui.CDTUITools;
import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceProxy;
+import org.eclipse.core.resources.IResourceProxyVisitor;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
@@ -127,22 +132,20 @@
}
private void updateAnnotations(boolean force) {
- // We do not annotate any editor displaying content of a project not tracked.
- ICElement element = CDTUITools.getEditorInputCElement(editor.getEditorInput());
- if (!GcovAnnotationModelTracker.getInstance().containsProject(element.getCProject().getProject())) {
- return;
- }
+ // We used to not annotate any editor displaying content of an element whose project was not tracked.
+ // This logic fails when we have a linked-in file which won't point back to a project that has
+ // been registered so it has been removed.
- SourceFile coverage = findSourceCoverageForEditor();
- if (coverage != null) {
- if (!annotated || force) {
- createAnnotations(coverage);
- }
- } else {
- if (annotated) {
- clear();
- }
- }
+ SourceFile coverage = findSourceCoverageForEditor();
+ if (coverage != null) {
+ if (!annotated || force) {
+ createAnnotations(coverage);
+ }
+ } else {
+ if (annotated) {
+ clear();
+ }
+ }
}
private SourceFile findSourceCoverageForEditor() {
@@ -160,39 +163,94 @@
return findSourceCoverageForElement(element);
}
+ // Private resource proxy visitor to run through a project's resources to see if
+ // it contains a link to a C element's resource. This allows us to locate the
+ // project (and it's binary) that has gcov data for a particular resource that has been linked into
+ // the project. We can't just query the resource for it's project in such a case. This
+ // is part of the fix for bug: 447554
+ private class FindLinkedResourceVisitor implements IResourceProxyVisitor {
+
+ final private ICElement element;
+ private boolean keepSearching = true;
+ private boolean found;
+
+ public FindLinkedResourceVisitor(ICElement element) {
+ this.element = element;
+ }
+
+ public boolean foundElement() {
+ return found;
+ }
+
+ @Override
+ public boolean visit(IResourceProxy proxy) {
+ if (proxy.isLinked() && proxy.requestResource().getLocationURI().equals(element.getLocationURI())) {
+ found = true;
+ keepSearching = false;
+ }
+ return keepSearching;
+ }
+
+ }
+
private SourceFile findSourceCoverageForElement(ICElement element) {
- List<SourceFile> sources = new ArrayList<> ();
- ICProject cProject = element.getCProject();
- IPath target = GcovAnnotationModelTracker.getInstance().getBinaryPath(cProject.getProject());
- try {
- IBinary[] binaries = cProject.getBinaryContainer().getBinaries();
- for (IBinary b : binaries) {
- if (b.getResource().getLocation().equals(target)) {
- CovManager covManager = new CovManager(b.getResource().getLocation().toOSString());
- covManager.processCovFiles(covManager.getGCDALocations(), null);
- sources.addAll(covManager.getAllSrcs());
- }
- }
- } catch (IOException|CoreException|InterruptedException e) {
- }
+ List<SourceFile> sources = new ArrayList<> ();
+ ICProject cProject = element.getCProject();
+ IPath target = GcovAnnotationModelTracker.getInstance().getBinaryPath(cProject.getProject());
+ if (target == null) {
+ // We cannot find a target for this element, using it's project.
+ // This can be caused by linking in a file to the project which may
+ // not have a project or may point to another unseen project if the file originated
+ // there.
+ IProject[] trackedProjects = GcovAnnotationModelTracker.getInstance().getTrackedProjects();
+ for (IProject proj : trackedProjects) {
+ // Look at all projects that are registered for gcov viewing and see if the
+ // element is linked in.
+ try {
+ FindLinkedResourceVisitor visitor = new FindLinkedResourceVisitor(element);
+ proj.accept(visitor, IResource.DEPTH_INFINITE);
+ // If we find a match, make note of the target and the real C project.
+ if (visitor.foundElement()) {
+ target = GcovAnnotationModelTracker.getInstance().getBinaryPath(proj);
+ cProject = CoreModel.getDefault().getCModel().getCProject(proj.getName());
+ break;
+ }
+ } catch (CoreException e) {
+ }
+ }
+ if (target == null)
+ return null;
+ }
- for (SourceFile sf : sources) {
- IPath sfPath = new Path(sf.getName());
- IFile file = STLink2SourceSupport.getFileForPath(sfPath, cProject.getProject());
- if (file != null && element.getResource().getLocation().equals(file.getLocation())) {
- return sf;
- }
- }
+ try {
+ IBinary[] binaries = cProject.getBinaryContainer().getBinaries();
+ for (IBinary b : binaries) {
+ if (b.getResource().getLocation().equals(target)) {
+ CovManager covManager = new CovManager(b.getResource().getLocation().toOSString());
+ covManager.processCovFiles(covManager.getGCDALocations(), null);
+ sources.addAll(covManager.getAllSrcs());
+ }
+ }
+ } catch (IOException|CoreException|InterruptedException e) {
+ }
- IPath binFolder = target.removeLastSegments(1);
- for (SourceFile sf : sources) {
- String sfPath = Paths.get(binFolder.toOSString()).resolve(sf.getName()).normalize().toString();
- if (sfPath.equals(element.getLocationURI().getPath())) {
- return sf;
- }
- }
+ for (SourceFile sf : sources) {
+ IPath sfPath = new Path(sf.getName());
+ IFile file = STLink2SourceSupport.getFileForPath(sfPath, cProject.getProject());
+ if (file != null && element.getResource().getLocation().equals(file.getLocation())) {
+ return sf;
+ }
+ }
- return null;
+ IPath binFolder = target.removeLastSegments(1);
+ for (SourceFile sf : sources) {
+ String sfPath = Paths.get(binFolder.toOSString()).resolve(sf.getName()).normalize().toString();
+ if (sfPath.equals(element.getLocationURI().getPath())) {
+ return sf;
+ }
+ }
+
+ return null;
}
private void createAnnotations(SourceFile sourceFile) {
diff --git a/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/GcovAnnotationModelTracker.java b/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/GcovAnnotationModelTracker.java
index 06d3208..04ee132 100644
--- a/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/GcovAnnotationModelTracker.java
+++ b/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/GcovAnnotationModelTracker.java
@@ -126,7 +126,11 @@
}
public void addProject (IProject project, IPath binary) {
- trackedProjects.put(project, binary);
+ trackedProjects.put(project, binary);
+ }
+
+ public IProject[] getTrackedProjects() {
+ return trackedProjects.keySet().toArray(new IProject[0]);
}
public void dispose() {
diff --git a/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/OpenSourceFileAction.java b/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/OpenSourceFileAction.java
index aa421fb..ca7656d 100644
--- a/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/OpenSourceFileAction.java
+++ b/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/OpenSourceFileAction.java
@@ -29,6 +29,7 @@
import org.eclipse.linuxtools.internal.gcov.parser.SourceFile;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IURIEditorInput;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
@@ -46,17 +47,24 @@
// FIXME: move this method in binutils plugin.
private static IFileStore getFileStore(IProject project, IPath path) {
- IEditorInput input = STLink2SourceSupport.getEditorInput(path, project);
- if (input instanceof IURIEditorInput) {
- IURIEditorInput editorInput = (IURIEditorInput) input;
- URI uri = editorInput.getURI();
- try {
- return EFS.getStore(uri);
- } catch (CoreException e) {
- return null;
- }
- }
- return null;
+ IEditorInput input = STLink2SourceSupport.getEditorInput(path, project);
+ if (input instanceof IURIEditorInput) {
+ IURIEditorInput editorInput = (IURIEditorInput) input;
+ URI uri = editorInput.getURI();
+ try {
+ return EFS.getStore(uri);
+ } catch (CoreException e) {
+ return null;
+ }
+ } else if (input instanceof IFileEditorInput) {
+ IFile f = ((IFileEditorInput) input).getFile();
+ try {
+ return EFS.getStore(f.getLocationURI());
+ } catch (CoreException e) {
+ return null;
+ }
+ }
+ return null;
}
public static void openAnnotatedSourceFile(IProject project, IFile binary, SourceFile sourceFile, int lineNumber) {