public inbox for libabigail@sourceware.org
 help / color / mirror / Atom feed
* [Bug default/19734] New: Shifted exported fields in c++ classes are not detected as abi breakage
@ 2016-01-01  0:00 dank at kegel dot com
  2016-01-01  0:00 ` [Bug default/19734] Libabigail skips the 'this' pointer when comparing two member functions dodji at redhat dot com
  2020-11-11 16:07 ` maennich at android dot com
  0 siblings, 2 replies; 3+ messages in thread
From: dank at kegel dot com @ 2016-01-01  0:00 UTC (permalink / raw)
  To: libabigail

https://sourceware.org/bugzilla/show_bug.cgi?id=19734

            Bug ID: 19734
           Summary: Shifted exported fields in c++ classes are not
                    detected as abi breakage
           Product: libabigail
           Version: unspecified
            Status: NEW
          Severity: normal
          Priority: P2
         Component: default
          Assignee: dodji at redhat dot com
          Reporter: dank at kegel dot com
                CC: libabigail at sourceware dot org
  Target Milestone: ---

abidiff fails to detect abi breakage from added structure members.
To demonstrate, create these files, then run foo.sh:

::::::::::::::
foo_h
::::::::::::::
struct __attribute__ ((visibility ("default"))) lego {
    #ifdef VERSION2
    char buggy_symbol[10];
    #else
    char buggy_symbol[5];
    #endif
    int payload;

    lego();

    int get() { return payload; }
    int set(int x) { payload = x; }
};
::::::::::::::
foo.cpp
::::::::::::::
#include "foo.h"

lego::lego() : payload(42) {}
::::::::::::::
main.cpp
::::::::::::::
#include "foo.h"
#include <assert.h>

int main(int argc, char **argv)
{
    lego x;
    assert(x.get() == 42);
    return (x.get() == 42) ? 0 : 1;
}
::::::::::::::
foo.sh
::::::::::::::
#!/bin/sh
set -e
set -x
rm -rf v1 v2
mkdir v1 v2
cp foo_h v1/foo.h
echo "#define VERSION2 1" > v2/foo.h
cat foo_h >> v2/foo.h

# Build library version 1
g++ -g -I v1 foo.cpp -shared -fpic -o libfoo1.so -g
# Build library version 2
g++ -g -I v2 foo.cpp -shared -fpic -o libfoo2.so -g
# abidiff reports no ABI breakage between version 1 and version 2
abidiff libfoo1.so libfoo2.so
# but abidw shows the abi breakage is potentially detectable:
abidw libfoo1.so > abi1.xml
abidw libfoo2.so > abi2.xml
diff -u abi1.xml abi2.xml

# App built against version 1 runs fine against version 1
g++ -g -I v1 main.cpp ./libfoo1.so -o main1
./main1 || echo failed
# App built against version 2 crashes when run against version 1 despite
all-clear from abidiff
g++ -g -I v2 main.cpp ./libfoo1.so -o main2
./main2 || echo failed

-- 
You are receiving this mail because:
You are on the CC list for the bug.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [Bug default/19734] Libabigail skips the 'this' pointer when comparing two member functions
  2016-01-01  0:00 [Bug default/19734] New: Shifted exported fields in c++ classes are not detected as abi breakage dank at kegel dot com
@ 2016-01-01  0:00 ` dodji at redhat dot com
  2020-11-11 16:07 ` maennich at android dot com
  1 sibling, 0 replies; 3+ messages in thread
From: dodji at redhat dot com @ 2016-01-01  0:00 UTC (permalink / raw)
  To: libabigail

https://sourceware.org/bugzilla/show_bug.cgi?id=19734

dodji at redhat dot com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |ASSIGNED
            Summary|Shifted exported fields in  |Libabigail skips the 'this'
                   |c++ classes are not         |pointer when comparing two
                   |detected as abi breakage    |member functions

--- Comment #1 from dodji at redhat dot com ---
Right, this is a real issue.

The problem is that today, when libabigail compares two functions (two
constructors, for instance) it doesn't compare their implicit 'this' parameter.

In the case of the example, lego::lego() is the only function that has the
"lego" type as a sub-type.  But that lego type, is reachable only through the
implicit 'this' parameter of that function.  As libabigail skips that implicit
this pointer during its comparison, it doesn't see the changes that were made
to the lego type.

Just to illustrate my point, I added another member function lego.  That member
explicitly takes a parameter which type "contains" the lego type.

Here is the diff of my change to your example:
----------------------------------->8<--------------------
$ diff -u foo.h.orig foo_h
--- foo.h.orig  2016-02-26 16:02:43.122804515 +0100
+++ foo_h       2016-02-26 15:10:03.473190139 +0100
@@ -7,6 +7,7 @@
   int payload;

   lego();
