Bug 1554332 - annobin: Plugin breaks -pg/gprof on ppc64
Summary: annobin: Plugin breaks -pg/gprof on ppc64
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Fedora
Classification: Fedora
Component: annobin
Version: rawhide
Hardware: ppc64
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
Assignee: Nick Clifton
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks: 1548438
TreeView+ depends on / blocked
 
Reported: 2018-03-12 13:00 UTC by Florian Weimer
Modified: 2018-03-26 22:29 UTC (History)
2 users (show)

Fixed In Version: annobin-5.0-1.fc29 annobin-5.1-1.fc28
Clone Of:
Environment:
Last Closed: 2018-03-26 22:29:27 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)
tst-gmon.c (1.30 KB, text/plain)
2018-03-12 13:00 UTC, Florian Weimer
no flags Details
Assembler file with annobin disabled (8.38 KB, text/plain)
2018-03-12 13:02 UTC, Florian Weimer
no flags Details
Assembler file with annobin enabled (11.38 KB, text/plain)
2018-03-12 13:03 UTC, Florian Weimer
no flags Details
gmon.out (684 bytes, application/octet-stream)
2018-03-14 12:41 UTC, Florian Weimer
no flags Details

Description Florian Weimer 2018-03-12 13:00:52 UTC
Created attachment 1407177 [details]
tst-gmon.c

Enabling the annobin plugin breaks the tst-gmon family of glibc test cases.  gprof is no longer able to recover the correct function names.

Seen with:

annobin-3.5-1.fc29.ppc64
binutils-2.30-12.fc29.ppc64
gcc-8.0.1-0.16.fc29.ppc64

Test case source file attached.   Compile it with “gcc -O2 -pg -g” and “gcc -O2 -pg -g --specs=/usr/lib/rpm/redhat/redhat-annobin-cc1”.

Expected “gprof -C” output is something like this (the dot is due to the function descriptors on ppc64 and is expected):

tst-gmon.c:29: (.f2:0x10000750) 1000 executions
tst-gmon.c:24: (.f1:0x10000720) 2000 executions

Actual output with annobin enabled is:

tst-gmon.c:29: (.f2:0x10000750) 1000 executions
<unknown>:0: (._start:0x10000540) 2000 executions

Comment 1 Florian Weimer 2018-03-12 13:02:42 UTC
Created attachment 1407178 [details]
Assembler file with annobin disabled

Comment 2 Florian Weimer 2018-03-12 13:03:02 UTC
Created attachment 1407179 [details]
Assembler file with annobin enabled

Comment 3 Florian Weimer 2018-03-12 13:04:15 UTC
This could also be an issue with how gprof parses the binary.

Nick, please let me know if you want me to dig into this, but maybe this looks familiar to you?

Comment 4 Nick Clifton 2018-03-12 13:36:01 UTC
Hi Florian,

  Yes - I will investigate this one.

Cheers
  Nick

Comment 5 Nick Clifton 2018-03-14 11:56:14 UTC
Hi Florian,

  Would it be possible for you to upload the gmon.out created from the
  run of the annotated binary ?

Cheers
  Nick

