Closed
Bug 1405567
Opened 7 years ago
Closed 7 years ago
LCOV data from js::GetCodeCoverageSummary() ignores line 1 and not-taken branches
Categories
(Core :: JavaScript Engine, defect, P3)
Tracking
()
RESOLVED
FIXED
mozilla59
Tracking | Status | |
---|---|---|
firefox59 | --- | fixed |
People
(Reporter: ptomato, Assigned: ptomato)
References
Details
(Whiteboard: [js:tech-debt][js:testability])
Attachments
(3 files, 4 obsolete files)
2.44 KB,
text/x-c++src
|
Details | |
13.60 KB,
patch
|
nbp
:
review+
|
Details | Diff | Splinter Review |
6.33 KB,
patch
|
ptomato
:
review+
|
Details | Diff | Splinter Review |
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36
Steps to reproduce:
There are a couple of tweaks that should be made in order to get the LCOV output similar to that produced by GCC or Clang:
- Line 1 is never marked as executable or executed
- Branches not taken are marked with hit count "-" instead of 0 (a dash means the whole branch instruction was never executed, 0 should mean the branch instruction was executed but the other branch was taken every time)
See the attachment for a minimal C++ program that demonstrates both problems.
Actual results:
The JS program being instrumented is:
1 let x = function () { return 0; };
2 let y = 0;
3 if (x() > 0)
4 y++;
5 else
6 y++;
The LCOV output is:
TN:Compartment_5f7fbb0700a800
SF:cov.js
FN:1,top-level
FN:1,x
FNDA:1,top-level
FNDA:1,x
FNF:2
FNH:2
BRDA:3,0,0,1
BRDA:3,0,1,-
BRF:2
BRH:1
DA:2,1
DA:3,1
DA:4,0
DA:6,1
LF:4
LH:3
end_of_record
Note that line 1 is not counted as executable and the totals of executable and executed lines are wrong. (Adding a \n to the beginning of the program does yield the correct totals and another DA: entry for line 2.)
Expected results:
The LCOV output should instead be this:
TN:Compartment_5f7fbb0700a800
SF:cov.js
FN:1,top-level
FN:1,x
FNDA:1,top-level
FNDA:1,x
FNF:2
FNH:2
BRDA:3,0,0,1
BRDA:3,0,1,0
BRF:2
BRH:1
DA:1,1
DA:2,1
DA:3,1
DA:4,0
DA:6,1
LF:5
LH:4
end_of_record
Comment 1•7 years ago
|
||
Thanks again for making these minimal test cases :)
(In reply to Philip Chimento [:ptomato] from comment #0)
> - Branches not taken are marked with hit count "-" instead of 0 (a dash
> means the whole branch instruction was never executed, 0 should mean the
> branch instruction was executed but the other branch was taken every time)
You are right!
I miss-interpreted the documentation from http://ltp.sourceforge.net/coverage/lcov/geninfo.1.php when I implemented it.
Assignee | ||
Comment 2•7 years ago
|
||
Glad to help make it easier for you. I wonder if I can help out with this one - it seems like it should be a straightforward patch.
Comment 3•7 years ago
|
||
(In reply to Philip Chimento [:ptomato] from comment #2)
> Glad to help make it easier for you. I wonder if I can help out with this
> one - it seems like it should be a straightforward patch.
That would be the fastest way to get this fixed ;)
The LCov output produced by SpiderMonkey is all located in:
http://searchfox.org/mozilla-central/source/js/src/vm/CodeCoverage.cpp
The dash symbols are manually checked and added here:
http://searchfox.org/mozilla-central/rev/7ba03cebf1dcf3b4c40c85a4efad42a5022cf1ec/js/src/vm/CodeCoverage.cpp#238,244,342,407
there are several test cases that you might have to update, which are checking for the LCov output, such as:
http://searchfox.org/mozilla-central/source/js/src/jit-test/tests/coverage
You can run these tests with:
python ./jit-test/jit_test.py ./path/to/js coverage
Updated•7 years ago
|
Priority: -- → P3
Whiteboard: [js:tech-debt][js:testability]
Assignee | ||
Comment 4•7 years ago
|
||
Attachment #8926195 -
Flags: review?(nicolas.b.pierron)
Assignee | ||
Comment 5•7 years ago
|
||
Attachment #8926196 -
Flags: review?(nicolas.b.pierron)
Assignee | ||
Updated•7 years ago
|
Attachment #8926195 -
Attachment is obsolete: true
Attachment #8926195 -
Flags: review?(nicolas.b.pierron)
Assignee | ||
Comment 6•7 years ago
|
||
Attachment #8926197 -
Flags: review?(nicolas.b.pierron)
Assignee | ||
Comment 7•7 years ago
|
||
The -/0 issue was indeed quite straightforward.
The off-by-one issue not so much, because leaving out the first line sidestepped another problem: a JSScript's first line can also be part of another JSScript. I'm not sure if the solution that I chose to ensure that each line's hit count was only written out once is the correct one, but so far it works for my purposes.
Assignee | ||
Comment 8•7 years ago
|
||
Attachment #8926624 -
Flags: review?(nicolas.b.pierron)
Assignee | ||
Updated•7 years ago
|
Attachment #8926196 -
Attachment is obsolete: true
Attachment #8926196 -
Flags: review?(nicolas.b.pierron)
Updated•7 years ago
|
Attachment #8926197 -
Flags: review?(nicolas.b.pierron) → review+
Comment 9•7 years ago
|
||
Comment on attachment 8926624 [details] [diff] [review]
Get LCOV stats for first line of script, and handle lines that belong to more than one script
Review of attachment 8926624 [details] [diff] [review]:
-----------------------------------------------------------------
::: js/src/vm/CodeCoverage.cpp
@@ +207,5 @@
> }
>
> + if ((oldLine != lineno || lineno == script->lineno()) &&
> + fallsthrough &&
> + !linesWritten_.has(lineno)) {
nit: put the { on a new line, when the condition span on multiple lines.
::: js/src/vm/CodeCoverage.h
@@ +77,5 @@
> size_t numLinesInstrumented_;
> size_t numLinesHit_;
> + // Which lines have had their statistics printed, since a line may be part
> + // of more than one JSScript.
> + HashSet<size_t, DefaultHasher<size_t>, SystemAllocPolicy> linesWritten_;
I don't think we want this behaviour. For example if we have the following code:
function f() { return function g() { if (arguments.length) return;
… some code …
} }
The reports that we might get will show the first line displayed, which does not correspond to the sum of all the lines.
This issues sounds like a post-processing issue to me than a lcov report generation issue.
Attachment #8926624 -
Flags: review?(nicolas.b.pierron)
Assignee | ||
Comment 10•7 years ago
|
||
I buy that, it indeed depends on what the expected behaviour is. Just to be clear, you want the sum of all the execution counts from each script for a particular line displayed?
Comment 11•7 years ago
|
||
(In reply to Philip Chimento [:ptomato] from comment #10)
> I buy that, it indeed depends on what the expected behaviour is. Just to be
> clear, you want the sum of all the execution counts from each script for a
> particular line displayed?
Yes, because you have multiple sources of information. Otherwise, the alternative of picking the first one depends on the creation & clean-up order which is not desirable, and potentially confusing.
Assignee | ||
Comment 12•7 years ago
|
||
Attachment #8928053 -
Flags: review?(nicolas.b.pierron)
Assignee | ||
Updated•7 years ago
|
Attachment #8926624 -
Attachment is obsolete: true
Comment 13•7 years ago
|
||
Comment on attachment 8928053 [details] [diff] [review]
Get LCOV stats for first line of script, and handle lines that belong to more than one script
Review of attachment 8928053 [details] [diff] [review]:
-----------------------------------------------------------------
2 remarks:
- If this is only per JSScript, then why should it be shared across all functions?
- It seems you are trying to solve the fact that lines are not being visited in an increasing line number, is that right?
::: js/src/vm/CodeCoverage.h
@@ +72,5 @@
> size_t numBranchesFound_;
> size_t numBranchesHit_;
>
> + // Holds lines statistics. A line may be part of more than one JSScript,
> + // so this is shared between all scripts in the source file.
nit: add a comment saying that line values are added, if the same line appears in multiple function, across multiple JSScript or multiple times within the same function.
Attachment #8928053 -
Flags: review?(nicolas.b.pierron) → review+
Assignee | ||
Comment 14•7 years ago
|
||
(In reply to Nicolas B. Pierron [:nbp] from comment #13)
> - If this is only per JSScript, then why should it be shared across all
> functions?
My understanding was that there is one JSScript per function plus one for the toplevel in the source file. I may be using the wrong term? The intention is one coverage hash map per source file.
> - It seems you are trying to solve the fact that lines are not being
> visited in an increasing line number, is that right?
They seem to be visited in an increasing line number within each function, but not across functions. The problem I'm really trying to solve with the hash map is So if you have this source
let x = function () { return 0; };
let y = 0;
if (x() > 0)
y++;
else
y++;
Then without the hashmap you get
DA:1,1
DA:2,1
DA:3,1
DA:4,0
DA:6,1
DA:1,1
Line 1 is repeated because it's covered both by the toplevel JSScript and the JSScript for function x, and added to outDA_ by two subsequent invocations of LCovSource::writeScript(). So it's not just a question of reordering the lines.
> ::: js/src/vm/CodeCoverage.h
> @@ +72,5 @@
> > size_t numBranchesFound_;
> > size_t numBranchesHit_;
> >
> > + // Holds lines statistics. A line may be part of more than one JSScript,
> > + // so this is shared between all scripts in the source file.
>
> nit: add a comment saying that line values are added, if the same line
> appears in multiple function, across multiple JSScript or multiple times
> within the same function.
Will do.
Assignee | ||
Comment 15•7 years ago
|
||
Assignee | ||
Updated•7 years ago
|
Attachment #8928053 -
Attachment is obsolete: true
Assignee | ||
Updated•7 years ago
|
Attachment #8928388 -
Flags: review+
Assignee | ||
Updated•7 years ago
|
Keywords: checkin-needed
Comment 16•7 years ago
|
||
Pushed by shindli@mozilla.com:
https://hg.mozilla.org/integration/mozilla-inbound/rev/6341e29e55f5
Get LCOV stats for first line of script, and handle lines that belong to more than one script. r=nbp
https://hg.mozilla.org/integration/mozilla-inbound/rev/994d32bb01a3
Mark LCOV branches not taken with 0, and not executed with -. r=nbp
Keywords: checkin-needed
Comment 17•7 years ago
|
||
bugherder |
https://hg.mozilla.org/mozilla-central/rev/6341e29e55f5
https://hg.mozilla.org/mozilla-central/rev/994d32bb01a3
Status: UNCONFIRMED → RESOLVED
Closed: 7 years ago
status-firefox59:
--- → fixed
Resolution: --- → FIXED
Target Milestone: --- → mozilla59
Updated•6 years ago
|
Assignee: nobody → philip.chimento
You need to log in
before you can comment on or make changes to this bug.
Description
•