C ++ character has a different size in a common object

I am working on a cross-platform window library designed specifically for OpenGL, currently focused on Linux. I use glload to manage OpenGL extensions, and this compiles with other libraries that I will use later in .so . This `.so is dynamically loaded, as you would expect, but at runtime the program gives the following result (manually wrapped to make it easier to read):

 _dist/x64-linux-debug/bin/test: Symbol `glXCreateContextAttribsARB' has \ different size in shared object, consider re-linking 

Now, obviously, I tried to reconnect, moving on to rebuilding the entire project many times (checking everything, and not just blindly hoping that this magic would make everything better). The program seems to be ready to work, as it will generate some registration results, as I would expect. I used nm to confirm that the character "is in .so

 nm _dist/x64-linux-debug/lib64/libvendor.so | grep glXCreateContextAttribsARB 00000000009e0e78 B glXCreateContextAttribsARB 

If I use readelf to look at the defined characters, I get the following (again, I manually wrapped the first three lines for formatting):

 readelf -Ws _dist/x64-linux-debug/bin/test \ _dist/x64-linux-debug/lib64/libvendor.so | \ grep glXCreateContextAttribsARB 348: 000000000062b318 8 OBJECT GLOBAL DEFAULT 26 glXCreateContextAttribsARB 421: 000000000062b318 8 OBJECT GLOBAL DEFAULT 26 glXCreateContextAttribsARB 1370: 00000000009e0e78 8 OBJECT GLOBAL DEFAULT 25 glXCreateContextAttribsARB 17464: 00000000009e0e78 8 OBJECT GLOBAL DEFAULT 25 glXCreateContextAttribsARB 

I’m afraid that this is all I can offer to help, since I really don’t know what to try or take a look. As I said, I’m sure more information will be needed, so please just say that I have provided what I can. I run these commands from my project root, making you wonder.

+7
source share
3 answers

Wilsonmichaelpatrick's answer is mostly correct, but using gdb is probably not the fastest way to find the problem, and most likely will not work at all if you have a build without debugging.

First, you must confirm that the problem is actually:

 readelf -Ws _dist/x64-linux-debug/bin/test _dist/x64-linux-debug/lib64/libvendor.so | grep glXCreateContextAttribsARB 

This should show the character defined in test and libvendor.so , with different sizes.

Secondly, move the test link and libvendor.so with the flag -Wl,-y,glXCreateContextAttribsARB . This will tell you which object files (or libraries) provide (different) definitions.

Finally, pre-process the sources that produce the -E and -dD flags on object files and see what differs between them.

Update:

I need help digesting what she says

Do not be helpless. Read man readelf or just run it manually. You will see something like this:

 readelf -Ws /bin/date | head -5 Symbol table '.dynsym' contains 75 entries: Num: Value Size Type Bind Vis Ndx Name 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND 1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __ctype_toupper_loc@GLIBC _2.3 (2) 

This indicates the importance of the data that you have. In particular, this suggests that the character size in test and in libvendor.so same ( 8 ). Therefore, the problem is not in these two ELF files, but in another place. Run readelf in other libraries and find the glXCreateContextAttribsARB definition, which has a different size. Then follow the rest of the procedures.

+6
source

The runtime notices that glXCreateContextAttribsARB is both compiled into a common object, and glXCreateContextAttribsARB, compiled in the main program (or perhaps even some other previously related object), has different sizes. This means that in separate assemblies for a common object and any other references to this object, they should look for another code (possibly in a common object) where it is defined. Sometimes this happens because they look at different files, sometimes it happens because of different #defines that cause different interpretations of the same file. Whatever the reason, you absolutely need to make sure that the same character (for example, structure) is defined in the same way (that is, with the same variables and element size) in everything that is associated at run time.

In fact, it is very good that he refuses to run, as it is a disaster when two pieces of code interpret the same bit of memory differently at runtime. (There are not too many exaggerations to say that everything can happen if it is allowed to continue.)

You can try just loading the executable into gdb (without running it) and entering

info types

to find out where it is defined, and then load the shared object into gdb (without running it) and do another info types to see what each one thinks it is watching. If this is the same, check the preprocessor directives.

+3
source

I ran into the tedious problem associated with objects of different sizes, so I want to share my experience, although it is clear to me that only one reason can explain the different sizes of objects, and not necessarily OP.

Symptoms were objects of different sizes in debug mode, none of them in release mode. The compiler has issued appropriate warnings. Character names are difficult to decipher, but are associated with some unnamed static variables in instances of class templates.

The reason was the debug logging function Γ  la LOG("Do something."); . The LOG macro used the C ANSI __FILE__ , which expanded to a different path depending on whether the header was included by the application or shared library. And this line was exactly the above unnamed static variable.

Even more tedious was the fact that, due to our make environment, the __FILE__ macro sometimes expanded to, say, C:\temp\file.h , and sometimes to C:\other\..\temp\file.h , so that the creation of the application and the library from the same place did not work 'and solve this problem.

Hope this experience can save some time for some of you.

+1
source

All Articles