Runtime warning: Symbol [vtable] has different size in shared object, consider relinking

Tyler Cardon tyler.k.cardon@gmail.com
Tue Jan 7 23:06:00 GMT 2014


This warning is given at run-time:

./test: Symbol `_ZTV5CTest' has different size in shared object, consider
re-linking

objdump -s test | grep _ZTV5CTest
10: 08049b30    20 OBJECT  WEAK   DEFAULT   25 _ZTV5CTest
86: 08049b30    20 OBJECT  WEAK   DEFAULT   25 _ZTV5CTest

nm -C test | grep 08049b30
08049b30 V vtable for CTest

The executable, test, has a class that inherits from a base class defined in
libtest_base_class.so.

Does this mean that adding virtual method declarations (even without
changing virtual method order) breaks the base class library's abi?  The
program appears to run normally.  Also, this warning goes away after making
the base class abstract (i.e. repeating test with TEST_ABSTRACT
uncommented).

Compiler: GCC 3.4.0
Ran on Linux systems: Centos 6.4, Debian 3.1
Test case: 
built libtest_base_class.so with #define BUILD_EXPANDED commented out.
built test linking against libtest_base_class.so
rebuilt libtest_base_class.so with #define BUILD_EXPANDED uncommented.
ran test linking with the new libtest_base_class.so

Result:
./test: Symbol `_ZTV5CTest' has different size in shared object, consider
re-linking
Doing something with 0 and 0
0!
Doing something totally new...
2
Will this really work...
0
Seems to be working...
2
Yeah, this must be working...
1
Woot!...
42

test_base_class.h
-----------------
#ifndef TEST_BASE_CLASS_H
#define TEST_BASE_CLASS_H

#ifdef TEST_MAIN
	#define TEST_API		__attribute__((visibility("default")))
	#define TEST_LOCAL	__attribute__((visibility("hidden")))
#else
	#define TEST_API
	#define TEST_LOCAL
#endif

//#define BUILD_EXPANDED
#ifdef BUILD_EXPANDED 
	#define TEST_DISPATCH
#endif 

#define TEST_ABSTRACT

class TEST_API CTest
{

public:
	CTest();
	virtual ~CTest() {};

protected:

#ifdef TEST_ABSTRACT
	virtual int DoSomething(int x, int y);
#endif

#ifdef BUILD_EXPANDED

	virtual int DoSomethingTotallyNew(int x, int y);
	virtual int WillThisReallyWork(int x, int y);
	virtual int SeemsToBeWorking(int x, int y);
	virtual int MustReallyBeWorking(int x, int y);
	virtual int Woot(int x, int y);

	#ifdef TEST_DISPATCH
		void RunTimeDispatch();
	#endif
#endif

	TEST_LOCAL int NotExported(int x, int y);

#ifdef BUILD_EXPANDED

//---------------------------------------------------------------------------
	// Added after child build
	// 
private:
#pragma GCC visibility push(hidden)
	int m_nNewParam;
	int NewFunction(int x, int y);
#pragma GCC visibility pop
#endif

};

#endif
-------------------

test_base_class.cpp
-------------------

#define TEST_MAIN
#include "test_base_class.h"

//------------------------------------------------------------------------------
// Before child build
// 
#ifndef BUILD_EXPANDED
CTest::CTest()
{
	;
}

#endif

int CTest::NotExported(int x, int y)
{
	return (x - y);
}

int CTest::DoSomething(int x, int y)
{
	return (x - y);
}

#ifdef BUILD_EXPANDED

//------------------------------------------------------------------------------
// After child build
// 
#include "stdio.h"
int CTest::NewFunction(int x, int y)
{
	return (x + y + m_nNewParam);
}

CTest::CTest()
{
	int a = 1;
	int b = 2;
	int x = 0, y = 0;
	m_nNewParam = 5;
	printf("Doing something with %d and %d\n", x, y);
	printf("%d!\n", DoSomething(x, y));
	printf("Doing something totally new...\n");
	printf("%d\n", DoSomethingTotallyNew(a,b));
	printf("Will this really work...\n");
	printf("%d\n", WillThisReallyWork(a,b));
	printf("Seems to be working...\n");
	printf("%d\n", SeemsToBeWorking(a,b));
	printf("Yeah, this must be working...\n");
	printf("%d\n", MustReallyBeWorking(a,b));
	printf("Woot!...\n");
	printf("%d\n", Woot(a,b));
}

int CTest::DoSomethingTotallyNew(int x, int y)
{
	return (x * y);
}
int CTest::WillThisReallyWork(int x, int y)
{
	return (x / y);
}

int CTest::SeemsToBeWorking(int x, int y)
{
	return (y / x);
}

int CTest::MustReallyBeWorking(int x, int y)
{
	return (y - x);
}

int CTest::Woot(int x, int y)
{
	return (42);
}
#endif
-----------------

test_child_class.h
-----------------
#ifndef TEST_CHILD_CLASS_H
#define TEST_CHILD_CLASS_H

#include "test_base_class.h"

#endif

test.cpp
--------
#include "test_child_class.h"

class CTestChild : public CTest
{

public:

	CTestChild() {};
	virtual ~CTestChild() {};

protected:

#ifdef TEST_ABSTRACT
	virtual int MustOverride(int x, int y) { return (x + y);}
#endif

};

int main ()
{
	CTestChild* pcTest = new CTestChild;

	delete pcTest;

	return 0;
}
-------------



--
View this message in context: http://gcc.1065356.n5.nabble.com/Runtime-warning-Symbol-vtable-has-different-size-in-shared-object-consider-relinking-tp1000550.html
Sent from the gcc - Help mailing list archive at Nabble.com.



More information about the Gcc-help mailing list