Comment 6 Florian Weimer 2018-03-14 12:07:11 UTC
(In reply to Nick Clifton from comment #5)
>   Would it be possible for you to upload the gmon.out created from the
>   run of the annotated binary ?

Working on it.  I don't know how quickly I can obtain a Fedora ppc64 machine again.

Comment 7 Florian Weimer 2018-03-14 12:41:31 UTC
Created attachment 1407935 [details]
gmon.out

The gmon.out file contents is identical for both binaries.

Comment 8 Nick Clifton 2018-03-14 13:18:57 UTC
Thanks - I am attempting to reproduce the problem now...

Comment 9 Nick Clifton 2018-03-15 10:46:05 UTC
Darn - this is a hard problem to reproduce.  Everything I try fails in some way...

Florian - would you mind doing some more debugging for me if possible ?

Specifically:

  * Are the gmon.out files the same for the annotated executable
    and the un-annotated executable ?  (I have a theory that the
    problem might lie in the *generation* of the gmon.out file,
    rather than in its consumption).

  * Does the problem go away if you change f1() so that it is no 
    longer weak ?

  * What does "addr2line -e a.out 0x10000720" show for the annotated
    a.out file ?

Thanks.

Cheers
  Nick

Comment 10 Florian Weimer 2018-03-15 11:46:11 UTC
(In reply to Nick Clifton from comment #9)
> Darn - this is a hard problem to reproduce.  Everything I try fails in some
> way...
> 
> Florian - would you mind doing some more debugging for me if possible ?
> 
> Specifically:
> 
>   * Are the gmon.out files the same for the annotated executable
>     and the un-annotated executable ?  (I have a theory that the
>     problem might lie in the *generation* of the gmon.out file,
>     rather than in its consumption).

No, as I said, the files are identical:

<mock-chroot> sh-4.4# gcc -O2 -pg -g tst-gmon.c
<mock-chroot> sh-4.4# ./a.out 
<mock-chroot> sh-4.4# sha256sum gmon.out
34f2734776bc6d049d24c5cc36dbb4f292a735847a1ce9abdfaddd3380f4a40c  gmon.out
<mock-chroot> sh-4.4# gcc -O2 -pg -g --specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 tst-gmon.c
<mock-chroot> sh-4.4# ./a.out 
<mock-chroot> sh-4.4# sha256sum gmon.out
34f2734776bc6d049d24c5cc36dbb4f292a735847a1ce9abdfaddd3380f4a40c  gmon.out

>   * Does the problem go away if you change f1() so that it is no 
>     longer weak ?

The compiler barrier implied by the weak attribute is unfortunately needed by this test.

If I remove it, I have to compile with -O0 to retain the test objective.  The difference in output persists, although you now see f1, f2, and f3 in the non-annobin case:

/var/tmp/tst-gmon.c:24: (.f1:0x100006c4) 2000 executions
/var/tmp/tst-gmon.c:29: (.f2:0x10000704) 1000 executions
/var/tmp/tst-gmon.c:37: (.f3:0x10000748) 1 executions

With annobin:

<unknown>:0: (._start:0x10000500) 2000 executions
/var/tmp/tst-gmon.c:29: (.f2:0x10000704) 1000 executions
/var/tmp/tst-gmon.c:37: (.f3:0x10000748) 1 executions

>   * What does "addr2line -e a.out 0x10000720" show for the annotated
>     a.out file ?

<mock-chroot> sh-4.4# addr2line -e a.out 0x10000720
/var/tmp/tst-gmon.c:24

Comment 11 Nick Clifton 2018-03-15 17:27:47 UTC
    Right - thanks to lots of help from Florian I have been able to track down 
    the problem:  The annobin plugin creates a symbol called tst_gmon.c to mark 
    the start of the compiled tst_gmon.c code.  Unfortunately this symbol has 
    exactly the same address as the first function in tst-gmon.c, namely f1().

    This matters because the code in the BFD library which generates the dot 
    prefixed function descriptor symbols will not generate a symbol for any
    function which already has a symbol at its (real) start address.  This means
    that symbols .f2 and .f3 are generated but not .f1.  The generated symbols 
    are biased to point to the entry points in the PowerPC opd, and it is these 
    addresses that get recorded in the gmon.out file generated by the profiling 
    code.

    Hence when gprof runs, it cannot find a symbol to match the opd entry point
    for f1() and so it selects the nearest symbol before that, which happens to 
    be ._start.

    The solution I am trying is to bias the file start symbol generated by the
    annobin plugin, so that it no longer matches the start of the file, or the
    start of the f1() function.  This appears to work, and the patch has been
    applied to the latest annobin release: annobin-5.0-1.fc29

    (Note - the jump in the annobin version number is not significant.  I am
    just trying to keep the annobin version in sync with the plugin version).

    A small patch is needed for readelf to be able to cope with the changed
    file symbols, but that is a minor issue which I will fix tomorrow.

Comment 12 Florian Weimer 2018-03-15 18:31:11 UTC
(In reply to Nick Clifton from comment #11)
>     Right - thanks to lots of help from Florian I have been able to track
> down 
>     the problem:  The annobin plugin creates a symbol called tst_gmon.c to
> mark 
>     the start of the compiled tst_gmon.c code.  Unfortunately this symbol
> has 
>     exactly the same address as the first function in tst-gmon.c, namely
> f1().
> 
>     This matters because the code in the BFD library which generates the dot 
>     prefixed function descriptor symbols will not generate a symbol for any
>     function which already has a symbol at its (real) start address.

Isn't it a bug that BFD doesn't generate a function descriptor symbol if the symbol in question is STT_NOTYPE?

(Just a thought, I'm no ELF/linker POWER expert.)

Comment 13 Nick Clifton 2018-03-16 10:55:12 UTC
Hi Florian,

> Isn't it a bug that BFD doesn't generate a function descriptor symbol if the
> symbol in question is STT_NOTYPE?
> 
> (Just a thought, I'm no ELF/linker POWER expert.)

Maybe.  This is PowerPC specific code, written by Alan Modra, and he
usually gets things like this right.

I did think about creating a BFD patch to skip STT_NOTYPE symbols, but
in the end I felt that it was safest just to modify the placement of the
annobin symbols instead.

Cheers
  Nick

Comment 14 Fedora Update System 2018-03-20 13:15:17 UTC
annobin-5.1-1.fc28 has been submitted as an update to Fedora 28. https://bodhi.fedoraproject.org/updates/FEDORA-2018-2c415304da

Comment 15 Fedora Update System 2018-03-20 14:55:44 UTC
annobin-5.1-1.fc28 has been pushed to the Fedora 28 testing repository. If problems still persist, please make note of it in this bug report.
See https://fedoraproject.org/wiki/QA:Updates_Testing for
instructions on how to install test updates.
You can provide feedback for this update here: https://bodhi.fedoraproject.org/updates/FEDORA-2018-2c415304da

Comment 16 Fedora Update System 2018-03-26 22:29:27 UTC
annobin-5.1-1.fc28 has been pushed to the Fedora 28 stable repository. If problems still persist, please make note of it in this bug report.


Note You need to log in before you can comment on or make changes to this bug.