Trace Block Inconsistent with Coverage Map

Joel Sherrill joel at rtems.org
Wed Jul 12 17:42:25 UTC 2017


On Wed, Jul 12, 2017 at 12:13 PM, Cillian O'Donnell <cpodonnell8 at gmail.com>
wrote:

> I just want to give an update to my understanding of this problem as
> I'm not sure I was clear enough in the IRC meeting. We ended up
> talking about nops but I think the problem is something else.
>
> So when there is a successful covoar run, it will generate a report
> but also finish with this message.
>
> *** Trace block is inconsistent with coverage map
> *** Trace block (0x4000c2cc - 0x4000c2ec) for 36 bytes
> *** Coverage map /home/cpod/coverage_test/leon3/coverage/base_sp.exe.cov
>
> -----------------------------
>
> The coverage map is 24 bytes:
>
> (gdb) p/x *entry
> $2 = {pc = 0x4000c2cc, size = 0x24, op = 0x12}
>
> -----------------------------
>
> The disassembly block in question is:
>
> 4000c2cc <_Objects_Get_information_id>:
> 4000c2cc:   83 32 20 18     srl  %o0, 0x18, %g1
>
> Objects_Information *_Objects_Get_information_id(
>   Objects_Id  id
> )
> {
>   return _Objects_Get_information(
> 4000c2d0:   93 32 20 1b     srl  %o0, 0x1b, %o1
> 4000c2d4:   90 08 60 07     and  %g1, 7, %o0
> 4000c2d8:   82 13 c0 00     mov  %o7, %g1
> 4000c2dc:   40 00 00 02     call  4000c2e4 <_Objects_Get_information>
> 4000c2e0:   9e 10 40 00     mov  %g1, %o7
>
> 4000c2e4 <_Objects_Get_information>:
>
> Objects_Information *_Objects_Get_information(
>   Objects_APIs   the_api,
>   uint16_t       the_class
> )
> {
> 4000c2e4:   9d e3 bf a0     save  %sp, -96, %sp
>   Objects_Information *info;
>   int the_class_api_maximum;
>
>   if ( !the_class )
> 4000c2e8:   80 a6 60 00     cmp  %i1, 0
> 4000c2ec:   02 80 00 19     be  4000c350 <_Objects_Get_information+0x6c>
> 4000c2f0:   01 00 00 00     nop
>
> ------------------------------------
>
> I have checked this out on base_sp.exe and ticker.exe where the same
> inconsistency appears in both. Couverture-QEMU decides the trace block
> encompasses that entire block
>
> Whereas from the covoar side the objdump is always processed line by
> line and a regex is checked to determine what kind of line it is.
>
> 408       items = sscanf(
> 409         inputBuffer,
> 410         "%x <%[^>]>%c",
> 411         &offset, symbol, &terminator1
> 412       );
>
> If there is a match for all 3 items then this is a new function
>
> 415       if ((items == 3) && (terminator1 == ':')) {
> 416
> 417         endAddress = executableInformation->getLoadAddress() + offset
> - 1;
>
>
> So the objdump above is always processed as 2 seperate sections.
>
> One for:
> 4000c2cc <_Objects_Get_information_id>:
>
>
> And one for:
> 4000c2e4 <_Objects_Get_information>:
>
> The size from Objects_Get_information_id to Objects_Get_information is
> 24 bytes which is the coverage map.
> The size of both functions combined is 36 bytes which is the
> Couverture trace block.
>

OK. I think I finally understand enough to believe that covoar is at fault
here.
It is complicated because of the multiple pieces in action but you have
given plenty of information. Let's see if I can explain how the different
sources of data are (incorrectly) being thought to not match up.

First, it is not about having a varying amount of padding at the end
of a method so the next method is on a cache-aligned boundary.

Qemu traces reflect that qemu executes "translation blocks" of code.
Each block is up to a point of potential change of execution flow. This
means they should always end with a call, return from subroutine,
branch, trap, etc.

Internally, covoar processes methods which have C statements and
assembly statements. Each method can have "ranges" of covered and
uncovered code. That's the basis for the reports at the end.

The trace reader for qemu is getting confused trying to interpret
the branch information. It is assuming that the branch is the
last instruction in the range in aCoverageMap.

For some unknown reason, the trace reader class appears to be
checking that the couverture trace record precisely matches the
size of the associated uncovered range. I don't think it always can.
It probably is always <= size of the code in aCoverageMap.

CoverageMapBase.cc has a "dump()" method to assist in debugging.

I think the math for associating the branch information is wrong.
It should compute the address of the branch instruction, verify
it is the start of an instruction, that it is a branch, and then set
was taken or was not taken.

Well..crap.. the output variables offset_t and offset_e from  the calls
being checked on the if:
are not even being used.

          if ((aCoverageMap->determineOffset( a, &offset_a ) != true)   ||
             (aCoverageMap->determineOffset( entry->pc, &offset_e ) !=
true))
          {

Disable the if and check if things look better.

In other words, just assume that it is consistent.  We have already looped
through the "aCoverageMap" and set was executed in the loop around
135.



>
> Couverture could possibly be doing something more sophisticated to
> determine the end of the block or it could just be wrong. So the next
> thing I'm doing is figuring out exactly how Couverture is processing
> this.
>
> For both cases the trace op code is 0x12 which means 'Branch fully
> executed' and 'Branch not taken'. I'm trying to find one with op code
> 0x11 which would mean the 'branch is taken' and possibly it might be
> processed differently in this case. The only place both these
> functions appear in the source is libtests/dl04 and dl05. I'm checking
> those out at the moment.
>
> Thanks,
>
> Cillian.
> _______________________________________________
> devel mailing list
> devel at rtems.org
> http://lists.rtems.org/mailman/listinfo/devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/devel/attachments/20170712/ef243724/attachment-0002.html>


More information about the devel mailing list