+  lego(const lego&);

   int get() { return payload; }
   int set(int x) { payload = x; }
dodji@tintin:PR19734$ diff -u foo.cpp.orig foo.cpp
--- foo.cpp.orig        2016-02-26 16:02:30.621655698 +0100
+++ foo.cpp     2016-02-26 16:00:01.296878100 +0100
@@ -1,3 +1,10 @@
+#include <string.h>
 #include "foo.h"

 lego::lego() : payload(42) {}
+
+lego::lego(const lego& l)
+{
+  memcpy(buggy_symbol, l.buggy_symbol, sizeof(buggy_symbol));
+  payload = l.payload;
+}
$


Now abidiff does see the change.  This is what running foo.sh now yields:

[...]

+ abidiff libfoo1.so libfoo2.so
Functions changes summary: 0 Removed, 1 Changed, 0 Added function
Variables changes summary: 0 Removed, 0 Changed, 0 Added variable

1 function with some indirect sub-type change:

  [C]'method lego::lego(const lego&)' has some indirect sub-type changes:
    parameter 1 of type 'const lego&' has sub-type changes:
      in referenced type 'const lego':
        in unqualified underlying type 'struct lego':
          type size changed from 96 to 128 bits
          2 data member changes:
           type of 'char lego::buggy_symbol[5]' changed:
             type name changed from 'char[5]' to 'char[10]'
             array type size changed from 40 to 80 bits:
             array type subrange 1 changed length from 5 to 10

           'int lego::payload' offset changed from 64 to 96 (in bits)
[...]


Libabigail skips the this parameter because otherwise, too much noise is
emitted in the report.  In this small test case, there won't be any noise, of
course.  But on big c++ code bases with lots classes that have lots of member
functions, there can be lots of duplicated change reports that seriously
clutter the output.  I made that decision back when the library didn't have a
strong framework for filtering out redundant change reports.  It thought that
in general, there would be other functions that would use the class type
explicitly, so skipping the this parameter wouldn't necessarily make user miss
changes on the class type.

And you are with a real life case that rightfully argues otherwise :-)

I guess now that the library has stronger filtering framework, the this
parameter can be taking in account again when comparing methods.  We'll then
need to go through the resulting change reports for various interesting
binaries, spot the cases where unnecessary duplicated change reports are
emitted due to this change, and devise automatic redundancy detection and
filtering for those.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [Bug default/19734] Libabigail skips the 'this' pointer when comparing two member functions
  2016-01-01  0:00 [Bug default/19734] New: Shifted exported fields in c++ classes are not detected as abi breakage dank at kegel dot com
  2016-01-01  0:00 ` [Bug default/19734] Libabigail skips the 'this' pointer when comparing two member functions dodji at redhat dot com
@ 2020-11-11 16:07 ` maennich at android dot com
  1 sibling, 0 replies; 3+ messages in thread
From: maennich at android dot com @ 2020-11-11 16:07 UTC (permalink / raw)
  To: libabigail

https://sourceware.org/bugzilla/show_bug.cgi?id=19734

Matthias Maennich <maennich at android dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |maennich at android dot com
         Resolution|---                         |FIXED
             Status|ASSIGNED                    |RESOLVED

--- Comment #2 from Matthias Maennich <maennich at android dot com> ---
That appears to be fixed by a recent patch 

2f92777dc8c3 ("Consider the implicit 'this' parameter when comparing methods")
https://sourceware.org/git/?p=libabigail.git;a=commit;h=2f92777dc8c34a7f84011fbd62811b3c5d076a1a

This is now reported as

 | Functions changes summary: 0 Removed, 1 Changed, 0 Added function
 | Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
 |
 | 1 function with some indirect sub-type change:
 |
 |   [C] 'method lego::lego()' at foo.h:10:1 has some indirect sub-type
changes:
 |     implicit parameter 0 of type 'lego*' has sub-type changes:
 |       in pointed to type 'struct lego' at foo.h:2:1:
 |         type size changed from 96 to 128 (in bits)
 |         2 data member changes:
 |           type of 'char lego::buggy_symbol[5]' changed:
 |             type name changed from 'char[5]' to 'char[10]'
 |             array type size changed from 40 to 80
 |             array type subrange 1 changed length from 5 to 10
 |           'int lego::payload' offset changed from 64 to 96 (in bits) (by +32
bits)


Hence closing.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2020-11-11 16:07 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-01  0:00 [Bug default/19734] New: Shifted exported fields in c++ classes are not detected as abi breakage dank at kegel dot com
2016-01-01  0:00 ` [Bug default/19734] Libabigail skips the 'this' pointer when comparing two member functions dodji at redhat dot com
2020-11-11 16:07 ` maennich at android dot com

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).