diff options
author | Jeff Johnston | 2014-10-20 18:12:19 +0000 |
---|---|---|
committer | Roland Grunberg | 2014-10-20 19:21:32 +0000 |
commit | 75704836bd061a8d66588792170d9528a0946b3c (patch) | |
tree | 4c7344c75fd74a1c847d1ca0e016c28b939f45ed /gcov | |
parent | 9b65ccd480f6e6dd78f896a040b9f7a21c6a23c3 (diff) | |
download | org.eclipse.linuxtools-75704836bd061a8d66588792170d9528a0946b3c.tar.gz org.eclipse.linuxtools-75704836bd061a8d66588792170d9528a0946b3c.tar.xz org.eclipse.linuxtools-75704836bd061a8d66588792170d9528a0946b3c.zip |
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>
Diffstat (limited to 'gcov')
5 files changed, 145 insertions, 63 deletions
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 42894f6802..3f5d45d6c0 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 @@ public class CovManager implements Serializable { // 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 a4c901a97f..107d13a67b 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 @@ public class GcdaRecordsParser { 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 @@ public class GcdaRecordsParser { 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 @@ public class GcdaRecordsParser { * @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 ceb6892e2f..50f756711f 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.Arrays; 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 @@ public final class GcovAnnotationModel implements IAnnotationModel { } 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; - } - - SourceFile coverage = findSourceCoverageForEditor(); - if (coverage != null) { - if (!annotated || force) { - createAnnotations(coverage); - } - } else { - if (annotated) { - clear(); - } - } + // 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(); + } + } } private SourceFile findSourceCoverageForEditor() { @@ -160,39 +163,94 @@ public final class GcovAnnotationModel implements IAnnotationModel { return findSourceCoverageForElement(element); } - 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) { - } - - 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; - } - } + // 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; + } - 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 SourceFile findSourceCoverageForElement(ICElement element) { + 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; + } + + 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) { + } + + 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; + } + } + + 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 06d3208623..04ee132a27 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 final class GcovAnnotationModelTracker { } 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 aa421fb48e..ca7656d397 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.Activator; 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 @@ public final class OpenSourceFileAction { // 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) { |