Hello, and welcome to C++ Weekly. I'm your host, Jason Turner. I'm available for
code reviews and on-site training. In this episode we're going to look at a potential way of tracking
ABI changes that you've made in your code so that you know if you need to alert your users.
So the project that we're going to talk about is abidiff,
and this is a tool that is supposed to show you the ABI changes between two different binaries,
so we're going to give it a try and see what we find. Okay, so we've created a new folder
here to play with, and let's just make sure we've got abidiff installed. We do not - it looks like
it is in 'abigail-tools'. I'm not using Debian, but this would be an interesting way to see what
binaries are actually in here. Okay, 'abicompat', 'abidiff', 'abidw', 'abilint', "abi package diff",
and 'kmidiff'. Let's see if we can get this installed. Well, it looks like there's no
easy way to install it on Arch Linux, so we will be getting the get repository here and
compiling it ourselves... actually maybe we should just download the latest package.
All right. It compiled without any problems, and now we'll see what we have.
Oh goodness...
options file1 and file2... there are many, many options here - we can give it header
file information; we can tell it things to drop things, to keep things that are
harmless, it'll tell us that. Okay so we have to clearly create a couple of examples.
Now of course, since this is C++ Weekly, I'm going to go with C++ not C.
I don't know if this tool is mostly designed for C or C++, or what the difference may be.
I'm going to get const and non-const overloads here. This is going to be a simple struct,
and actually let's do something like this:
Uh, yeah, that seems good for the header file to me. I really don't know what kind of files it's
necessarily going to assume that I have here, so we're going to, again, just have to test it out.
Now for the one that takes a single parameter,
I'm going to go ahead and add an 'int' to it so that's definitely got to be an ABI breakage - I
added a parameter, and I really don't know what these functions should do.
All right. This is a pretty silly test. No main, so we're just going to compile to an object file
and see if that's good enough for us to test against.
Let's just start with this - go back into our tools folder,
and we're going to try this abidiff between these two object files which we believe
should be the same. Okay, it did not report any errors, and it did not report anything.
All right, so it's really not showing any changes at all, which is expected. Let's go ahead and
start making changes and see what we get.
Now I want this one to become const because we know that it ultimately should be const;
and I made a mistake back on the previous example - I made it so the non-const version of this
took an integer. Let's make sure that our headers match
and let's get rid of this one. So we know we've made an ABI
breakage in they 'use_params' function and in the
change to the 'get_x' number function -
let's see if we get a diff reported now. Ah, here we go, so "Removed the function symbol
not referenced by debug info." So I removed this thing. Now clearly this needs
some sort of demangle action. Yeah, I don't see a demangle,
so we're going to pipe this through c++filt, which is going to automatically de-mingle
these things. So we removed the "function symbol not referenced by debug info" - so we deleted
the one that takes an 'int' and we added one that takes, uh, that doesn't take an 'int',
so that is true; but it didn't track the changes for our member functions. Oh I didn't properly
define our member function. That would be related, wouldn't it?
Now defining it inline
means that we're probably still not going to get it dumped in the binary.
Yeah, so we're still not seeing that difference here but, I declared it inline, so let's make it
out-of-line. Oh, no, let's actually let's give it the header files for these two different versions.
Still not getting it showing up here, now I think that that's actually fair.
At no point is that function actually being
generated here, so it's not ending up in the executable.
There we go, now we see an entry for this 'get_x' function - 'get_x' here, and note object dump has
demangle support built in, so I do -C and I can get this 'get_x'. So let's try that diff again.
All right, now we go. We see that we've got "removed function symbols" and "added function
symbols not referenced in the debug info." Let's go ahead and also add debug info to both of these
and see what difference that makes in the abidiff tool. Oh,
well that was
interesting. Wow. Okay, so now with debug info we actually get to see things like method and
function used and not, used which makes me wonder if I need to pass this through C++filt. Nah,
I don't need C++filt anymore, now it, actually, um, interesting. It shows us the method and then
the symbol name - that's great. We don't want demangling now anymore. So yeah, there you go.
That's really interesting. So what other tools do we have now? We have a lot of tools. I wonder
what this does. Oh, core dumped. Looks like they're not checking for a missing symbol
name. Okay. Found a simple an instance of a "function symbol type of weak binding"
and "symbol not found." So, interesting ways to search through the ABI of your library. This has
actually been a really interesting exercise here trying to just play with this tool.
If you're concerned about ABI compatibility, uh, you need to really dig into these tools. So this
is libabigail, and you should be sure to check this stuff out because it looks like that there
is plenty of info here. This is the kind of thing that you could roll into like your CI and alert
you if you broke ABI and you're really concerned about that; and it doesn't look like it would be
terribly difficult to work with once you get used to these tools. So I hope you enjoyed this episode
of C++ Weekly, and, you know, the usual - be sure to subscribe and give this video a thumbs up.