I've distilled my problem down to a (hopefully) very simple example. At a high level, I have a shared library which provides a class implementation, and a main executable which uses the library. In my example, the library is then extended with CPPFLAG=-DMORE
so that the class initializer list now has one additional member. Since the ABI signature of the library does not changed, there should be no need to recompile the executable. Yet, in my case, I get a coredump. I do not understand why this is an issue. Can someone please point out where I am going wrong?
Environment
Linux, amd64, gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.1)
Setup
Using the code provided below, do the following:
make clean
make main
(which also buildsbase-orig
version of the library)./main
which runs just finemake base_more
./main
which crashes withBase hello Base class constructor has non-null MORE Base goodbye Base class destructor has non-null MORE *** stack smashing detected ***: terminated Aborted (core dumped)
Code
library header (base.h)
#ifdef MORE
#include <functional>
#endif
class base
{
public:
base();
~base();
private:
#ifdef MORE
std::function<void()> more_;
#endif
};
library source (base.cpp)
#include "base.h"
#include <iostream>
#ifdef MORE
void hi()
{
std::cout << "Hello from MORE" << std::endl;
}
#endif
base::base()
#ifdef MORE
: more_(std::bind(&hi))
#endif
{
std::cout << "Base hello " << std::endl;
#ifdef MORE
if (nullptr != more_)
{
std::cout << "Base class constructor has non-null MORE" << std::endl;
}
#endif
}
base::~base()
{
std::cout << "Base goodbye " << std::endl;
#ifdef MORE
if (nullptr != more_)
{
std::cout << "Base class destructor has non-null MORE" << std::endl;
}
#endif
}
Executable (main.cpp)
#include "base.h"
int main()
{
base x;
}
Makefile
base_orig:
g++ -O0 -g -fPIC -shared -olibbase.so base.cpp
objdump -C -S -d libbase.so > orig.objdump
base_more:
g++ -O0 -g -DMORE -fPIC -shared -olibbase.so base.cpp
objdump -C -S -d libbase.so > more.objdump
main: base_orig
g++ -O0 -g -Wextra -Werror main.cpp -o main -L. -Wl,-rpath=. -lbase
objdump -C -S -d main > main.objdump
clean:
rm -f main libbase.so
I tried to go through the objdump
output to figure out why the stack is getting corrupted, but alas, my knowledge of amd64 assembly is rather weak.