So, following up from the last quiztime which was about the importance of explicit linking, another case from the wonderful world of shared libraries.
This time we study the implications of dlopen, its parameters and C++. Consider the program and module below. If you run that, it will crash somewhat obscurely in libstdc++. Why?
#0 0x00007f687b2eb126 in std::ostream::sentry::sentry(std::ostream&) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#1 0x00007f687b2eb889 in std::basic_ostream >& std::__ostream_insert >(std::basic_ostream >&, char const*, long) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#2 0x00007f687b2ebd57 in std::basic_ostream >& std::operator< < >(std::basic_ostream >&, char const*) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3 0x00007f687a6f01a0 in Impl::print (this=0x558a9bc1f2e0, str="Hello") at module.cc:24
#4 0x0000558a99de3d1b in main (argc=1, argv=0x7ffca28cf538) at main.cc:31
#ifndef INTERFACE_H
#define INTERFACE_H
#include
class IInterface {
public:
virtual ~IInterface() {};
virtual void print(const std::string& str) = 0;
};
#endif // INTERFACE_H
#include "interface.h"
#include
class Impl : public IInterface {
public:
Impl();
virtual ~Impl();
void print(const std::string& str);
};
extern "C" {
void *entry_point(void)
{
return new Impl;
}
};
Impl::Impl() {};
Impl::~Impl() {};
void Impl::print(const std::string& str)
{
std::cerr < <"Some text to print\n";
std::cerr << "Got passed this: " << str << "\n";
std::cerr << "=====\n";
}
#include
#include
#include "interface.h"
extern "C" {
typedef void *(*EntryFunction)(void);
};
int main(int argc, char *argv[])
{
IInterface *iface;
EntryFunction f;
void *lib = dlopen("./module.so", RTLD_NOW | RTLD_DEEPBIND);
if (lib == nullptr) {
std::cerr < < dlerror () << "\n";
return 1;
}
f = (EntryFunction) dlsym (lib, "entry_point");
if (f == nullptr) {
std::cerr << dlerror () << "\n";
return 1;
}
iface = reinterpret_cast(f());
while (true) {
iface->print ("Hello");
}
}
.PHONY: all clean
all: main module.so
clean:
rm -f main
rm -f module.so
main: main.cc
g++ -g -o $@ $< -ldl
module.so: module.cc
g++ -g -o $@ -shared $< -fPIC